feat(transit-agent): timed document uploads and a real-data overview

This commit is contained in:
marshal
2026-09-02 23:36:35 +00:00
parent 42ca020a1f
commit 3fd94c9314
20 changed files with 3717 additions and 1152 deletions

View File

@@ -99,7 +99,16 @@ export interface ClearanceWorkflowFile {
label: string;
uploadedBy: ClearanceWorkflowFileOwner;
category: ClearanceWorkflowFileCategory;
file: { id: string; name: string; url: string } | null;
file: {
id: string;
name: string;
url: string;
/** When this file record was stored — a replaced batch carries the new stamp. */
uploadedAt?: string | null;
updatedAt?: string | null;
size?: number | null;
mimeType?: string | null;
} | null;
}
const CATALOG_BY_CODE = new Map(
@@ -239,6 +248,39 @@ export function exportTransportFileLabel(code: string, index?: number): string {
return code;
}
// ── Transit agent arrival paperwork (export) ────────────────────────────────
// Filed by the assigned transit officer at Djibouti around train arrival. Both
// are append-only multi-file sets: each upload adds files, and a file can be
// removed on its own, unlike the DO/RO batches that replace as a whole.
/** Multi-file Djibouti gate pass uploads use `gate_pass_0`, `gate_pass_1`, … */
export const GATE_PASS_FILE_PREFIX = "gate_pass_";
export function isGatePassFileCode(code: string | null | undefined): boolean {
if (!code) return false;
return code.toLowerCase().startsWith(GATE_PASS_FILE_PREFIX);
}
export function gatePassFileLabel(index?: number): string {
return index != null ? `Gate pass ${index + 1}` : "Gate pass";
}
/** Multi-file Djibouti T1 uploads use `djibouti_t1_0`, `djibouti_t1_1`, … */
export const DJIBOUTI_T1_FILE_PREFIX = "djibouti_t1_";
export function isDjiboutiT1FileCode(code: string | null | undefined): boolean {
if (!code) return false;
return code.toLowerCase().startsWith(DJIBOUTI_T1_FILE_PREFIX);
}
export function djiboutiT1FileLabel(index?: number): string {
return index != null ? `Djibouti T1 ${index + 1}` : "Djibouti T1";
}
/** The two transit-agent arrival document sets, keyed by the API route segment. */
export const TRANSIT_ARRIVAL_DOCUMENT_KINDS = ["gate_pass", "djibouti_t1"] as const;
export type TransitArrivalDocumentKind = (typeof TRANSIT_ARRIVAL_DOCUMENT_KINDS)[number];
export function catalogEntriesForTradeDirection(
tradeDirection: string,
): ClearanceWorkflowFileCatalogEntry[] {

View File

@@ -1177,6 +1177,8 @@ export interface GlExchangeDocument {
/** The clearance view for a booking, driving both portals' clearance UI. */
export interface ClearanceView {
/** When the booking was created — the import DO clock starts here. */
bookingCreatedAt?: string | null;
status: string;
includesCustoms: boolean;
inputCode: string | null;