Result Import Functional Requirements
1. Business Context
After a race, the timing system (currently RaceDay Scoring) produces a CSV export containing finishing positions, times, and lap counts for every EventParticipant. Operations staff import this file into the admin service so that:
-
Each
EventCategoryrace’sResultSetreflects the authoritative finishing order -
Series leaderboards can calculate standings from
RaceResult.points -
Participants can view their results via the membership and registration portals
-
Downstream systems (reporting, federation submissions) have a single source of truth
The timing system’s CSV schema, PK conventions, and column labels can all change between releases, and results are often re-exported after the initial run (corrections, appeal outcomes). The import must therefore be idempotent, forgiving of minor schema drift, and auditable against the source file.
1.1. Scope
In scope:
-
Bulk CSV import for multi-category race result files
-
Resolution of the CSV’s external identifier to
EventParticipantvia configurable mode -
Full reconciliation of each
ResultSetagainst its category group in the CSV -
Points calculation via a pluggable strategy
-
Detection and optional application of race-number changes observed in the file
-
A reconciliation summary that accounts for every line of the input file
Out of scope (handled elsewhere):
-
Leaderboard aggregation across ResultSets (see Leaderboard Synchronization)
-
Single-race XLSX import (soft-deprecated, documented separately under Common Design)
-
Interactive category mapping for fuzzy name matches (deferred to async import framework)
2. Functional Requirements
2.1. FR-RI-001: Bulk CSV Import Endpoint
| ID | FR-RI-001 |
|---|---|
Title |
Multi-Category Bulk CSV Import (async) |
Priority |
High |
Description |
The system shall expose a single HTTP endpoint that accepts a CSV containing finisher rows for multiple |
Acceptance Criteria |
|
2.2. FR-RI-002: Participant Identifier Resolution Modes
| ID | FR-RI-002 |
|---|---|
Title |
Configurable Participant Resolution |
Priority |
High |
Description |
The system shall support three mutually-exclusive modes for resolving the CSV’s |
Acceptance Criteria |
|
2.3. FR-RI-003: Full Reconciliation per ResultSet
| ID | FR-RI-003 |
|---|---|
Title |
ResultSet Mirrors CSV Exactly |
Priority |
High |
Description |
The system shall reconcile each |
Acceptance Criteria |
|
2.4. FR-RI-004: Upsert by Seq (Record Identity Preservation)
| ID | FR-RI-004 |
|---|---|
Title |
Preserve RaceResult Identity Across Re-imports |
Priority |
High |
Description |
The system shall use a stable |
Acceptance Criteria |
|
Related |
2.5. FR-RI-005: Reconciliation Summary
| ID | FR-RI-005 |
|---|---|
Title |
Account for Every File Line |
Priority |
High |
Description |
The response shall contain a reconciliation summary that allows an operator to answer "was the file fully consumed?" without inspecting logs or the database. |
Acceptance Criteria |
|
2.6. FR-RI-006: Non-Data Row Classification
| ID | FR-RI-006 |
|---|---|
Title |
Classify Non-Data Lines Distinctly |
Priority |
Medium |
Description |
The system shall classify non-data lines into three named buckets so that the operator can distinguish "expected noise" from "unexpected malformed input". |
Acceptance Criteria |
|
2.7. FR-RI-007: Unmatched Category Reporting
| ID | FR-RI-007 |
|---|---|
Title |
Report Unresolvable Category Names |
Priority |
Medium |
Description |
The system shall report any |
Acceptance Criteria |
|
2.8. FR-RI-008: Pluggable Points Calculator
| ID | FR-RI-008 |
|---|---|
Title |
Per-Import Points Calculation Strategy |
Priority |
High |
Description |
The system shall recalculate |
Acceptance Criteria |
|
2.9. FR-RI-009: Number Change Detection
| ID | FR-RI-009 |
|---|---|
Title |
Detect and Classify Race Number Changes |
Priority |
Medium |
Description |
The system shall compare the imported |
Acceptance Criteria |
|
2.10. FR-RI-010: Optional Number Change Application
| ID | FR-RI-010 |
|---|---|
Title |
Apply SIMPLE Number Changes on Opt-In |
Priority |
Medium |
Description |
When invoked with |
Acceptance Criteria |
|
2.11. FR-RI-011: Idempotent Re-Import
| ID | FR-RI-011 |
|---|---|
Title |
Idempotent Re-Import |
Priority |
High |
Description |
Re-importing an unchanged CSV against the same event shall produce the same end-state without churning |
Acceptance Criteria |
|
2.12. FR-RI-012: Mode Mismatch Safety
| ID | FR-RI-012 |
|---|---|
Title |
Guard Against Catastrophic Delete on Mode Mismatch |
Priority |
High |
Description |
When |
Acceptance Criteria |
|
Status |
Not yet implemented — item surfaced by 2026-04-20 production incident (event 119 wiped). Tracked as Outstanding Item #10 in |
2.13. FR-RI-013: DNF / Non-Finisher Status Handling
| ID | FR-RI-013 |
|---|---|
Title |
Preserve Non-Finisher Status |
Priority |
Medium |
Description |
The system shall preserve the distinction between "finished at position N", "did not finish", "did not start", and "disqualified" so that reports and leaderboards render and score them correctly. |
Acceptance Criteria |
|
Status |
Partially implemented — admin-service-only subset shipped via ADO-457; schema changes ( |
2.14. FR-RI-014: Error Handling and HTTP Semantics
| ID | FR-RI-014 |
|---|---|
Title |
Errors Mapped to Meaningful HTTP Responses |
Priority |
High |
Description |
The system shall translate parsing and business errors into HTTP status codes that let a thin client distinguish retryable from non-retryable failures. |
Acceptance Criteria |
|
3. Non-Functional Requirements
3.1. NFR-RI-001: Throughput
The system shall accept an import upload within 5 seconds end-to-end (synchronous upload response, before background processing starts). Background processing of up to 1,000 data rows shall complete within 60 seconds wall-clock; larger files are no longer bounded by the nginx/gateway timeout because the HTTP request returns 202 Accepted as soon as the job is persisted. Observed production baseline on 2.3.31 (pre-async): event 121 (314 rows, 16 categories) completed in ~21 s; event 117 (938 rows, 14 categories) completed in ~3 min — post-async the ~3 min case no longer risks a 180 s gateway timeout. Post-upload processing latency is observable via the import.processWholeFile Micrometer timer (tagged importType).
4. Traceability
| Artefact | Reference |
|---|---|
ADO Feature |
#442 (WPCA Event Migration — EP Import & Result Import Improvements) |
ADO User Stories |
#443, #444, #455, #456, #457 |
ADO Bugs |
#417 (duplicate RaceResult), #452 (laps), #453 (repeated headers), #454 (exception swallowing), #459 (WPCA participation points) |
Design Journal |
|
Design Doc |
|
Operations Runbook |