WordloopWordloop
WorkMeeting RecordingTechnical Design DocMilestones06 Live Notes

Core — Live Notes

PATCH /meetings/:id notes field update, debounced write semantics, and EntityChangedEvent broadcast to the owner's other sessions.

Core — Live Notes

Owner: Core Engineer Domain: core Complexity: S Prerequisite: Milestone 03 merged (shared note components)

When this slice is complete, PATCH /meetings/{id} accepts a notes field update at any time — including during an active recording — persists every edit immediately (there is no separate save/commit call), echoes the stored value in the response, and broadcasts EntityChangedEvent { entity: "meeting", action: "updated", fields: ["notes"] } to the owner's other sessions while excluding the originating Client-Session-Id. Notes are never touched by any ML write-back path (PUT /synthesis, POST /talking-points, PUT /tasks/system) or by service-auth field updates such as the generated headline.

Required Capabilities

  • PATCH /meetings/{id} accepts {"notes": string | null} and persists it immediately, with no separate save/commit call.
  • The response echoes the saved notes value.
  • GET /meetings/{id} and GET /meetings (list shape) carry notes.
  • Every successful notes PATCH broadcasts EntityChangedEvent { entity: "meeting", action: "updated", fields: ["notes"] } to the owner's other WebSocket sessions.
  • The originating Client-Session-Id does not receive an echo of its own edit.
  • PUT /meetings/{id}/synthesis, POST /meetings/{id}/talking-points, PUT /meetings/{id}/tasks/system, and the service-auth headline PATCH never modify notes.
  • An invalid notes body (non-string, non-null) is rejected with 422 without altering the previously saved value.
  • A PATCH against a meeting that does not exist, or that belongs to another user, is rejected (404/403) without altering the previously saved value.

Dependencies

  • Milestone 03 (reusable-note-components) must be merged — this slice reuses the shared note rendering components on the finalized meeting page.
  • Milestone 04 (live-transcript-to-final-rebuild) must be merged — the live recording WebSocket session used to exercise the autosave path during an active recording.

Domain Notes

Notes are a plain field on meetings, not a generated artifact — they are the one piece of state on the recording session that no ML write-back path is allowed to touch. There is no autosave endpoint distinct from the ordinary PATCH: durability comes from every PATCH being immediately persisted, so a debounced client can fire as many of them as it likes and only the latest write wins.

Write-back pathTouches notes?
PATCH /meetings/{id} (user)Yes — this is the only path that writes notes
PUT /meetings/{id}/synthesis (ML)No
POST /meetings/{id}/talking-points (ML)No
PUT /meetings/{id}/tasks/system (ML)No
PATCH /meetings/{id} (service, headline)No — updates headline only

Test Cases

Test cases map to tests/bets/meeting-recording/test_milestone_06_live_notes.py. Run via ./dev test bet meeting-recording.

TestLocationAssertion
test_user_can_edit_private_notes_while_recordingtest_milestone_06Three successive PATCH /meetings/{id} calls during an active recording each persist and echo their notes value, and the owner's other WebSocket session receives one entity.changed(meeting, fields=["notes"]) per edit.
test_notes_autosave_without_manual_savetest_milestone_06Five rapid PATCH calls tagged with a Client-Session-Id leave the last value stored with no explicit save call; the owner's other session sees all five entity.changed events, and the originating session receives none of its own.
test_notes_restore_after_refresh_during_recordingtest_milestone_06A brand-new client (GET /meetings/{id} and GET /meetings) sees the latest saved notes while the recording is still active.
test_notes_survive_stop_and_finalizationtest_milestone_06After stop and finalization, GET /meetings/{id} returns the unchanged notes alongside the completed final synthesis.
test_generated_artifacts_do_not_overwrite_notestest_milestone_06PUT /synthesis, POST /talking-points, PUT /tasks/system, and the service PATCH headline update all succeed without changing notes.
test_note_save_failure_does_not_corrupt_saved_contenttest_milestone_06An invalid body (422), a save against a non-existent meeting (404/403), and a save by a different user (403/404) all leave the previously saved notes intact; a subsequent valid save still succeeds.

Completion Checklist

  • Code merged and deployed
  • Bet progress tests pass (./dev test bet meeting-recording)
  • Permanent service tests implemented per testing strategy
  • Code review completed
  • API review completed (PATCH /meetings/{id} notes semantics)
  • Testing review completed
  • System documentation updated (API reference, architecture docs as applicable)

On this page