Files
edr-platform/apps/edr-freight-api/src/modules/eims/entities/eims-system-state.entity.ts
2026-08-12 14:12:23 +00:00

58 lines
2.4 KiB
TypeScript

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;
/**
* `DocumentDetails.DocumentNumber` for the next registration.
*
* Separate from our own `invoiceNumber`, which MoR cannot accept: it validates the field against
* `^(0|[1-9][0-9]{0,8})$`, a plain integer.
*/
@Column({ name: "next_document_number", type: "bigint", default: 1 })
nextDocumentNumber!: number;
@Column({ name: "in_flight_document_number", type: "bigint", nullable: true })
inFlightDocumentNumber?: number | null;
/**
* IRN of the last successful registration; null until the first one succeeds. `text`, not a
* fixed varchar — same reasoning as `Invoice.eimsIrn`: a real IRN already overflowed varchar(64).
*/
@Column({ name: "previous_irn", type: "text", 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;
}