Files
netfelix-audio-fix/.claude/memory/feedback_schema_migrations.md
Felix Förtsch c0bcbaec1b
All checks were successful
Build and Push Docker Image / build (push) Successful in 49s
time input: replace hand-rolled fields with react-aria-components TimeField
the previous TimeInput was a bespoke two-field widget. correct in behaviour
but off-policy: we don't roll our own ui primitives when a maintained
library solves it. swap for react-aria-components + @internationalized/date
pinned to hourCycle={24}, granularity=minute, shouldForceLeadingZeros so
the output is always strict HH:MM regardless of browser/OS locale.

wrapper lives at src/shared/components/ui/time-input.tsx and keeps the
existing string-based API (value: "HH:MM", onChange(next)) so callers don't
change.

also updates the stack docs: web-stack.md now pins react-aria-components
as THE required library for every date/time ui; iOS and Android entries
mark their canonical component as TBD and explicitly forbid rolling our
own without user sign-off.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 15:37:03 +02:00

2.0 KiB

name, description, type, originSessionId
name description type originSessionId
Schema changes need migrations going forward From 2026-04-13 onwards, any media_items/media_streams/review_plans schema change must ship an idempotent ALTER TABLE migration in server/db/index.ts — don't rely on the factory-reset button feedback de22fecc-a14b-436f-b6c2-55e545bca160

When adding or altering a column in server/db/schema.ts, also add an idempotent ALTER TABLE ... ADD COLUMN migration in server/db/index.ts so existing deployments (the Unraid container with a persistent ./data volume) pick it up without losing scan state.

Why: On 2026-04-13 we wiped the schema twice in one day (canonical-language rewrite, schedule split). The first time I deleted the old try/catch migration shims because the user said "drop the whole scan database" — fine for local dev, but the production container's volume silently carried the old schema and the scan loop crashed with table media_items has no column named original_title. We then re-added migrations, then deleted them again because a factory-reset button now handles the upgrade path. The user's intent after that last removal was not "migrations are dead forever" — it was "for this one upcoming reset, we don't need them." Future schema changes should resurrect the pattern.

How to apply:

  • The pattern: a local addColumn(table, column, type) helper inside getDb() (or a dedicated applyMigrations(db) function) that wraps each ALTER TABLE ... ADD COLUMN in try/catch, because SQLite has no ADD COLUMN IF NOT EXISTS. Keep entries forever — fresh installs get the column from SCHEMA; upgrading installs get it from the migration function. Removing an entry breaks any install that didn't apply it yet.
  • For destructive changes (renames, type changes, dropped columns) the factory-reset button in Settings → Danger Zone is the escape hatch — tell the user to click it.
  • When in doubt, check git history around 2026-04-13: commit c06172f added the migration function back, commit a3fde7c removed it as a temporary simplification.