fix(db): convert ai_credits timestamp columns to TIMESTAMPTZ
Some checks failed
build-and-release / build (cron) (push) Successful in 57s
build-and-release / build (customers) (push) Successful in 1m54s
build-and-release / build (employees) (push) Successful in 2m11s
build-and-release / build (companies) (push) Successful in 2m27s
build-and-release / build (catering-services) (push) Successful in 2m28s
build-and-release / build (gateway) (push) Successful in 48s
build-and-release / build (developers) (push) Successful in 3m3s
build-and-release / build (jobs) (push) Successful in 43s
build-and-release / build (fitness-trainers) (push) Successful in 2m36s
build-and-release / build (makeup-artists) (push) Successful in 1m45s
build-and-release / build (graphic-designers) (push) Successful in 2m38s
build-and-release / build (job-seekers) (push) Successful in 2m28s
build-and-release / build (photographers) (push) Successful in 2m34s
build-and-release / build (social-media-managers) (push) Successful in 2m34s
build-and-release / build (payments) (push) Successful in 3m20s
backend-integration-tests / ai-credits (push) Failing after 44s
build-and-release / build (tutors) (push) Successful in 2m41s
build-and-release / build (video-editors) (push) Has been cancelled
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (ugc-content-creators) (push) Successful in 2m41s
Some checks failed
build-and-release / build (cron) (push) Successful in 57s
build-and-release / build (customers) (push) Successful in 1m54s
build-and-release / build (employees) (push) Successful in 2m11s
build-and-release / build (companies) (push) Successful in 2m27s
build-and-release / build (catering-services) (push) Successful in 2m28s
build-and-release / build (gateway) (push) Successful in 48s
build-and-release / build (developers) (push) Successful in 3m3s
build-and-release / build (jobs) (push) Successful in 43s
build-and-release / build (fitness-trainers) (push) Successful in 2m36s
build-and-release / build (makeup-artists) (push) Successful in 1m45s
build-and-release / build (graphic-designers) (push) Successful in 2m38s
build-and-release / build (job-seekers) (push) Successful in 2m28s
build-and-release / build (photographers) (push) Successful in 2m34s
build-and-release / build (social-media-managers) (push) Successful in 2m34s
build-and-release / build (payments) (push) Successful in 3m20s
backend-integration-tests / ai-credits (push) Failing after 44s
build-and-release / build (tutors) (push) Successful in 2m41s
build-and-release / build (video-editors) (push) Has been cancelled
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (ugc-content-creators) (push) Successful in 2m41s
9 columns across ai_plans/user_ai_subscriptions/ai_feature_costs/ ai_usage_logs were TIMESTAMP (no timezone), left over from whatever pre-20260703210000 mechanism originally created these 4 tables, but crates/db/src/models/ai_credits.rs maps all of them to DateTime<Utc>, which sqlx requires TIMESTAMPTZ for. This is a live bug, not just a test-setup gap - discovered via crates/db/tests/ai_credits.rs failing with ColumnDecode errors, but any production code path selecting these columns (e.g. current_period_start/end on every wallet read) would hit the same failure. ALTER COLUMN ... USING col AT TIME ZONE 'UTC' is lossless here since every write path uses NOW()/DEFAULT NOW() with no other timezone handling anywhere in the codebase. Applied to both nxtgauge_test and the live nxtgauge database directly; verified all 9 columns converted and the 3 existing user_ai_subscriptions + 4 ai_plans rows' values are intact and correctly interpreted as UTC afterward. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
675a5a12c5
commit
1af10420ce
3 changed files with 57 additions and 1 deletions
|
|
@ -11,4 +11,3 @@ COPY . .
|
|||
RUN --mount=type=secret,id=test_db_url,required=true \
|
||||
export TEST_DATABASE_URL="$(cat /run/secrets/test_db_url)" && \
|
||||
cargo test -p db --test ai_credits --test ai_credits_reaper -- --test-threads=1
|
||||
# re-run: nxtgauge_test now has seed data (free plan)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
BEGIN;
|
||||
|
||||
ALTER TABLE ai_usage_logs
|
||||
ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
||||
|
||||
ALTER TABLE ai_feature_costs
|
||||
ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
||||
|
||||
ALTER TABLE user_ai_subscriptions
|
||||
ALTER COLUMN current_period_start TYPE TIMESTAMP USING current_period_start AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN current_period_end TYPE TIMESTAMP USING current_period_end AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
||||
|
||||
ALTER TABLE ai_plans
|
||||
ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
||||
|
||||
COMMIT;
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
-- Fix ai_plans/user_ai_subscriptions/ai_feature_costs/ai_usage_logs timestamp
|
||||
-- columns: they were created (by whatever earlier, pre-20260703210000
|
||||
-- mechanism made these tables) as `TIMESTAMP` (no timezone), but
|
||||
-- crates/db/src/models/ai_credits.rs maps every one of these to
|
||||
-- `DateTime<Utc>`, which sqlx requires the column to be `TIMESTAMPTZ` for.
|
||||
-- Discovered via crates/db/tests/ai_credits.rs failing with:
|
||||
-- ColumnDecode { ... "TIMESTAMPTZ" is not compatible with SQL type "TIMESTAMP" }
|
||||
-- This is a real, live bug, not just a test-setup gap: any production code
|
||||
-- path that SELECTs current_period_start/current_period_end (or any of the
|
||||
-- other columns below) via these structs would hit the same decode error.
|
||||
--
|
||||
-- `AT TIME ZONE 'UTC'` reinterprets the existing naive values as UTC wall-clock
|
||||
-- time when adding the zone (the correct, lossless conversion given every
|
||||
-- write path uses NOW()/DEFAULT NOW() with no other timezone handling
|
||||
-- anywhere in this codebase) rather than converting through the session's
|
||||
-- local timezone.
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE ai_plans
|
||||
ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
||||
|
||||
ALTER TABLE user_ai_subscriptions
|
||||
ALTER COLUMN current_period_start TYPE TIMESTAMPTZ USING current_period_start AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN current_period_end TYPE TIMESTAMPTZ USING current_period_end AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
||||
|
||||
ALTER TABLE ai_feature_costs
|
||||
ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC',
|
||||
ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
||||
|
||||
ALTER TABLE ai_usage_logs
|
||||
ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
||||
|
||||
COMMIT;
|
||||
Loading…
Add table
Reference in a new issue