feat(db): roll DEFAULT_TABLE_CONFIG to 2026 — teams_2026_summer_sat + streams_2026_summer_sat #23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/2026-summer-sat-tables"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Rolls the runtime table year forward for the 2026-06-13 event. Fresh DBs now come up as
teams_2026_summer_sat/streams_2026_summer_sat; the home page and all runtime API routes follow.Per direction in the conversation that asked for this (2026-05-20):
Changes
lib/constants.ts:DEFAULT_TABLE_CONFIG.year2025 → 2026.TABLE_NAMESnow resolves to the 2026 tables.getTableName(..., { year: 2025, ... })toTABLE_NAMES.{TEAMS,STREAMS}— these would otherwise silently keep targeting the 2025 tables (split-brain vs. the home page):app/api/createGroup/route.ts(UPDATE teams)app/api/syncGroups/route.ts(SELECT + UPDATE teams)app/api/addStream/route.ts× 3 (fetchTeamInfo, UUID UPDATE, INSERT into streams)app/api/__tests__/yearHardcodeGuard.test.ts: new CI guard that scansapp/api/**/*.tsfor literalyear: NNNN. Fails CI if any future runtime route hand-rolls a year config — so the next year roll is a one-line edit again, not a five-site safari.lib/__tests__/database.test.ts: newDEFAULT_TABLE_CONFIGblock pinningyear=2026andTABLE_NAMES.*to the 2026 names — anchors the bump so it can't silently regress.Non-changes (intentional)
scripts/{addGroupNameToTeams,addGroupUuidColumn,createSatSummer2025Tables}.tskeep their hard-codedyear: 2025. They are historical migration scripts named for the 2025 season; rewriting them rewrites history nobody asked for.initializeDatabase()creates the 2026 teams table withgroup_name+group_uuidalready baked in (per #21), so a fresh-DB cold-start needs no follow-upALTERs.CREATE TABLE IF NOT EXISTSis a no-op for those tables; they sit alongside the new 2026 tables, read-only by definition since no runtime route targets them after this commit.Test plan
yearHardcodeGuard+DEFAULT_TABLE_CONFIGpins); full suite 149/22 green.npm run audit:sqlite-openscleanDepends on
CREATE TABLEonly includesgroup_name/group_uuidbecause of #21; without it, fresh 2026 DBs would still trip/api/streams. Branch is rebased onto #21 — please merge #21 first.A fresh checkout (no sources.db inherited from a prior run, e.g. a hot- spare laptop provisioned at the venue) tripped /api/streams with SQLITE_ERROR: no such column: t.group_name. The columns were added late in the project via standalone migration scripts (addGroupNameToTeams.ts, addGroupUuidColumn.ts) that aren't auto-run on cold start, so a freshly-initialized DB had only (team_id, team_name). Phase 0.8 closes the foot-gun: 0.8.1 lib/database.ts: fold group_name TEXT + group_uuid TEXT into the teams CREATE TABLE IF NOT EXISTS. Migration scripts stay in place — they remain idempotent via PRAGMA table_info checks, so existing DBs are unaffected. 0.8.2 app/page.tsx unwrap path: Array.isArray guard around the streams payload and a typeof-object guard around activeSources, so a future schema-drift bug (or any /api/streams 500) degrades to "empty list" rather than crashing streams.forEach / streams.find during render. 0.8.3 lib/__tests__/database.test.ts: in-memory SQLite test that asserts (a) the streams + teams tables hold every column referenced by runtime route SELECTs, and (b) the actual SELECT statements from /api/streams, /api/setActive, /api/syncGroups, and /api/addStream resolve without "no such column" errors. initializeDatabase() is now exported for this purpose. Future CREATE-TABLE / runtime-SELECT drift is a CI failure rather than an event-day surprise. Acceptance (manual, on a fresh DB): rm files/sources.db && npm run dev curl -sS http://127.0.0.1:3000/api/streams → 200 {"success":true,"data":[],"timestamp":"..."} → sqlite3 files/sources.db "PRAGMA table_info(teams_2025_summer_sat);" yields team_id, team_name, group_name, group_uuid. Suite: 146/21 passing (was 137/20; +9 in lib/__tests__/database.test.ts). Type-check + lint clean.The Phase 0.8.3 drift guard opens an :memory: SQLite via the same `open({...})` shape that the audit pattern catches. It's a pure test surface — never touches disk, never runs in production — so allowlist it like the other test/script sites. Without this, CI on #21 trips the audit immediately after the test file lands.The event is 2026-06-13. The app was still defaulting to the 2025 SaT tables — fresh DBs would come up named teams_2025_summer_sat / streams_2025_summer_sat and operators would need to manually run the 2025-named CREATE script before the venue went live. This rolls the default forward. Per user direction (2026-05-20): - Bump the default; 2026 becomes the runtime year. - Start 2026 fresh — no row migration from the 2025 tables. - Just teams + streams; no additional table types in scope. Changes - lib/constants.ts: DEFAULT_TABLE_CONFIG year 2025 → 2026. TABLE_NAMES now resolves to teams_2026_summer_sat / streams_2026_summer_sat. - 5 runtime API sites were hand-rolling getTableName(BASE_TABLE_NAMES.X, { year: 2025, season: 'summer', suffix: 'sat' }) instead of using TABLE_NAMES.X. After a year bump those would silently keep targeting 2025 (split-brain against the home page). Refactored to TABLE_NAMES.{TEAMS,STREAMS}: - app/api/createGroup/route.ts (UPDATE teams) - app/api/syncGroups/route.ts (SELECT + UPDATE teams) - app/api/addStream/route.ts × 3 (fetchTeamInfo, UUID UPDATE, INSERT into streams) - app/api/__tests__/yearHardcodeGuard.test.ts: scans app/api/**/*.ts for literal `year: NNNN`. Fails CI if any new runtime route hand- rolls a year config — the next year roll will be a one-line edit again, not a five-site safari. - lib/__tests__/database.test.ts: new DEFAULT_TABLE_CONFIG block pinning year=2026 and TABLE_NAMES.* to the 2026 names — anchors the bump so it can't silently regress. Non-changes (intentional) - scripts/{addGroupNameToTeams,addGroupUuidColumn,createSatSummer2025 Tables}.ts keep their hard-coded year:2025 — they are historical migration scripts named for the 2025 season; touching them rewrites history nobody asked for. No 2026 migration script is needed: initializeDatabase already creates the 2026 teams table with group_name + group_uuid baked in (Phase 0.8.1), so a fresh-DB cold-start needs no follow-up ALTERs. - 2025 row data is untouched in any DB that already holds it. CREATE TABLE IF NOT EXISTS is a no-op for those tables; they sit alongside the new 2026 tables, read-only by definition since no runtime route targets them after this commit. Acceptance (manual) rm files/sources.db && npm run dev curl http://127.0.0.1:3000/api/streams → 200 {"success":true,"data":[],"timestamp":"..."} sqlite3 files/sources.db ".tables" → streams_2026_summer_sat teams_2026_summer_sat PRAGMA table_info(teams_2026_summer_sat) → team_id, team_name, group_name, group_uuid (all four present) Suite: 149/22 passing (was 146/21 on phase-0.8; +3 in yearHardcodeGuard + DEFAULT_TABLE_CONFIG pins). Type-check + lint clean; sqlite-opens audit unchanged. Depends on #21 (Phase 0.8 — schema bootstrap). The 2026 teams CREATE TABLE only includes group_name/group_uuid because of #21; without it, fresh 2026 DBs would still trip /api/streams.