test(realtime): broadcast parity for every MCP write tool

A suite under tests/integration/broadcast-parity boots the app once per
group, runs a write tool through a real MCP session the way the
assistant attaches the registry, runs its REST twin on a twin scene, and
records every broadcast. Per case it checks the exact events in order and
count, that no MCP broadcast skips a socket (the asking tab hears its own
change), that nothing is sent inside a transaction, that every payload
parses with its registered schema, that REST sends the same sequence to
the same room and recipients, and that MCP's keys cover REST's.

A registry test lists the write tools as an MCP client sees them and
fails on a tool without a row, a stale row, or an exemption without a
reason; exemptions run too and must send nothing, and the tools still
waiting for a case are frozen in a list that may only shrink.

The new events the next changes send are registered now (member:updated,
todo:reordered, trips:changed, settings:updated, tags:changed,
notification:read-all, journey:updated, journey:deleted, atlas:changed);
the client keeps them apart as awaiting a sender, and the journey page
already leaves a journey that journey:deleted says is gone.
This commit is contained in:
Maurice
2026-10-22 00:03:34 +00:00
parent 5daa2a0311
commit 72ff9600f4
25 changed files with 2058 additions and 14 deletions
+19
View File
@@ -72,6 +72,9 @@ export const HANDLED_OUTSIDE_TRIP_STORE = [
'vacay:share-removed',
'vacay:shared-update',
// Journey — pages/journeyDetail/useJourneyDetail ('journey:' prefix listener)
// reads the open journey again, and leaves it once journey:deleted says it is gone.
'journey:updated',
'journey:deleted',
'journey:trip:synced',
'journey:entry:created',
'journey:entry:updated',
@@ -142,3 +145,19 @@ export const IGNORED_WS_EVENTS = [
'member:added',
'member:removed',
] as const satisfies readonly TrekWsEventName[]
/**
* Events registered ahead of the write that sends them: nothing on the server
* sends these yet, so there is nothing for the client to act on. They are not
* a decision to ignore. The change that adds a sender moves its event to a
* handler, and the list only shrinks.
*/
export const AWAITING_SENDER_WS_EVENTS = [
'member:updated',
'todo:reordered',
'trips:changed',
'settings:updated',
'tags:changed',
'notification:read-all',
'atlas:changed',
] as const satisfies readonly TrekWsEventName[]