fix(demo): let the crew view show the report the passenger actually filed - #43
Merged
Merged
Conversation
…iled The demo's one claim is that the crew hears about a lost item while it is still on board, and that hop was the part that was faked: /staff staged a notification hardcoded into the page on a 5s timer, so whatever a visitor reported on /, the crew saw "Schwarze Laptop-Tasche, Wagen 7, Platz 45" — the same string twice over, once in the list and once in the alert. The two halves of the demo now talk to each other. lib/demo-bus.ts carries a submitted report to the crew view through same-origin localStorage, and the `storage` event delivers it to the other tab, which is how the demo is shown (passenger on one screen, crew on another). LostItemModal publishes only when `result.item` is absent — i.e. the reporting service did not take the report, so no notification service will push it either. With a backend, the copy here would be a duplicate under a second id, so it is not written. `config.demo.enabled` is deliberately NOT the gate: it is false whenever an API URL is merely configured, including dev against a backend that is not running — exactly the case the fallback exists for. The staged notification stays for a visitor who opens /staff with no second device, but moves to mock-data as createDemoIncomingNotification(), derived from mockActiveTrip so seat and route cannot drift, and it stands down once a real report has arrived. The alert dialog renders the arriving notification instead of repeating a literal. Also: .playwright-mcp/ is git-ignored only in a personal global gitignore, so its snapshots survived into `prettier --check` and turned any browser pass into a red `verify`. Ignored in both files here. Verified end-to-end against the dev server with no backend running: reported "Rote Lesebrille im schwarzen Etui / Gepäckablage" on /, and the /staff tab already open in the same browser raised the alert with that text, that seat and the 👓 category, then took "Gefunden" on it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014MT1aaWfJeDUZpTxZ3DfHg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was broken
The demo's headline claim is that the crew hears about a lost item while it is still on board. That hop was faked:
/staffstaged a notification hardcoded into the page on a 5s timer, so whatever a visitor reported on/, the crew saw "Schwarze Laptop-Tasche, Wagen 7, Platz 45" — the same literal twice, once in the list and once in the alert dialog.For a portfolio piece whose only job is being credible when shown, that is the one thing that must not be theatre.
What changed
frontend/lib/demo-bus.ts(new) — carries a submitted report to the crew view through same-originlocalStorage; thestorageevent delivers it to the other tab, which is how the demo is actually shown (passenger on one screen, crew on another). Pure mapping (notificationFromReport) and defensive parsing (parseReports) are separated out and unit-tested.LostItemModalpublishes only whenresult.itemis absent — i.e. the reporting service did not take the report, so no notification service will push it either. With a backend, this copy would be a duplicate under a second id, so it is not written.config.demo.enabledis deliberately not the gate: it is false whenever an API URL is merely configured, including dev against a backend that is not running — exactly the case the fallback exists for./staffingests handed-over reports on mount (history, no alert) and live (alert + buzz), keeps locally answered notifications answered, and renders the alert dialog from the arriving notification instead of a literal./staffwith no second device, but moves tomock-data.createDemoIncomingNotification(), derived frommockActiveTripso seat and route cannot drift — and it stands down once a real report has arrived..playwright-mcp/was git-ignored only in a personal global gitignore, so its snapshots reachedprettier --checkand turned any browser pass into a redverify. Now ignored in.gitignoreand.prettierignore.Verification
npm run verifygreen: prettier clean, tsc clean, lint 0 errors, 67 tests pass (27 reporting-service + 40 frontend, 8 of them new), tenant SSOT ok.End-to-end against the dev server with no backend running: reported "Rote Lesebrille im schwarzen Etui / Gepäckablage" on
/; the/stafftab already open in the same browser raised the alert with that text, that seat (Wagen 7, Platz 42A • Gepäckablage) and the 👓 category, and then took "Gefunden" on it.Still simulated
The return path — the passenger learning what the crew answered — is still a
setTimeouttoast on/. Same bus, opposite direction; not in this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_014MT1aaWfJeDUZpTxZ3DfHg