diff --git a/server/backend/internal/store/store.go b/server/backend/internal/store/store.go index bc7e556..986deb8 100644 --- a/server/backend/internal/store/store.go +++ b/server/backend/internal/store/store.go @@ -699,3 +699,66 @@ func (s *ScreenScheduleStore) ListEnabled(ctx context.Context) ([]*ScreenSchedul } return out, rows.Err() } + +// SetOverrideOnUntil setzt oder löscht den per-Screen-Override (null = löschen). +func (s *ScreenScheduleStore) SetOverrideOnUntil(ctx context.Context, screenID string, until *time.Time) error { + _, err := s.pool.Exec(ctx, + `insert into screen_schedules (screen_id, override_on_until) + values ($1, $2) + on conflict (screen_id) do update + set override_on_until = excluded.override_on_until`, + screenID, until) + return err +} + +// ------------------------------------------------------------------ +// GlobalOverrideStore +// ------------------------------------------------------------------ + +// GlobalOverride beschreibt einen aktiven globalen Display-Override. +type GlobalOverride struct { + Type string `json:"type"` // "on" oder "off" + Until time.Time `json:"until"` + SetAt time.Time `json:"set_at"` +} + +// GlobalOverrideStore verwaltet den globalen Display-Override (max. 1 Zeile). +type GlobalOverrideStore struct{ pool *pgxpool.Pool } + +func NewGlobalOverrideStore(pool *pgxpool.Pool) *GlobalOverrideStore { + return &GlobalOverrideStore{pool: pool} +} + +// Get lädt den aktuellen globalen Override. Gibt nil zurück wenn keiner gesetzt ist. +func (s *GlobalOverrideStore) Get(ctx context.Context) (*GlobalOverride, error) { + var o GlobalOverride + err := s.pool.QueryRow(ctx, + `select type, until, set_at from global_override where id = 1`). + Scan(&o.Type, &o.Until, &o.SetAt) + if errors.Is(err, pgx.ErrNoRows) { + return nil, nil + } + if err != nil { + return nil, err + } + return &o, nil +} + +// Upsert setzt oder überschreibt den globalen Override. +func (s *GlobalOverrideStore) Upsert(ctx context.Context, overrideType string, until time.Time) error { + _, err := s.pool.Exec(ctx, + `insert into global_override (id, type, until, set_at) + values (1, $1, $2, now()) + on conflict (id) do update + set type = excluded.type, + until = excluded.until, + set_at = excluded.set_at`, + overrideType, until) + return err +} + +// Delete entfernt den globalen Override. +func (s *GlobalOverrideStore) Delete(ctx context.Context) error { + _, err := s.pool.Exec(ctx, `delete from global_override where id = 1`) + return err +}