diff --git a/backend/db/migrations/000022_calendar_timezone.down.sql b/backend/db/migrations/000022_calendar_timezone.down.sql new file mode 100644 index 0000000..abed15f --- /dev/null +++ b/backend/db/migrations/000022_calendar_timezone.down.sql @@ -0,0 +1 @@ +ALTER TABLE cal_calendars DROP COLUMN IF EXISTS timezone; diff --git a/backend/db/migrations/000022_calendar_timezone.up.sql b/backend/db/migrations/000022_calendar_timezone.up.sql new file mode 100644 index 0000000..c9a1743 --- /dev/null +++ b/backend/db/migrations/000022_calendar_timezone.up.sql @@ -0,0 +1,7 @@ +-- Standard-Zeitzone pro Kalender. Wird von CalDAV selbst nicht gebraucht +-- (jeder Termin trägt seine Zeitzone im .ics), sondern erst von der +-- künftigen Web-Oberfläche zum Anlegen neuer Termine (Phase 3, siehe +-- kalender-plan.md) – ein neuer Termin braucht eine Vorgabe, wenn der +-- Nutzer keine eigene wählt. Jetzt schon angelegt, damit später keine +-- weitere Migration für ein einzelnes Feld nötig ist. +ALTER TABLE cal_calendars ADD COLUMN IF NOT EXISTS timezone TEXT NOT NULL DEFAULT 'UTC'; diff --git a/backend/internal/calendar/model.go b/backend/internal/calendar/model.go index 3c58307..c65e7ce 100644 --- a/backend/internal/calendar/model.go +++ b/backend/internal/calendar/model.go @@ -20,8 +20,12 @@ type Calendar struct { Color string `json:"color"` Description string `json:"description"` SupportsTodo bool `json:"supports_todo"` - CTag int64 `json:"ctag"` - CreatedAt time.Time `json:"created_at"` + // TimeZone ist die Vorgabe für neue Termine, die die Web-Oberfläche + // künftig hier anlegt (Phase 3). CalDAV selbst braucht sie nicht – + // jeder Termin trägt seine Zeitzone bereits im .ics. + TimeZone string `json:"timezone"` + CTag int64 `json:"ctag"` + CreatedAt time.Time `json:"created_at"` } // Object ist ein einzelner Termin oder eine Aufgabe. Data ist die diff --git a/backend/internal/calendar/store.go b/backend/internal/calendar/store.go index c17d4af..ffcc0d5 100644 --- a/backend/internal/calendar/store.go +++ b/backend/internal/calendar/store.go @@ -23,7 +23,7 @@ func NewStore(db *pgxpool.Pool) *Store { func (s *Store) ListCalendars(ctx context.Context, ownerID uuid.UUID) ([]Calendar, error) { rows, err := s.db.Query(ctx, - `SELECT id, owner_id, name, color, description, supports_todo, ctag, created_at + `SELECT id, owner_id, name, color, description, supports_todo, timezone, ctag, created_at FROM cal_calendars WHERE owner_id = $1 ORDER BY created_at`, ownerID, ) @@ -35,7 +35,7 @@ func (s *Store) ListCalendars(ctx context.Context, ownerID uuid.UUID) ([]Calenda var out []Calendar for rows.Next() { var c Calendar - if err := rows.Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.CTag, &c.CreatedAt); err != nil { + if err := rows.Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.TimeZone, &c.CTag, &c.CreatedAt); err != nil { return nil, fmt.Errorf("scan calendar: %w", err) } out = append(out, c) @@ -46,10 +46,10 @@ func (s *Store) ListCalendars(ctx context.Context, ownerID uuid.UUID) ([]Calenda func (s *Store) GetCalendar(ctx context.Context, ownerID, id uuid.UUID) (*Calendar, error) { var c Calendar err := s.db.QueryRow(ctx, - `SELECT id, owner_id, name, color, description, supports_todo, ctag, created_at + `SELECT id, owner_id, name, color, description, supports_todo, timezone, ctag, created_at FROM cal_calendars WHERE owner_id = $1 AND id = $2`, ownerID, id, - ).Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.CTag, &c.CreatedAt) + ).Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.TimeZone, &c.CTag, &c.CreatedAt) if errors.Is(err, pgx.ErrNoRows) { return nil, ErrNotFound } @@ -82,9 +82,9 @@ func (s *Store) CreateCalendar(ctx context.Context, ownerID uuid.UUID, name, col err := s.db.QueryRow(ctx, `INSERT INTO cal_calendars (owner_id, name, color, description) VALUES ($1, $2, $3, $4) - RETURNING id, owner_id, name, color, description, supports_todo, ctag, created_at`, + RETURNING id, owner_id, name, color, description, supports_todo, timezone, ctag, created_at`, ownerID, name, color, description, - ).Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.CTag, &c.CreatedAt) + ).Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.TimeZone, &c.CTag, &c.CreatedAt) if err != nil { return nil, fmt.Errorf("insert calendar: %w", err) } diff --git a/backend/pkg/db/migrations/000022_calendar_timezone.down.sql b/backend/pkg/db/migrations/000022_calendar_timezone.down.sql new file mode 100644 index 0000000..abed15f --- /dev/null +++ b/backend/pkg/db/migrations/000022_calendar_timezone.down.sql @@ -0,0 +1 @@ +ALTER TABLE cal_calendars DROP COLUMN IF EXISTS timezone; diff --git a/backend/pkg/db/migrations/000022_calendar_timezone.up.sql b/backend/pkg/db/migrations/000022_calendar_timezone.up.sql new file mode 100644 index 0000000..c9a1743 --- /dev/null +++ b/backend/pkg/db/migrations/000022_calendar_timezone.up.sql @@ -0,0 +1,7 @@ +-- Standard-Zeitzone pro Kalender. Wird von CalDAV selbst nicht gebraucht +-- (jeder Termin trägt seine Zeitzone im .ics), sondern erst von der +-- künftigen Web-Oberfläche zum Anlegen neuer Termine (Phase 3, siehe +-- kalender-plan.md) – ein neuer Termin braucht eine Vorgabe, wenn der +-- Nutzer keine eigene wählt. Jetzt schon angelegt, damit später keine +-- weitere Migration für ein einzelnes Feld nötig ist. +ALTER TABLE cal_calendars ADD COLUMN IF NOT EXISTS timezone TEXT NOT NULL DEFAULT 'UTC';