Skip to content

Submission field mapping

Document Information Details
Purpose Deliverable of issue #49
Contract packages/contracts/src/submissions.ts
Schema version 1.0
Status Current

1. Purpose

This document maps every field of the direct submission contract to the relational entity that stores it, and records the fields the contract deliberately does not carry. It describes the contract as implemented, not a proposed design.

The relational model is defined by the migration 20260806150357535_delivery-event-schema and documented in the event model.

2. Envelope

Contract field Stored as Notes
fixtureId Resolved against fixture.fixture_id Must already exist. The contract does not create fixtures.
schemaVersion submission.schema_version Literal 1.0. A submission declaring any other version is rejected.
events One delivery row per element Between 1 and 1,000 elements.

The submission itself is recorded in submission, carrying the submitter, the received timestamp and the accepted status. Every delivery references it through delivery.submission_id, which is how a published statistic remains traceable to the submission that supplied it.

3. Delivery event

Contract field Column Table Notes
eventId Recorded against the submitted event submission provenance A UUID. Detects accidental retry or replay within a submission.
inningsId delivery.innings_id delivery Must already exist. The contract does not create innings.
sequenceNumber delivery.innings_sequence delivery Assigned at submission, not derived on read. Must ascend within an innings.
overNumber delivery.over_number delivery Zero-based. Part of the natural key.
positionInOver delivery.position_in_over delivery Zero-based index within the over. This is the identifying column, not the printed ball number.
ballNumber delivery.ball_number delivery Optional display only. Never unique or used to join; its over component must match overNumber.
strikerId delivery.striker_id delivery References person. Must differ from the non-striker.
nonStrikerId delivery.non_striker_id delivery References person.
bowlerId delivery.bowler_id delivery References person.
runs.offBat delivery.runs_off_bat delivery
runs.extras delivery.runs_extras delivery Must equal the sum of the extras breakdown.
runs.total delivery.runs_total delivery Must equal off-bat plus extras. Enforced by delivery_runs_ck.
runs.nonBoundary delivery.non_boundary delivery Defaults to false.

4. Extras

Extras are stored as a nullable column per type rather than as a type and a count, because more than one type can apply to a single delivery — a wide with byes, for example.

Contract field Column
extras.wides delivery.extra_wides
extras.noBalls delivery.extra_noballs
extras.byes delivery.extra_byes
extras.legByes delivery.extra_legbyes
extras.penalty delivery.extra_penalty

An absent type is stored as null rather than zero, so that a type which did not occur is distinguishable from one that occurred and awarded no runs.

5. Wickets and fielders

Contract field Column Table
wickets[].kind delivery_wicket.kind and delivery_wicket.source_kind delivery_wicket
wickets[].playerOutId delivery_wicket.player_out_id delivery_wicket
wickets[].fielders[].participantId delivery_wicket_fielder.person_id delivery_wicket_fielder
wickets[].fielders[].substitute delivery_wicket_fielder.is_substitute delivery_wicket_fielder

kind is resolved against the dismissal_kind lookup table before storage. The vocabulary is held in that table rather than enumerated in the contract because the set is open: two kinds present in the full corpus were absent from the subset the schema was designed against.

person_id on a fielder is nullable, because some records identify a substitute with no name at all. A fielder must therefore either identify a participant or be marked as a substitute; fielder_identified_ck enforces this at the database and the contract enforces it at submission.

6. Innings metadata and fields the delivery contract does not carry

The season package now carries authoritative powerplay metadata at innings scope. The remaining rows are represented in the relational model but have no delivery-submission path; they are recorded so each omission is explicit.

Field Stored in Consequence
Fixture creation fixture and its associated tables A submission adds events to a fixture created by other means. Only the ingestion script creates one.
Innings creation innings Likewise.
Super-over flag innings.is_super_over Belongs to the innings, so the contract is agnostic: the same delivery is valid whichever innings it references.
Innings penalty runs innings.penalty_pre, innings.penalty_post A team total is the sum of delivery totals plus innings-level penalty runs, so it cannot be derived from submitted deliveries alone.
fixtures[].innings[].powerplays[] innings_powerplay Reviewed markers are published with their source batch and scope accepted current deliveries in fixture statistics. Missing metadata remains absent.
Miscounted-over notes innings_miscounted_over The irregularity is not recorded, though legal balls are still counted from the delivery rows themselves.
Reviews delivery_review Not used by any Basic statistic; retained in the model for provenance.
Replacements delivery_replacement Likewise.
Correction of an existing delivery delivery.superseded_by The contract submits new events. Correcting one is not yet supported through submission.

AI Declaration

The preceding document was generated with the assistance of Claude-Web[Claude Opus 5]. The issue #633 powerplay mapping was documented with the assistance of Codex[GPT-5].