[E08] Import Results
Actor & Context
Actor: event organiser, results officer, tenant admin.
Frequency: per event (initial result import, corrections during the verification window).
Precondition: event has finished; EPs exist; user has EVENT_MANAGER or RESULTS_OFFICER permission.
Entry point: Import results button on E04 Event Results; from E05's Results unverified pill click.
Main Flow
-
Upload screen. File picker (CSV/XLSX), result-import-specific options:
-
Identifier mode (
participantIdMode) —EPID/PERSON_ID/REGISTRATION_ID. Defaults fromEvent.preferredTimingIdentifier(per Participant Identity Correlation F14, US #699). Operator can override per-import; override logged in summary. The three modes drive how the inboundExternalReferenceIDcolumn is interpreted to match the EP record:-
EPID→ matchEP.id -
PERSON_ID→ match(Event.id, Person.id)composite -
REGISTRATION_ID→ matchEP.registrationId(cross-system mode, used when EPs were imported from an external registration system)
-
-
DNF / DNS / Drop status handling toggle (per US #457).
-
Repeated header tolerance (per Bug #453).
-
-
User clicks Upload — write
localStorage.importCaller = 'e08', thenPOST /api/imports?participantIdMode=…&statusHandling=…&repeatedHeaders=…. -
Redirect to C05 for column / cell mapping + progress.
-
C05 redirects back on completion to the summary screen.
-
Summary screen. Per-row reconciliation:
-
Created / updated result counts.
-
Unresolved EPs surfaced as actionable issues (US #456).
-
DNF / DNS / Drop entries reported separately (US #457).
-
Non-data-line counts (US #455).
-
Identifier-mode mismatch warning — surfaces when the operator’s chosen mode differs from
Event.preferredTimingIdentifier. Per F14 (US #699). -
Link to E04 for follow-up.
-
Alternative Flows
-
AF-1: Re-import during correction window — existing results updated; summary distinguishes new vs corrected.
-
AF-2: Re-import after correction window closed — soft warning; user must confirm before submit.
-
AF-3: Cancel / fatal error — same patterns as E06.
Acceptance Criteria
-
Use-case page authored.
-
Status
design-todo → handoff-readyafter Claude Design pass. -
:design-url:populated. -
Cross-references C05 + E04 + E05.
-
DNF / DNS / Drop entries surfaced separately per US #457.
-
Unresolved EPs surfaced as actionable issues per US #456.
API Surface
| Call | Purpose |
|---|---|
|
Create import job from uploaded file + result-import options. |
|
Reads |
|
Driving the summary screen. Per F14 (US #699), each |
(delegates to C05 for column / cell / progress) |
Shared mapping flow. |
Design Anchors
Design Decisions
-
Three identifier modes for participant resolution (2026-05-04). Per Participant Identity Correlation § Decisions Made (Timing round-trip), the inbound
ExternalReferenceIDcolumn is interpreted as one of:-
EPID— our internalEventParticipant.id. Used when our system is authoritative for the event lifecycle. -
PERSON_ID— our internalPerson.id. Default for new events; safe across multiple events for the same person. -
REGISTRATION_ID—EP.registrationId(the source system’s EP UID). Used when EPs were imported from an external registration system and we want timing to round-trip their identifier back.The mode default per Event lives in
Event.preferredTimingIdentifier(set during EP creation, lockable via the timing-export UI gate per F12 US #697). Result import reads this default but lets the operator override per-import — useful when re-importing legacy result files exported with a different mode than the Event currently has set. Mismatch surfaced in summary as a warning, not an error.
-
-
Persist inbound
ExternalReferenceIDtoRaceResult.externalReferenceIdfor audit (2026-05-04). Per F14 (US #699). Detects mode-change drift, supports forensic comparison ("what we last exported" vs "what they returned"), aids Bug #417 (duplicate RaceResult records) debugging. Light cost (one VARCHAR column); high audit value. -
Bookend pattern mirrors E06 (2026-05-04). Same upload + summary structure as E06; same C05 caller-key contract (
'e08'literal); same async-import state machine. The result-import-specific options live entirely on the upload screen + summary; the mapping middle steps are content-type-agnostic.
Notes
Backend result-import improvements: PR #146 (merged) + PR #147 (in flight). USs #455–#458 detail the row-level reporting nuances the summary screen must surface. The 2026-05-04 design adds the identifier-mode strategy and RaceResult.externalReferenceId audit field; backend changes scoped under Participant Identity Correlation F14 (US #699).