Skip to content

chore(db): codify arecs updated_at ON UPDATE fix as migration 0001 - #369

Merged
ety001 merged 1 commit into
nextfrom
chore/arecs-updated-at-migration
Oct 8, 2026
Merged

ety001 merged 1 commit into
nextfrom
chore/arecs-updated-at-migration

Conversation

@ety001

@ety001 ety001 commented Oct 8, 2026

Copy link
Copy Markdown
Member

Summary

Codifies the arecs.updated_at ON UPDATE fix (applied manually to production on 2026-10-08, MAIN-57 follow-up) as a proper drizzle migration, so dev environments and future rebuilds converge to the schema baseline instead of relying on hand-run SQL.

  • drizzle/0001_arecs_updated_at_on_update.sql — custom migration (drizzle-kit generate --custom): ALTER TABLE arecs MODIFY updated_at datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, with full rationale in the header (legacy Sequelize migration declared the timestamps NOT NULL without DB defaults; the recovery lifecycle's 24h code TTL and 10-minute stuck-claim self-heal read updated_at as their inactivity timer)
  • drizzle/meta/0001_snapshot.json + _journal.json — generated bookkeeping
  • docs/DATABASE.md — timestamp-drift section now points at the migration instead of advising a manual SHOW CREATE TABLE check

Verification

  • drizzle-kit check passes; pnpm type-check passes
  • Real MySQL 8 E2E: created a legacy-shaped arecs table (updated_at datetime NOT NULL, no ON UPDATE), applied 0001 → column becomes NOT NULL ON UPDATE CURRENT_TIMESTAMP, and a subsequent UPDATE bumps updated_at to NOW() (0s skew)
  • Production already has the column in this state (manual apply, functionally verified there on 2026-10-08); drizzle's journal marks 0001 applied after the first successful migrate run, so it will not re-execute there

Production's `arecs` table (built by the legacy Sequelize migration) had
`updated_at datetime NOT NULL` without ON UPDATE CURRENT_TIMESTAMP, so the
recovery lifecycle timers (24h code TTL, 10-min stuck-claim self-heal in
src/lib/recovery/lifecycle.ts) never re-armed on UPDATE. The column was
fixed manually on production on 2026-10-08 (MAIN-57 follow-up, verified
with a functional probe: UPDATE bumps updated_at, 0s skew).

This codifies that change as a proper migration so dev environments and
future rebuilds converge to the drizzle schema baseline instead of
relying on hand-run SQL:

- drizzle/0001_arecs_updated_at_on_update.sql — custom migration with the
  rationale and production-application record in its header
- drizzle/meta/0001_snapshot.json + _journal.json — generated bookkeeping
  (drizzle-kit generate --custom, drizzle-kit check passes)
- docs/DATABASE.md — timestamp-drift section now points at the migration
  instead of advising a manual SHOW CREATE TABLE check

Verified against a legacy-shaped table in real MySQL 8: applying 0001
produces `updated_at datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP` and a
subsequent UPDATE bumps the timestamp as expected. Production already has
the column in this state; drizzle's journal marks 0001 applied after the
first successful migrate run, so it will not re-execute there.
@ety001
ety001 merged commit 729e24b into next Oct 8, 2026
2 of 3 checks passed
@ety001
ety001 deleted the chore/arecs-updated-at-migration branch October 8, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant