import { BaseEntity } from "@edr/api-common"; import { Column, Entity } from "typeorm"; /** * One row per MoR system number, holding the sequence state EIMS expects across registrations: * the next `SourceSystem.InvoiceCounter` and the IRN that the next document must chain to via * `ReferenceDetails.PreviousIrn`. * * Registration locks this row `FOR UPDATE` for the duration of the submission, which is what keeps * two concurrent registrations from claiming the same counter or breaking the IRN chain. */ @Entity({ schema: "freight", name: "eims_system_state" }) export class EimsSystemState extends BaseEntity { @Column({ name: "system_number", type: "varchar", length: 32, unique: true }) systemNumber!: string; /** Counter to send on the next registration; advanced only once an attempt has consumed it. */ @Column({ name: "next_invoice_counter", type: "bigint", default: 1 }) nextInvoiceCounter!: number; /** IRN of the last successful registration; null until the first one succeeds. */ @Column({ name: "previous_irn", type: "varchar", length: 64, nullable: true }) previousIrn?: string | null; /** * Invoice holding the current reservation. Committed before the HTTP call, so it survives a * crash and blocks a blind resubmission of a document that may already have reached MoR. */ @Column({ name: "in_flight_invoice_id", type: "uuid", nullable: true }) inFlightInvoiceId?: string | null; /** Counter handed to the in-flight submission. */ @Column({ name: "in_flight_counter", type: "bigint", nullable: true }) inFlightCounter?: number | null; /** * Why registration is blocked for this system number. Set when a submission ends ambiguously: * the IRN is unknown, so no further document can chain correctly until it is resolved. */ @Column({ name: "blocked_reason", type: "text", nullable: true }) blockedReason?: string | null; }