This commit is contained in:
Marshal
2026-07-23 11:06:10 +00:00
parent 8f143b2341
commit 13609f8d59
26 changed files with 1717 additions and 115 deletions

View File

@@ -120,6 +120,10 @@ export interface SeedContractOpts {
freight?: "CONTAINER" | "BULK";
originCode?: string;
destCode?: string;
/** GENERAL = multi-booking drawdown contract (status CONTRACT_ACTIVE). */
kind?: "ONE_TIME" | "GENERAL";
/** GENERAL only: quantity cap on the 20ft scope row (40ft stays uncapped). */
cap20?: number;
}
export function seedImportContract(opts: SeedContractOpts) {
@@ -127,6 +131,8 @@ export function seedImportContract(opts: SeedContractOpts) {
const customs = opts.customs ?? false;
const direction = opts.direction ?? "IMPORT";
const freight = opts.freight ?? "CONTAINER";
const kind = opts.kind ?? "ONE_TIME";
const status = kind === "GENERAL" ? "CONTRACT_ACTIVE" : "FULLY_EXECUTED";
// Pre-booking boundary milestone for Path B contracts differs by direction.
const boundary = direction === "EXPORT" ? "EXPORT_RELEASED" : "DO_COLLECTED";
db(
@@ -146,11 +152,11 @@ export function seedImportContract(opts: SeedContractOpts) {
ELSE 1
END
LIMIT 1),
'ONE_TIME', $2::text, $9::text,
$11::text, $2::text, $9::text,
(SELECT st.id FROM freight.service_types st ORDER BY st.created_at LIMIT 1),
$3, $4,
CASE WHEN $4 THEN 'CLEARANCE_READY_FOR_BOOKING' ELSE 'NOT_APPLICABLE' END,
'FULLY_EXECUTED', now(), now() - interval '1 day',
$12::text, now(), now() - interval '1 day',
now() + interval '60 days', 'E2E import-corridor fixture contract'
FROM freight.companies comp
WHERE comp.tin = $5
@@ -175,8 +181,10 @@ export function seedImportContract(opts: SeedContractOpts) {
RETURNING id
), scope_container AS (
INSERT INTO freight.contract_cargo_scope
(contract_id, container_size, cargo_free_text)
SELECT c.id, v.size, 'E2E import corridor cargo'
(contract_id, container_size, quantity_cap, cargo_free_text)
SELECT c.id, v.size,
CASE WHEN v.size = '20ft' THEN $13::numeric END,
'E2E import corridor cargo'
FROM c CROSS JOIN (VALUES ('20ft'), ('40ft')) AS v(size)
WHERE $9::text = 'CONTAINER'
), scope_bulk AS (
@@ -203,6 +211,9 @@ export function seedImportContract(opts: SeedContractOpts) {
opts.suffix,
freight,
boundary,
kind,
status,
opts.cap20 ?? null,
],
);
// Backfill the boundary milestone when the insert above was skipped because
@@ -414,6 +425,34 @@ export function bookBulk(opts: {
});
}
/**
* Walk a GENERAL booking through its PER-BOOKING clearance chain (Path A):
* AWAITING_DOCUMENTS → upload one doc → GL approves it → finalize →
* CLEARANCE_READY → customer proceeds with the shipment day →
* OPERATION_REQUEST_PENDING → ops accept → FULLY_EXECUTED (pool). The e2e
* seed configures no required documents, so one ad-hoc doc satisfies the
* 100%-approved gate.
*/
export function clearGeneralBooking(suffix: string, scheduledDate: string) {
withBooking(suffix, (b) => {
expect(b.status, `${suffix} starts in the clearance gate`).to.eq("AWAITING_DOCUMENTS");
glUpload(`/api/bookings/${b.id}/clearance/documents`, {}, "custom_e2e");
apiPost(superAdmin, `/api/bookings/${b.id}/clearance/review`, {
fileKey: "custom_e2e",
status: "APPROVED",
})
.its("status")
.should("be.oneOf", [200, 201]);
apiPost(superAdmin, `/api/bookings/${b.id}/clearance/finalize`)
.its("status")
.should("be.oneOf", [200, 201]);
apiPost(customer, `/api/bookings/${b.id}/clearance/proceed`, { scheduledDate })
.its("status")
.should("be.oneOf", [200, 201]);
});
acceptOperation(suffix);
}
/** Ops accepts the operation request → FULLY_EXECUTED (enters the day pool). */
export function acceptOperation(suffix: string) {
withBooking(suffix, (b) => {