feat(db): agent_message + agent_message_archive (s4m-queue fase 1) #136
No reviewers
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
janpeter/Scrum4Me!136
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/s4m-queue-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?
Fase 1c van de s4m-queue-migratie naar de scrum4me-DB. Scrum4Me is de designated migrator, dus de SQL-migratie landt hier. Spec + plan:
scrum4me-mcpdocs/superpowers/{specs,plans}/2026-07-12-s4m-queue-*.Volgt op de gemergde s4m-queue #12 (cleanup-fix) en scrum4me-shared #37 (de modellen).
Wat er in zit
9d618d04a819432d2154868d652422ff99504c514c209d69fDe DDL is byte-identiek sinds
9d618d0— md5 van het comment-gestripte bestand is gelijk over alle zeven commits (8a5dc5ab…). Alles daarna is comment en test.DDL-equivalentie: het hele contract
De s4m-queue-CLI (raw SQL) en het Messages-dashboard blijven op deze tabellen werken en wisselen straks alléén van connection string. De DDL moet dus identiek zijn aan
s4m-queue/migrations/001_init.sql+002_archive.sql, op twee bewuste afwijkingen na.Drie diffs tegen een echte Postgres, onafhankelijk gedraaid door implementer én reviewer (en nogmaals ná de comment-edits):
information_schema.columnsincl.ordinal_position)pg_constraint, schema-genormaliseerd)source_checkkrijgt'mcp'pg_indexes)agent_message_in_reply_to_idxPrecies de twee bedoelde afwijkingen, geen derde. De constraint-dump bevestigt ook dat het archief alleen zijn pkey draagt — nul CHECKs, nul FK, geen index, conform 002.
Subtiliteit die de review opleverde: PG17 slaat
DEFAULT now()enDEFAULT CURRENT_TIMESTAMPverschillend op in de catalog. Deze migratie gebruiktnow()(zoals 001), Prisma emitCURRENT_TIMESTAMP, en dit is de enige handgeschrevenDEFAULT now()in echte DDL in deze repo. Eenmigrate diff --from-emptyvergelijkt Prisma met Prisma en is daar structureel blind voor; de--from-config-datasource-variant tegen een scratch-schema met de echte DDL bewees dat Prisma beide normaliseert — geen drift.Bewuste keuze: kale
CREATE TABLE, géénIF NOT EXISTSIF NOT EXISTSzou stil slagen tegen een tabel van afwijkende vorm — en DDL-identiteit is het hele contract hier. Dan levert het de CLI op runtime een kapotte tabel. Luid falen is correct. (De 14IF NOT EXISTS-migraties in deze repo zijn hotfix-reconciliaties, een ander probleem.)Niet-transactioneel — lees de header vóór de deploy
Prisma wrapt migratiebestanden niet. Getest op PG 17.10 met echte migratiehistorie: faalt dit bij het láátste statement, dan blijft
agent_messagestaan én houdt_prisma_migrationsfinished_at IS NULL— waarna élke volgende deploy stopt met P3009 (de falende deploy zelf meldt P3018; in CI is P3009 het enige dat de operator ooit ziet). Omdat Scrum4Me designated migrator is, blokkeert dat de migratiepijplijn van het hele platform.BEGIN;/COMMIT;lost dat op, maar degradeert de CLI-fout tot "current transaction is aborted" en verbergt de echte42P07. Bewust niet gedaan: de dominante faalmodus (tabellen bestaan al) faalt bij statement 1 met nul residu. Het herstelpad staat in de header.Die runbook is twee keer bijgesteld na review, en dat was nodig. De eerste versie vernietigde data in zijn eigen dominante faalmodus — gereproduceerd met 42 echte rijen:
Stil verlies, met een succesmelding erachteraan. De runbook was geschreven voor "faalt halverwege" (leeg restant, droppen veilig) maar was het enige
Herstel:-blok in het bestand. Nu is de drop conditioneel op de werkelijke fout en eist hijcount(*) = 0op beide tabellen. Beide scenario's zijn daarna letterlijk nagespeeld: 42 → 42, en het legitieme halve-fail-herstel blijft uitvoerbaar.Guard-test
__tests__/db/agent-message-queue-migration.test.ts, string-assert-huisstijl conform de acht precedenten in__tests__/db/. De guard in scrum4me-shared bewaakt het Prisma-schema; deze bewaakt de migratie-SQL, waar het identiteitscontract en beide afwijkingen leven.7 tests, elk aantoonbaar rood tegen een echte sabotage:
'mcp'in_reply_to-index wegbodyverliestNOT NULLmeta-default'{}'→'[]'in één tabelDe laatste is per
CREATE TABLE-blok geassert, niet over het hele bestand: beide tabellen dragenmeta … DEFAULT '{}', dus een whole-file-assert blijft groen bij eenzijdige drift — precies wat hij moet vangen. Het mutatie-harnas breekt af als een vervanging niets raakt, dus geen vacuüm-rode tests.Twee dingen die je moet weten
1. De submodule-bump landt shared PR #36 mee.
resolveRuntimeJobConfigverandert CODEX-modelresolutie vank.codex_model ?? nullnaarisCodexModel(...) ? ... : 'gpt-5.5', en versmaltmodel: string | null→string. Geen defect — main draagt de tegenhanger-datamigratie20260714160000_set_codex_model_flooral, dus de bump sluit juist een achterstand, en de 43 geraakte tests slagen. Staat ook in de commit-body van9d618d0.2. Gitlink-conflict met
chore/gen-schema-drop-url-strip. Die branch bumpt de submodule naarab6e97b, dat niet op shared's main zit maar op een chore-branch daar. Deze branch pint op shared's main-tip. Geen van beide bevat de ander → conflict voor wie tweede merget. Suggestie: deze eerst, dan landt die branch zijn shared-PR en herpint.Verificatie
npm test: 213 bestanden / 1654 tests, exit 0 (de ene skip ishierarchical-order-migration-livedie zichzelf skipt zonderTEST_DATABASE_URL)npx prisma validate: groenDe deploy naar productie is een aparte taak met expliciete hardstop.
🤖 Generated with Claude Code
Laatste default-gat: meta '{}' -> '[]' bleef groen. Bewust per CREATE TABLE-blok geassert in plaats van op het hele bestand — beide tabellen dragen dit default, dus een hele-bestand-toContain blijft groen zodra één van de twee nog '{}' heeft. Rood-bewijs bevestigt dat: bij een mutatie in alleen agent_message (of alleen het archief) staat de naïeve vorm vals groen en de per-blok-vorm rood. Titel van de archief-test gecorrigeerd: die claimde 'zonder kolom-defaults', maar het archief draagt meta's '{}' wél — het mist alleen id/status/created_at. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Verdict: APPROVED
Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
Findings
Review-notities
agent_message/agent_message_archivecontract: UUID/timestamptz/raw-SQL compatibiliteit, expliciete@@map, handmatige CHECK-constraints in SQL en bewuste afwijkingen voorsource='mcp'enin_reply_to-index.vendor/scrum4me-shared; de inhoud daarvan zit niet in de payload-diff en kon in deze review-runtime niet inhoudelijk worden geïnspecteerd. Op basis van de zichtbare diff is dat geen blocker.