diff --git a/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.down.sql b/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.down.sql index 95acc7489c..31a1f44859 100644 --- a/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.down.sql +++ b/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.down.sql @@ -1,2 +1,5 @@ -ALTER TABLE draft - ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC'; +-- Symmetric to the up migration: Postgres's default `TIMESTAMPTZ -> TIMESTAMP` +-- cast strips the timezone by representing the instant in the session's +-- current timezone, mirroring how the original `now()` values were +-- truncated on insert. +ALTER TABLE draft ALTER COLUMN created_at TYPE TIMESTAMP; diff --git a/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.up.sql b/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.up.sql index 42839c6717..79f20611d4 100644 --- a/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.up.sql +++ b/backend/migrations/20260514233244_convert_draft_created_at_to_timestamptz.up.sql @@ -1,7 +1,12 @@ -- `draft.created_at` was originally created as `TIMESTAMP` (no timezone). The -- new `*WithDraft` API responses surface it as `chrono::DateTime` for the --- frontend's staleness check, which requires `TIMESTAMPTZ`. Existing values --- are interpreted as UTC (matching `now()`'s behaviour on a UTC server, the --- expected deployment for Windmill). -ALTER TABLE draft - ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC'; +-- frontend's staleness check, which requires `TIMESTAMPTZ`. +-- +-- We rely on Postgres's default `TIMESTAMP -> TIMESTAMPTZ` cast (no explicit +-- USING), which interprets each existing wall-clock value in the session's +-- current timezone. That's the exact semantics under which the original +-- `INSERT ... DEFAULT now()` values were truncated to TIMESTAMP — so the +-- conversion is a no-op on UTC servers (the common case) and correctly +-- recovers the original instant on non-UTC servers, instead of shifting all +-- pre-migration timestamps by the server's tz offset. +ALTER TABLE draft ALTER COLUMN created_at TYPE TIMESTAMPTZ;