Skip to content

XBRL filing status machine

An XBRL filing is one ACRA filing for a single client + period (e.g. ACME's period ending 31 Dec 2024). It moves through eight states. The taxonomy version is pinned at creation and is immutable.

What each state means

StateMeaningLock semantics
DRAFTFiling created. Period, entry point, entity type, taxonomy version captured. No documents yetHeader editable; no line items or mappings
DOCUMENTS_INGESTEDDOCX/PDF parsed; XbrlLineItem rows inserted with (statement, label, valueCurrent, valuePrior)Line items can be edited; mapping suggestions about to fire
MAPPING_IN_PROGRESSSuggestion engine has produced XbrlTagMapping rows (all with confirmedById = NULL)Staff confirms or overrides each mapping; new synonyms may be added to the shared library
VALIDATION_PASSEDThe 144-rule validation engine ran with no severity=ERROR failuresExport becomes available — but ONLY if every mapping is also confirmed (separate gate); reverting any confirmation drops back to MAPPING_IN_PROGRESS
VALIDATION_FAILEDAt least one severity=ERROR rule failedExport hard-blocked. Staff fixes mappings, re-runs validation
EXPORTEDBizFinx XLSX or XBRL XML produced. Artifact persisted to S3, link in the filing detail pageFiling can be marked filed, or back-routed to mapping for further edits
FILEDStaff has marked the filing as accepted by ACRA. ACRA filing reference + filed-at timestamp capturedSealed for editing; archive is the only forward path
ARCHIVEDFiling closedSealed; no further changes

The export gate

VALIDATION_PASSED is necessary but not sufficient for export. The gate (in packages/xbrl/src/export-gate.ts) checks all of:

  1. The filing has at least one line item.
  2. Validation has been run at least once.
  3. No XbrlValidationResult row has severity = ERROR AND passed = false.
  4. No XbrlTagMapping row has confirmedById IS NULL.

A failure of any check raises XbrlExportBlockedError, which the API translates to HTTP 422 with a typed reason (NO_LINE_ITEMS, NO_VALIDATION_RUN, VALIDATION_ERROR_PRESENT, UNCONFIRMED_TAG_MAPPING). There is no override path — these are the cursorrules non-negotiables.

Why VALIDATION_PASSED can return to MAPPING_IN_PROGRESS

A reviewer may notice an incorrect confirmed mapping after validation passed. Reverting that confirmation is allowed — it returns the filing to MAPPING_IN_PROGRESS and forces a re-validation before any export becomes possible again. This keeps the gate honest.

Why MARK_XBRL_FILED is restricted

EXPORTED → FILED records the regulator-facing acknowledgement (ACRA filing reference). Only XBRL_REVIEWER and PLATFORM_ADMIN hold the MARK_XBRL_FILED action — even Senior Accountants who can do everything else short of filing. The boundary deliberately matches the human accountability boundary: whoever marks the filing is the one taking responsibility with the regulator.

Where these transitions happen

TransitionTriggered by
DRAFT → DOCUMENTS_INGESTEDingest-fs-document and extract-line-items worker handlers complete
DOCUMENTS_INGESTED → MAPPING_IN_PROGRESSsuggest-tag-mappings handler
MAPPING_IN_PROGRESS → VALIDATION_PASSED / _FAILEDrun-xbrl-validation handler outcome
VALIDATION_FAILED → MAPPING_IN_PROGRESSImplicit on the next mapping change (no explicit transition needed)
VALIDATION_PASSED → EXPORTEDgenerate-bizfinx-xlsx or generate-xbrl-xml handler succeeds (gated)
EXPORTED → FILEDPOST /ops/xbrl/filings/:id/mark-filed (XBRL Reviewer / Platform Admin only)
FILED → ARCHIVEDStaff-triggered archive

Implementation

State transitions live in packages/xbrl/src/status-transitions.ts, enforced by canTransitionXbrlFiling(from, to). The valid set per current state is queryable via getNextXbrlFilingStatuses(from) for UI rendering.

Internal use only — BreezyCorp