feat(calendar): Standard-Zeitzone pro Kalender vorbereiten
Neue Spalte cal_calendars.timezone (Default UTC). CalDAV selbst braucht sie nicht - jeder Termin trägt seine Zeitzone bereits im eigenen .ics, und die TZID-Auflösung darin läuft schon korrekt über die System-Zeitzonendatenbank. Gebraucht wird das Feld erst von der künftigen Web-Oberfläche zum Anlegen neuer Termine (Phase 3) als Vorgabe, wenn der Nutzer keine eigene Zeitzone wählt - jetzt schon angelegt, damit dafür keine weitere Migration nötig wird. Gegen den laufenden Container geprüft: Migration lief durch, Home-Set- PROPFIND (nutzt die geänderten SELECTs) weiterhin grün. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
469274171c
commit
3f1b2b8a14
6 files changed
+28
-8
No files matched your search
@@ -0,0 +1 @@
|
||||
ALTER TABLE cal_calendars DROP COLUMN IF EXISTS timezone;
|
||||
@@ -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';
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE cal_calendars DROP COLUMN IF EXISTS timezone;
|
||||
@@ -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';
|
||||
Reference in new issue
Block a user