feat(store): ScreenScheduleStore mit Get/Upsert/ListEnabled

Fügt ScreenSchedule-Typ, ScreenScheduleStore und GetByID-Methode
für ScreenStore hinzu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jesko Anschütz 2026-03-27 07:17:37 +01:00
parent 1556c0d002
commit 7e485e505e

View file

@ -40,6 +40,13 @@ type ScreenStatus struct {
ReportedAt time.Time `json:"reported_at"`
}
type ScreenSchedule struct {
ScreenID string `json:"screen_id"`
ScheduleEnabled bool `json:"schedule_enabled"`
PowerOnTime string `json:"power_on_time"`
PowerOffTime string `json:"power_off_time"`
}
type MediaAsset struct {
ID string `json:"id"`
TenantID string `json:"tenant_id"`
@ -94,11 +101,15 @@ type TenantStore struct{ pool *pgxpool.Pool }
type ScreenStore struct{ pool *pgxpool.Pool }
type MediaStore struct{ pool *pgxpool.Pool }
type PlaylistStore struct{ pool *pgxpool.Pool }
type ScreenScheduleStore struct{ pool *pgxpool.Pool }
func NewTenantStore(pool *pgxpool.Pool) *TenantStore { return &TenantStore{pool} }
func NewScreenStore(pool *pgxpool.Pool) *ScreenStore { return &ScreenStore{pool} }
func NewMediaStore(pool *pgxpool.Pool) *MediaStore { return &MediaStore{pool} }
func NewPlaylistStore(pool *pgxpool.Pool) *PlaylistStore { return &PlaylistStore{pool} }
func NewScreenScheduleStore(pool *pgxpool.Pool) *ScreenScheduleStore {
return &ScreenScheduleStore{pool}
}
// ------------------------------------------------------------------
// TenantStore
@ -185,6 +196,12 @@ func (s *ScreenStore) GetBySlug(ctx context.Context, slug string) (*Screen, erro
return scanScreen(row)
}
func (s *ScreenStore) GetByID(ctx context.Context, id string) (*Screen, error) {
row := s.pool.QueryRow(ctx,
`select id, tenant_id, slug, name, orientation, created_at from screens where id=$1`, id)
return scanScreen(row)
}
func (s *ScreenStore) Create(ctx context.Context, tenantID, slug, name, orientation string) (*Screen, error) {
row := s.pool.QueryRow(ctx,
`insert into screens(tenant_id, slug, name, orientation)
@ -624,3 +641,55 @@ func scanPlaylistItem(row interface {
}
return &it, nil
}
// ------------------------------------------------------------------
// ScreenScheduleStore
// ------------------------------------------------------------------
// Get lädt den Zeitplan eines Screens. Gibt einen leeren ScreenSchedule zurück wenn keiner vorhanden.
func (s *ScreenScheduleStore) Get(ctx context.Context, screenID string) (*ScreenSchedule, error) {
var sc ScreenSchedule
err := s.pool.QueryRow(ctx,
`select screen_id, schedule_enabled, power_on_time, power_off_time
from screen_schedules where screen_id = $1`, screenID).
Scan(&sc.ScreenID, &sc.ScheduleEnabled, &sc.PowerOnTime, &sc.PowerOffTime)
if err != nil {
return &ScreenSchedule{ScreenID: screenID}, nil
}
return &sc, nil
}
// Upsert speichert oder aktualisiert den Zeitplan eines Screens.
func (s *ScreenScheduleStore) Upsert(ctx context.Context, sc *ScreenSchedule) error {
_, err := s.pool.Exec(ctx,
`insert into screen_schedules (screen_id, schedule_enabled, power_on_time, power_off_time)
values ($1, $2, $3, $4)
on conflict (screen_id) do update
set schedule_enabled = excluded.schedule_enabled,
power_on_time = excluded.power_on_time,
power_off_time = excluded.power_off_time`,
sc.ScreenID, sc.ScheduleEnabled, sc.PowerOnTime, sc.PowerOffTime)
return err
}
// ListEnabled gibt alle Screens mit aktivem Zeitplan zurück.
func (s *ScreenScheduleStore) ListEnabled(ctx context.Context) ([]*ScreenSchedule, error) {
rows, err := s.pool.Query(ctx,
`select screen_id, schedule_enabled, power_on_time, power_off_time
from screen_schedules
where schedule_enabled = true
and (power_on_time != '' or power_off_time != '')`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []*ScreenSchedule
for rows.Next() {
var sc ScreenSchedule
if err := rows.Scan(&sc.ScreenID, &sc.ScheduleEnabled, &sc.PowerOnTime, &sc.PowerOffTime); err != nil {
return nil, err
}
out = append(out, &sc)
}
return out, rows.Err()
}