Event-wide searchable Audit page; Marshaling keeps a compact strip#352
Merged
Conversation
…pact strip
Marshaling is the "do the work" page — the full per-heat audit trail moves to
a new first-class, event-wide Audit review surface ("defensible results").
Server:
- New open read GET /events/{event_id}/audit serving Vec<EventAuditEntry>
(the per-heat AuditEntry fields flattened + a heat tag), newest first.
Built by running the EXISTING per-heat audit fold (marshaling_log over
heat_window_offsets) per scheduled heat, so the Audit page can never
disagree with Marshaling's per-heat view — including the window rules:
a late ruling heat-tagged to a finished heat lands under THAT heat, and
a Restarted heat's pre-restart rulings are absent (current-run window).
- Unit tests: cross-heat tagging + newest-first merge, restart exclusion,
unknown-event 404. ts-rs binding exported (bindings/EventAuditEntry.ts).
Console:
- New workspace tab "audit" (route.ts, App.svelte, Alt+7, magnifier icon)
rendering screens/EventAudit.svelte: newest-first rows with kind badge
(DQ / Time penalty / Points / Lap added / ... derived per entry), resolved
pilot callsign + friendly heat name as clickable filter chips, the #337
re-composed summary (raw "(ref N)" stripped), and the log ref trailing.
Client-side filters: pilot / heat / kind / free text. Role-agnostic pure
read; #340 error-state + retry (no silent []).
- Shared lib/auditRender.ts: the #337 helpers extracted from Marshaling
(badge/label/time/ref-strip/competitor-chase/line composition) so the
Audit page and Marshaling render every entry identically.
- lib/auditFilter.svelte.ts: the one-shot cross-screen prefilter seam —
openAudit(setTab, {heat?, pilot?}); EventAudit consumes+clears on mount.
- Marshaling: full trail replaced by a "Recent rulings" strip (latest 3,
same shared rendering) + "View full audit →" jumping pre-filtered to the
marshaled heat. The heat-scoped audit read stays — the Reverse-ruling /
Resolve-protest pickers and the open-protest Finalize gate derive from it.
- Results: each ROUND-standings row gains a per-pilot "audit" affordance
jumping to the Audit page pre-filtered to that pilot.
- protocol-client: eventAudit(baseUrl, eventId) mirroring roundStandings;
session.eventAudit() with test seam.
Tests: EventAudit page suite (order, names, chips, filters, prefilter,
error+retry, read-only); Marshaling strip tests (latest-3, prefiltered
jump) with picker tests untouched; Results audit-link test; new contract
suite (contract/audit.contract.ts) driving a real Director through
schedule -> run -> finalize -> penalty + void, asserting heat tags and
newest-first order over the wire.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The user-approved split of the audit trail's two jobs (review vs action source):
GET /events/{id}/auditmerges the existing per-heat audit fold over each heat's window (identical attribution to the Marshaling view — including the current-run rule), tagged with the heat, newest-first. NewEventAuditEntrybinding +eventAuditclient helper.lib/auditRender.tsso the strip, the pickers, and the page can't drift.Gates: 16 Rust suites (3 new fold tests incl. restart-run exclusion), 536 console tests (new EventAudit suite; strip + cross-link tests), contract 91 incl. a new audit.contract.ts against a real Director, both check passes, clippy/fmt/lint clean. Verified live: the route + page render the real test event's marshaling history (screenshot-checked).
🤖 Generated with Claude Code