feat(schema): AgentMessage + AgentMessageArchive voor s4m-queue (fase 1) #37
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-shared!37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/agent-message-schema"
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 1b van de s4m-queue-migratie naar de scrum4me-DB. Spec + plan:
scrum4me-mcpdocs/superpowers/{specs,plans}/2026-07-12-s4m-queue-*.Waarom
De losse berichtenqueue
s4m-queue(eigen DBops_dashboard) wordt onderdeel van het platform. Deze PR definieert de modellen; de SQL-migratie zelf volgt in Scrum4Me (designated migrator).Harde eis: de tabel-DDL moet identiek blijven aan
s4m-queue/migrations/001_init.sql+002_archive.sql— de CLI (raw SQL) en het Messages-dashboard blijven op deze tabellen werken en wisselen straks alléén van connection string.Wat er in zit
61e75bbAgentMessage+AgentMessageArchivefd00f03d00c504map:als load-bearing9548ec7__tests__/agent-message-schema.test.ts— guard-test062ec752df5d0eDe DDL is byte-identiek sinds
61e75bb— alles daarna is documentatie en guard.DDL-equivalentie: geverifieerd, niet beredeneerd
Beide reviewers genereerden de DDL via Prisma en legden die naast de bronmigraties. De spec-reviewer tuigde daarvoor een wegwerp-Postgres 17 op, paste bron-DDL en Prisma-DDL toe in twee schema's en vergeleek via
information_schema/pg_attributeop ordinal position: 34/34 kolommen equivalent op naam, type, nullability, default én volgorde.Hij draaide bovendien de échte raw SQL van de CLI tegen de Prisma-gegenereerde tabellen: de push-
INSERT(die id/meta/status/created_at weglaat en dus alle vier de defaults uitoefent), de claim-CTE verbatim uitsrc/db.ts, en het reply/FK-pad. Werkt.Vier verschillen zijn representatief, geen defect:
DEFAULT CURRENT_TIMESTAMPvsnow()(zelfde functie),TIMESTAMPTZ(6)vs baretimestamptz(typmod 6 vs -1, beide microseconde, round-trip identiek), PK-naamagent_message_pkey(die kent Postgres zelf toe aan de inlinePRIMARY KEYvan de bron), en de afwezige CHECKs (bewust — die horen in de SQL-migratie).Drie constructen zijn load-bearing en zien er niet zo uit
Dit is de kern van waarom hier een guard-test bij zit. Alle drie laten zich verwijderen met een groene
prisma validate:replied_to/repliesmap:op de claim-indexagent_message_to_server_to_model_status_created_at_idxonUpdate: NoActionON UPDATE CASCADEi.p.v.NO ACTIONHet relatiepaar is het venijnigste: niets consumeert het (CLI en dashboard zijn raw SQL), dus het ziet eruit als twee ongebruikte velden in een model waarvan de comment zelf zegt dat alles via raw SQL loopt. Het bestaat uitsluitend om de FK te emitten. Alleen
repliesweghalen geeft wél P1012; het paar als geheel niet.map:komt nergens anders in de 1326 regels voor — het ís dus de regel die eruitziet als een inconsistentie die iemand rechttrekt.De guard-test
__tests__/agent-message-schema.test.ts, in het idioom van de twee precedenten in deze repo (claude-job-usage-schema.test.ts,model-price-rate-card-schema.test.ts). Vóór deze PR beschermde niets deze modellen (grep -rn "AgentMessage" __tests__/→ nul hits).12 tests, elk aantoonbaar rood tegen een echte sabotage.
prisma validateliet alle twaalf gewoon door:map:wegonUpdate: NoAction→CascadeonDelete: SetNull→Cascade@@maphernoemd@db.Uuidwegmeta-default wegfrom_server→fromServer)String→IntDe kolom-guard deelt één
COLUMNS-lijst over beide modellen, wat 002's belofte "kolommen identiek aan agent_message" een uitvoerbare assertie maakt in plaats van een comment. De volgorde is bewust gepind: de cutover valideertinformation_schema.columnsinclusief ordinal position, encleanup.tshing daaraan — een reorder is dus een echte faalmodus.Bewuste keuzes
@db.Uuid/@db.Timestamptz(6)wijken af van de cuid/DateTime-huisstijl. Opzet: de DDL moet identiek blijven.@mapper kolom, in afwijking van wat de spec oorspronkelijk vroeg: snake_case ís de huisstijl hier, dus veldnaam == kolomnaam en 34@map-attributen zouden no-ops zijn. De spec is hierop gecorrigeerd.002_archive.sqlnoemt bij de weglatingen alleenreply_link_matches_typeen is daarmee onvolledig; dat staat nu expliciet in de doc zodat de migratie-auteur er niet drie te veel toevoegt.Verificatie
npm run verify: exit 0, 21 bestanden / 231 tests (was 20/219)prisma validate: groen, met sabotage-matrix aangetoond dat validate deze modellen echt uitoefentprisma formatlaat beide nieuwe blokken byte-identiek (pre-existing drift elders met rust gelaten)🤖 Generated with Claude Code
Verdict: REQUEST_CHANGES
Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
Findings
__tests__/agent-message-schema.test.ts:1: de nieuwe test importeertnode:fs. De actieve productdocProduct-doc write closure in @shared (dep-clean, ESM)beschrijft de purity gate als een brede ban op bare/node:builtins, met alleen een gerichte uitzondering voorproduct-doc-*.ts. Daardoor is dit waarschijnlijk niet conform de product-standaard en kannpm run verifyrood worden viascripts/verify-no-deps.sh. Los dit op zonder verboden builtin-import, of pas gate + productdoc expliciet mee aan als tests bewust buiten deze regel moeten vallen.Samenvatting
De Prisma-modellen zelf volgen de gedocumenteerde rol van
scrum4me-sharedals canonieke schema-bron en vermijden migraties in deze repo. De extra schema-regressietests zijn inhoudelijk zinvol, maar de nieuwenode:fsdependency botst met de gedocumenteerde dependency-hygiene afspraak.Reactie op de REQUEST_CHANGES: de
node:fs-finding klopt nietDe finding stelt dat
__tests__/agent-message-schema.test.ts:1(import { readFileSync } from 'node:fs') de purity gate schendt ennpm run verifyrood kan maken. Dat is nagetrokken en weerlegd — hieronder de vier controles.1. De gate scant
lib/, niet__tests__/scripts/verify-no-deps.shzegt het in zijn eigen eerste regel:Elke
grep -rEnin het script draait over"$LIB_DIR".__tests__/valt buiten scope. Dat is ook de bedoeling van de regel: de gate bewaakt het dependency-oppervlak van wat er verscheept wordt. Een test dieprisma/schema.prismaals tekst inleest, kanlib/niet vervuilen — hij importeert er niets uit en wordt niet meegebundeld.2. Beide precedent-tests doen exact hetzelfde en staan al op
mainDe nieuwe test volgt bewust dat gevestigde idioom. Was dit een overtreding, dan stond
mainal rood sinds die twee tests landden.3.
lib/is dep-cleanDe enige
node:-imports inlib/zijnnode:crypto/node:pathinproduct-doc-*.ts— precies de gedocumenteerde uitzondering.4.
npm run verifyis groen, gemeten op deze branchInclusief
bash scripts/verify-no-deps.shénbash __tests__/scripts/verify-no-deps.test.sh, die allebei in het verify-script zitten.Conclusie
De finding is een hypothese ("waarschijnlijk niet conform", "kan rood worden") die met één commando te toetsen was. De productdoc beschrijft de gate zoals hij geïmplementeerd is — over
lib/— en niet als een repo-brede ban opnode:-builtins.Geen wijziging. De test aanpassen om
node:fste vermijden zou hem óf onmogelijk maken (het schema is een bestand; je moet het lezen) óf laten afwijken van het patroon van de twee precedenten, zonder enige winst in dependency-hygiëne.Wat wél terecht is in de review: de modellen volgen de canonieke-schema-rol van deze repo en houden migraties erbuiten. Dat is inderdaad de bedoeling — de SQL-migratie landt in Scrum4Me als designated migrator (fase 1c).
Ter aanvulling, want het is de kern van deze PR:
prisma validateliet alle twaalf sabotages door die de guard-test wél vangt — relatiepaar weg (FK verdwijnt stil),map:weg (index hernoemd),onUpdate: NoAction→Cascade, kolom hernoemd/verwijderd/van type gewisseld. Die test is precies wat er tussen een stille Prisma-default en een gebroken CLI op runtime staat.🤖 Generated with Claude Code