From 7e485e505ed8b65a1d09ad6157d6c5fbaeb2c9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesko=20Ansch=C3=BCtz?= Date: Fri, 27 Mar 2026 07:17:37 +0100 Subject: [PATCH] feat(store): ScreenScheduleStore mit Get/Upsert/ListEnabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fügt ScreenSchedule-Typ, ScreenScheduleStore und GetByID-Methode für ScreenStore hinzu. Co-Authored-By: Claude Sonnet 4.6 --- server/backend/internal/store/store.go | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/server/backend/internal/store/store.go b/server/backend/internal/store/store.go index 879a142..1ad958b 100644 --- a/server/backend/internal/store/store.go +++ b/server/backend/internal/store/store.go @@ -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() +}