14description:'Core registered user. Umbrella term covering wholesale Freight Forwarder, Freight Forwarder, Transporter, NVOCC (Non-Vessel Operating Common Carrier), Farmers, and Customer/Clearing agents — represented as a single user group with equal feature access (BRD V2.0 §2.1). Access is at COMPANY-ACCOUNT level (one login per company; internal access managed within each company), not individual named users. NVOCCs such as AGS use this same LSP portal to provide release authority as part of the delegation workflow (BRD V2.0 §2.1/glossary) — release authority is an LSP feature, not a separate actor. Each LSP sees only shipments allocated to them. Can delegate to another LSP or a one-off P4TC. Replaces the previous WFF/FF/Carrier actor split. Note: roles are contextual per HBL — the same organisation can appear at different levels (e.g. top-level party on one HBL, delegatee on another). Visibility and role enforcement must be HBL-scoped, not user-scoped.',
15auth:'Single company-level login (username + password). Created by ACFS admin, or via backend bulk import for initial onboarding (BRD V2.0 FR-ADM-19). Activation link expires after 72 hours.',
16responsibilities:[
17{id:'lsp:r1',description:'View list of assigned HBLs with shipment status, milestone, payment, delegation, and booking info. Data auto-synced on login and on subsequent integration layer calls.'},
18{id:'lsp:r2',description:'Select one or multiple shipments to take action on (delegate or book).'},
19{id:'lsp:r3',description:'Delegate shipments to one or more existing registered LSPs. BRD V2.0 (FR-LSP-34) reinstates MULTI-RECIPIENT selection within a single delegation flow (search and select one or more target LSPs by company name or email) — this supersedes the 2026-06-04 standup note that limited the flow to a single recipient dropdown. The "add a new one-off LSP / P4TC by email" path: V2.0 records the delegation + sends a secure-link notification, but the one-off self-service access flow remains a fast follow (BRD V2.0 §4.2/FR-LSP-05; see deferred p4tc actor). A delegation batch may mix HBLs needing only digital release with HBLs needing DO upload (BR-002). Per HBL — if delegated, LSP cannot also book directly on that same HBL for the hop they hold (BR-004). Storage-deadline warning shown if any selected HBL has LFD within 5 days or exceeded (BR-042).'},
20{id:'lsp:r4',description:'Book pickup directly across one or more TRUCKS (BRD V2.0 §4.3, FR-LSP-30): configure trucks and assign only HBLs that have already passed the per-HBL readiness gate (unpacked via CFS Tally In Head + fully customs cleared + release authority: digital release for non-lowest HBLs OR ACFS-validated/free-release DO for lowest) → load calculation + pricing (per-HBL fee + minimum charge) → select slot (inline, week-by-week; each slot card shows the number of trucks already booked on that slot/date, booked_truck_count — client decision 2026-07-09, OQ-065) → enter per-truck driver details (name, licence, truck registration entered fresh each booking) → accept booking T&Cs + per-truck driver site induction → make a SINGLE consolidated payment for the whole booking (Compay) → receive booking confirmation with reference number. Missing DOs are uploaded independently from the LSP shipment page and validated by ACFS before the HBL becomes available to book; they cannot be resolved inside the booking flow (revised 17 Jul 2026, Jaffar/Roni). Requires each HBL at milestone "unpacked" or later (BR-001). Driver reuse deferred to Phase 2 (A-025).'},
21{id:'lsp:r13',description:'Provide release authority against assigned HBLs to let downstream parties proceed to booking (BRD V2.0 §4.1, FR-LSP-25/26/27). Two forms by HBL level (FFO flag, BR-040): for NON-lowest-level HBLs apply a DIGITAL RELEASE — a single flag, no documentation, recording the release flag + acting LSP + timestamp; for LOWEST-level HBLs upload a DO for ACFS validation. Multiple HBLs can be batch-selected and released in one action (batch executes at individual shipment level irrespective of container grouping). Release authority and delegation can be performed in the same combined flow without separate sessions or roles (FR-LSP-27).'},
22{id:'lsp:r14',description:'Configure trucks for a booking (BRD V2.0 §4.3, FR-LSP-30): add one or more trucks, each with Truck Registration (rego), Driver Name, Licence Number, and a Site Induction flag; assign HBLs individually or in bulk across trucks. Trucks with unresolved issues (HBLs failing readiness, incomplete driver details) are visually flagged (e.g. coloured tag, FR-LSP-33). Can remove HBLs with unresolved errors from a truck without cancelling the booking or affecting other trucks (FR-LSP-31).'},
23{id:'lsp:r5',description:'Request missing docs when DOs are unavailable. Booking process is aborted (offline) until DO is received.'},
24{id:'lsp:r6',description:'Upload Delivery Order for downstream enforcement.'},
25{id:'lsp:r7',description:'Flag an HBL as under-bond. Manually set in portal — not synced from Maximus.'},
26{id:'lsp:r8',description:'Modify booking: change per-truck driver/truck details (each truck edited independently, FR-LSP-22) anytime until collection (no cutoff) — and a driver-only change must NOT trigger a payment request (VBPP-310, VBPP-103). Change slot date/time before change cutoff. REVISED 2026-08-20: the LSP CAN both remove AND add HBLs on an existing booking — removal initiates a refund, addition takes a BALANCE payment in-portal, and removing the last HBL auto-cancels the booking (BR-035, BR-022; US-060/061/066). The former parallel-booking workaround is withdrawn. Edit opens with the current booking prefilled and batches all changes into a single Update action (BR-030). Cost-impacting changes after cutoff require ACFS (BR-015).'},
27{id:'lsp:r9',description:'Search and view bookings using multiple search keys: booking reference number, HBL reference number, truck registration, or driver name. Booking reference becomes the primary identifier once HBLs are booked (alongside HBL reference). Both booking reference and HBL reference must be prominent (displayed side-by-side) in booked HBL table views.'},
28{id:'lsp:r10',description:'Cancel bookings within defined rules — allowed any time before the booking reaches "processed"; not after (BR-022). Upon cancellation, HBLs in that booking become available for rebooking. Financial refunds and fee adjustments are handled outside VBS by ACFS (BR-022, C-003).'},
29{id:'lsp:r11',description:'View Bookings — a booking-reference-keyed list kept separate from the Shipments list (VBS daily standup 2026-06-04: LSP needs two distinct views, "Shipments" and "Bookings", not just "My Bookings"). Each booking expands to show the multiple HBLs grouped under it. Reuses the ACFS bookings list/detail component (BR-030).'},
30{id:'lsp:r12',description:'Revoke a delegation the LSP themselves made — allowed before the HBL is booked or processed. On revoke (with confirmation), the HBL is removed from the delegatee\'s list and returns to the revoking LSP\'s assigned shipments for re-delegation. Blocked once booked or processed. Revoke lives in the LSP login only — ACFS does not revoke, it reassigns (acfs:r13). (VBS daily standup 2026-06-04.)'},
31],
32},
33{
34id:'p4tc',
35name:'Party to Collect (P4TC)',
36deferred:true,
37description:'Deferred to fast follow (BRD v1.5 excludes from Phase 1). Tertiary/one-off user with no portal credentials. Receives email with shipment roster and document portal URL. No persistent account or history. Replaces previous "One-off Customer" and "Freight Forwarder" (magic-link) actors.',
38auth:'Magic link + OTP. No login required — clicks link from email, verifies via OTP. Portal access scoped to assigned shipments only. Link expires on collection.',
39responsibilities:[
40{id:'p4tc:r1',description:'Access portal via emailed link (no login). Verify identity with OTP.'},
41{id:'p4tc:r2',description:'View list of assigned HBLs from the delegation.'},
42{id:'p4tc:r3',description:'Delegate shipments further: enter P4TC name + email ID, optionally upload new DO. System sends email with shipment roster and secure link to the new P4TC.'},
43{id:'p4tc:r4',description:'Book pickup: validate booking readiness → load calculation + pricing → select slot → enter truck and driver details (name, license#, phone — no saved drivers for P4TC) → accept T&Cs + site induction → make payment → receive booking confirmation with reference.'},
44{id:'p4tc:r5',description:'Upload missing DO or contact ACFS for support if DO is unavailable.'},
45],
46},
47{
48id:'driver',
49name:'Driver',
50description:'Secondary user. No portal access. No direct system communication — the booking party manages driver rostering externally and forwards booking details to the driver.',
51auth:'No portal auth. No system emails. Booking party forwards confirmation externally.',
52responsibilities:[
53{id:'driver:r1',description:'Receive booking reference from booking party (forwarded externally — system does NOT email the driver directly).'},
54{id:'driver:r2',description:'Present booking reference and identity at gatehouse for pickup verification.'},
55],
56},
57{
58id:'acfs',
59name:'ACFS Internal',
60description:'Internal ACFS staff. Manages HBL assignment, slot configuration, booking operations, DO validation, pickup verification, HBL hierarchy correction, and user management. REVISED 2026-08-20: the former Admin / User pair is superseded by EIGHT granular capability roles — Gatehouse (read-only, default), Validate Delivery Orders, Apply Override Release, Correct HBL Hierarchy, FAK Frontdesk, Amend Bookings, Create New LSP Accounts, Full Admin (BR-014, Confluence LCBP 2715320321). Roles are grants and combine, so one person may hold several. Two operational groups sit behind these roles: GATEHOUSE staff, who police site access and admit only trucks holding a booking (read-only booking list, searchable by truck rego), and FAK FRONT DESK staff, who take the booking reference from the arriving driver and process the collection in Maximus. Where a responsibility below says "Admin", read it as the Full Admin role unless a narrower role covers it.',
61auth:'SSO-based access. Eight granular capability roles with permissions preconfigured in the backend per role (BR-014); Gatehouse is the default level.',
62responsibilities:[
63{id:'acfs:r1',description:'HBL Assignment (remedial/optional): manually assign or reassign HBLs to LSPs via searchable dropdown (search LSP by name → assign). Same UX for reassignment — search and select a different LSP. System lists unassigned FAK shipments. Low priority for Phase 1 — data fix preferred over UI.'},
64{id:'acfs:r2',description:'ECST Assignment (DEFERRED to Phase 2): assign ECST to shipments. Flow details to be defined in Phase 2.'},
65{id:'acfs:r3',description:'Slot Configuration (one site at a time; multi-site copy deferred): select site → select days of week → configure AM / PM half-day slots (start/end times bound the half-day window) → configure booking cutoff and change cutoff (relative day + time, e.g. "previous working day, 4 PM") → optionally set busyness-band thresholds → block holidays/blackout dates via calendar overlay → save/update slots. REVISED 2026-08-20: slot configuration is an ADMIN UI capability, not backend/DB-driven — there is a SlotsUpdate write API and an admin slot screen in the build (VBPP-301, VBPP-212), superseding the former "Phase 1 slot config is backend/DB-driven (C-006/FR-ADM-02)" position. Blackout dates are written through the same API and must round-trip to the slot read (VBPP-212). The admin also needs an ALL-SITES overview before drilling into any one site — which sites are configured vs pending, slots open, blackout count and next upcoming date, last updated — because a site with no slot configuration silently cannot accept bookings and today the screen drops the admin straight into a single-site editor with no way to tell (VBPP-299, In Discussion). NOTE: each slot card in the LSP booking view now shows the actual number of trucks already booked on that slot/date (booked_truck_count) — client decision 2026-07-09 (OQ-065, FR-LSP-14 addendum), which reveals the count and supersedes the earlier "heatmap without revealing counts" model; heat_map_threshold is retained only to optionally colour that number by band. Phase 1 slot config is backend/DB-driven (C-006/FR-ADM-02).'},
66{id:'acfs:r4',description:'Manage Booking: search bookings by booking ref# or by truck/driver details → view details (slot date/time, booking party, HBLs, fees paid, driver/truck) → edit opens with the current booking prefilled and batches all changes into a single Update action (one call), with Update enabled only when something changed, alongside Cancel (BR-030) → change pickup slot, change driver/truck, add/remove HBLs. All edits available on non-cancelled/non-collected bookings. Admin can override cutoffs. When HBLs are added/removed, fee total recalculates but no additional payment is collected in-portal (fee-free modifications for Phase 1, BR-036); any refund for removed HBLs is handled offline. No truck capacity validation — that is the carrier\'s responsibility. Booking update notification sent via email to booking party.'},
67{id:'acfs:r5',description:'DO Validation (pre-booking and separate from pickup verification): view the HBL-centric queue of uploaded/unvalidated DOs, prioritised by upload date → validate each DO against the lowest-level HBL details → mark validated, or flag with an optional reason (wrong DO, wrong content, unreadable upload, etc.). A validated DO makes the HBL eligible for booking once its other readiness checks pass; a flagged DO requires re-upload. Because validation now happens before booking, the queue does not depend on a booking reference or slot. Can be handled by the offshore team (revised 17 Jul 2026, Jaffar/Roni).'},
68{id:'acfs:r6',description:'Pickup Verification: triggered when the driver arrives (search bookings by ref# or by driver name/license/truck rego to find what that driver is collecting) → view details + DO validation status + customs clearance + audit tracking → validate or reject. If validated, mark the booking "processed" (manual CTA — BRD V2.0 §4.7 name; the 2026-06-04 standup had briefly renamed this "ready to collect", reverted in v0.14.0). If not validated, booking is flagged. Includes DO validation if not already done. After "processed" the only next state is "complete" (via Maximus/Tally Out sync once physically picked up).'},
69{id:'acfs:r7',description:'Accounts & Users management: manage two distinct groups — Accounts (LSP company accounts: company name, email, branch; company ID is internal/auto — email is the login, no per-user role) and Users (ACFS staff: username + role). ACFS users get a role dropdown (Admin / User) whose feature permissions are preconfigured in the backend per role — there is NO per-feature permission UI (VBS daily standup 2026-06-04). Create, update, and deactivate within each group. BRD v1.6 already separates the LSP entity from the User entity, consistent with this split.'},
70{id:'acfs:r8',description:'Override missing DO requirement. Restricted to Admin role. Audit trail with reason required. One-time per HBL, lives until collected.'},
71{id:'acfs:r9',description:'FOC rebooking for no-shows: admin edits the pickup slot (and optionally driver/truck) on the existing booking — no new booking created. Fee-free. No separate FOC rebook action — uses the same inline edit capability as acfs:r4.'},
72{id:'acfs:r10',description:'Flag an HBL as under-bond.'},
73{id:'acfs:r11',description:'Partially process bookings — clear HBLs proceed (move to "processed") while blocked ones are rebooked separately.'},
74{id:'acfs:r12',description:'Manage shipments (ACFS shipments module): manually assign/reassign unassigned shipments to LSPs (auto-assignment is primary; manual is the fail-safe), and mark HBLs as under-bond. ACFS CANNOT edit the milestone — milestone is Maximus-only/read-only (VBS daily standup 2026-06-04: "edit milestone... not something we can control, get rid of that"). Whether ACFS can mark free-release from this view is open (OQ-044).'},
75{id:'acfs:r13',description:'Reassign the assigned LSP (the last hop) when a shipment owner asks ACFS to correct/redirect an assignment. ACFS does NOT revoke delegations — revoke lives in the LSP login (lsp:r12); ACFS reassigns instead. If the HBL is already booked, reassignment is blocked with an error (the booker must cancel first). assigned_lsp always reflects the last hop. (VBS daily standup 2026-06-04 — supersedes the former "reassign or revoke" wording.)'},
76{id:'acfs:r14',description:'Trigger a manual real-time refresh of Maximus data on key views (BR-010, FR-ADM-16). BRD V2.0 moves the portal to a real-time MuleSoft model: relevant views (HBL list, booking flow, pickup verification) fetch the latest HBL / milestone / customs / tally data on each page load, and a manual refresh is available on demand. Fetch is non-blocking — loading states show while data is retrieved. (Manual refresh remains ACFS-only for Phase 1; LSP self-service refresh is not in scope.)'},
77{id:'acfs:r15',description:'Bulk-onboard LSP accounts via a backend import process for initial onboarding (BRD V2.0 §4.9, FR-ADM-19). Source data may come from Maximus, ICS-derived data, AGS exports, or business-provided datasets; bulk onboarding does not require individual account creation via the UI. Ongoing single-account creation still uses the Accounts UI (acfs:r7).'},
78],
79},
80],
81entities:[
82{
83id:'hbl',
84name:'House Bill of Lading (HBL)',
85description:'Primary tracking unit for a shipment. Sourced from Maximus in REAL TIME via MuleSoft APIs — fetched on each page load of relevant views and on manual refresh (BRD V2.0 §6.2/§7, FR-ADM-16; supersedes the former once/twice-daily batch sync — OQ-006). HBL hierarchy level is determined by the FFO flag from the EDI Requested Cargo table (BR-040): records WITHOUT an FFO flag are lowest-level HBLs (require a DO); records WITH an FFO flag are intermediate/upper-level (require only a digital release, BR-041). Two orthogonal dimensions: milestone (physical progress) and HBL status (delegation/booking state). BRD v1.5 flattens these into a single lifecycle (Unassigned → Assigned → Delegated → Booked → Collected) — the mapping is: BRD lifecycle = hbl_status + the "collected" milestone. Both dimensions are needed for implementation since an HBL can be e.g. in_yard + delegated simultaneously. HBLs exist in a hierarchy: AGS issues master HBLs (often 500-prefix), freight forwarders issue lower-level HBLs (e.g. 4033-prefix for Mondial). Mostly 1:1 parent-child relationship. The portal primarily deals with the lowest-level HBL as the primary identifier. An HBL may cover multiple cargo items (forwarders may consolidate multiple shipments into a single HBL per BRD v1.6 Addendum 1); when a forwarder splits cargo across different transport partners it generates child HBL references for the subsets, and items logically inherit the parent HBL reference (no physical re-tagging on the cargo). Full audit trail lives on HBL — shows all hops, delegation chain, assignment changes, and status transitions. Note: "booked" is derived from related_bookings and is NOT surfaced as a shipment-level status in the ACFS shipments/assignment view (VBS daily standup 2026-06-04) — though it remains an hbl_status value for the data model and the ACFS bookings view.',
86key_fields:[
87{name:'hbl_number',type:'string',description:'Primary identifier — lowest-level house bill number from Maximus.'},
88{name:'alt_hbl_reference',type:'string',description:'Alternative/parent HBL reference (e.g. AGS master HBL). Optional — present when hierarchy exists. Relationship established via AGS data feed, not Maximus.',warn:'Exact data source for HBL hierarchy relationship TBD — Matt and William resolving (OQ-034). The 2026-05-21 meeting clarified a deeper issue: there is no current system-wide reference mapping at all — see party_references field below.'},
89{name:'party_references',type:'{ party_id: string, reference: string }[]',description:'Per-party HBL references. The same shipment is known by a different reference at each tier of the delegation chain (WFF sees one ref, downstream FF sees another) — BRD v1.6 Addendum 1 confirms "parties will need to see their own reference in the portal". The per-party references DO exist in Maximus/ICS (Integrated Cargo System — the Australian customs feed), but there is no cross-hop mapping between them; the first hop and the last hop are reliably available, the intermediate hops are the gap (VBS daily standup 2026-06-04; Matt: "the $1,000,000 question" — VBS Screen Review 2026-05-21). The portal must display the correct reference per viewing party. Captured during delegation or via data discovery; ACFS reconciliation UI (BR-034) helps build/verify the mapping. 24 Jun: the backend transposes EdiRequestedCargo and builds the parent↔lowest link by weight+volume matching of FFO vs blank rows (probabilistic — manual exception queue for consolidations); the first and last hop are reliable, the intermediate hops are the derived gap.',warn:'Design open — capture mechanism (delegation-time entry vs feed) and storage shape pending discovery session. Blocks accurate per-party views in delegation chain.'},
90{name:'container_number',type:'string',description:'Container reference — ties HBL to the top-level container. Visible and sortable in the HBL list, which supports grouping / accordion drill-down by container (VBS daily standup 2026-06-04). AGS (wholesale FF) works at container level and would delegate a whole container at once, but container-level bulk delegation is AGS-specific and deferred for Phase 1 — see OQ-043; day one is container reference + sort/group only.'},
91{name:'ocean_bl',type:'string',description:'Ocean bill of lading. Multiple containers may share one ocean BL.'},
92{name:'vessel_id',type:'string',description:'Maximus VesselID. With voyage_no, disambiguates container_number — reused across voyages (the EDI→order join is ContainerNo + VesselID + VoyageNo).'},
93{name:'voyage_no',type:'string',description:'Maximus VoyageNo. Pairs with vessel_id to disambiguate a reused container_number.'},
94{name:'consignee',type:'string',description:'Next party in the chain (the logistics provider who can see this HBL), identified by account name or code. NOT the raw EDI ConsigneeName — on a lowest-level row that name is the END IMPORTER, who never logs in (24 Jun). The clean party identity is resolved in the backend: free-text ICS ConsigneeName → an account code via ACFS alias mappings (matching rule still TBD — OQ-034); the AGS feed is a more consistent source than raw ICS.'},
95{name:'weight_kg',type:'number',description:'Gross weight measurement for fee calculation (EdiRequestedCargo.GrossWeight).'},
96{name:'net_weight_kg',type:'number',description:'Net weight (EdiRequestedCargo.NetWeight). weight_kg is gross; net is one of the four fields the 1 Jul hierarchy-matching algorithm matches on (Gross + Net + Volume + Qty).'},
97{name:'volume_m3',type:'number',description:'Volumetric measurement for fee calculation.'},
98{name:'chargeable_weight',type:'number',description:'Derived: the greater of weight vs volume per HBL — max(weight_kg, volume_m3). Matt 7 Jul 2026: 1 CBM = 1 metric tonne (1000 kg), which is the equivalence that makes weight (kg) and volume (m³) directly comparable. Used for fee calculation: chargeable_weight × rate, with a configured minimum fee. Computed by backend, not stored independently.'},
99{name:'quantity',type:'number',description:'Number of packages (e.g. 3 boxes). Optional — may not be required for decision-making.'},
100{name:'pack_type',type:'string',description:'Package type description. Optional — may not be required for decision-making.'},
101{name:'un_code',type:'string',description:'UN dangerous-goods code (IntOrderItem.UNCode). OUT OF INITIAL RELEASE (1 Jul) — provisioned for the fast follow.'},
102{name:'dangerous_goods',type:'boolean',description:'Derived DG flag (IntContainer.CargoType + IntOrderItem.IMOCode/UNCode). OUT OF INITIAL RELEASE (1 Jul).'},
103{name:'pallet_quantity',type:'number',description:'CHEP/pallet count (IntOrderItem.Quantity2). OUT OF INITIAL RELEASE (1 Jul).'},
104{name:'pallet_type',type:'string',description:'Pallet UOM/type (IntOrderItem.UOM2). OUT OF INITIAL RELEASE (1 Jul).'},
105{name:'description',type:'string',description:'Goods description. Two source fields exist in Maximus: "description" and "marks and numbers" — may consolidate.'},
106{name:'milestone',type:"'on_vessel' | 'at_wharf' | 'in_yard' | 'unpacked' | 'collected'",description:'Physical progress milestone. Linear progression. Sourced from Maximus in real time via MuleSoft. Authoritative tables (BRD V2.0 §3/§7.4): "unpacked" is confirmed by the presence of an APPROVED CFS Tally In Head record (IsApproved = 1); "collected" by the presence of an APPROVED Tally Out record (IsApproved = 1) — Matt 2 Jul 2026 amendment: the tally record must be approved, not merely present. Earlier milestones (on_vessel/at_wharf/in_yard) are DERIVED, not stored in Maximus. 1 Jul 2026 RESOLVED (supersedes the earlier "Connect portal / Confluence rules, all but one" plan): there is NO single Maximus location field — derive location from EDICommon event/movement codes keyed by the container key (William\'s ACFS_Container_Location_CMT__mdt mapping; e.g. HL001 = arrived at wharf, DISCHARGED/GATE_IN = wharf, yard/MT-park codes, UNPACK_COMPLETE = unpacked). on_vessel (= "On Water") uses the AdmVesselSchedule ACTUAL arrival date (NOT the estimated PodEta) and is the DEFAULT status unless a later movement is known ("we don\'t fly those containers in"). Only these four container-level milestones are tracked pre-collection. Until unpack the container milestone IS the HBL milestone; after the Tally In record, HBL status is computed independently.'},
107{name:'hbl_status',type:"'unassigned' | 'assigned' | 'delegated' | 'booked'",description:'Delegation/booking status — a separate dimension from milestone. This is the CANONICAL (global) state of the HBL, NOT a per-viewer state: "unassigned" (no LSP yet), "assigned" (allocated to an LSP — the current last hop, assigned_lsp), "delegated" (the last hop passed it further down, so assigned_lsp has already moved to that downstream party), "booked" (a pickup is scheduled). Because assigned_lsp always tracks the LAST hop, the active party can ALWAYS act on an HBL their assigned_lsp points to: delegate/book gating is evaluated relative to the viewing party via assigned_lsp, never by reading the global "delegated" value (see BR-004, BR-038). Transitions for this dimension live in BR-038 — the entity lifecycle below models milestones only.'},
108{name:'customs_clearance_status',type:"'pending' | 'held' | 'partial_clearance' | 'fully_cleared'",description:'Customs clearance state. CONFIRMED 3 Aug 2026 (Confluence LCBP 2760474628, "HBL Staging to Master Business Rules") — supersedes the earlier provisional enum. Values are DERIVED from cargo-hold rows, not stored at source: "pending" = no cargo-hold records exist at all (no final clearance available); "held" = one or more active cargo holds (BOND, AQIS, Customs or ACFS hold); "partial_clearance" = some holds released, others still active; "fully_cleared" = all applicable holds released. Recalculated on EVERY sync from the latest Maximus release-date information — a status is never carried forward. Must be "fully_cleared" to satisfy the booking gate; verified under-bond is the documented exception (BR-001, OQ-045). Shown in HBL table. NOTE "pending" means "we have no hold data yet", NOT "cleared but unconfirmed" — an HBL with no holds is not bookable.'},
109{name:'under_bond',type:'boolean',description:'Flag — NOT a lifecycle state. Goods moving between bonded facilities before customs clearance (Australian Border Force customs bond). Manually set by LSP/ACFS in portal. Movement permission replaces DO requirement. Not synced from Maximus.'},
110{name:'under_bond_verified',type:'boolean',description:'Whether ACFS has verified the under-bond marking. Verification happens outside the portal; portal records the result. Set by ACFS staff only.'},
111{name:'last_free_storage_date',type:'date',description:'LFD (Last Free Day) — last date of free storage. After this date, storage fees apply (computed on read, not stored as a separate flag). Sourced from Maximus storage/LFD data, or set by ACFS. Drives the storage-deadline warning (BR-042, FR-LSP-35): the HBL list shows the LFD with a prominent warning indicator when it is within 5 days or has crossed, the list is sortable by LFD to prioritise, and delegation shows a warning before confirm if any selected HBL is at/over LFD.'},
112{name:'ffo_flag',type:'boolean',description:'New (BRD V2.0 §3, FR-ADM-17). FFO flag from the EDI Requested Cargo table — the authoritative classifier of HBL hierarchy level. ABSENT (false) ⇒ lowest-level HBL (requires a DO for release). PRESENT (true) ⇒ intermediate/upper-level HBL (requires only a digital release). Drives hbl_level_indicator and the release-authority branch (BR-040).'},
113{name:'hbl_level_indicator',type:"'lowest_level' | 'intermediate'",description:'New (BRD V2.0 §6.1). Derived from ffo_flag: "lowest_level" when the FFO flag is absent, "intermediate" when present. THE SINGLE SWITCH for the release model: when "lowest_level", release authority is the DO path (release_type / dos_fully_validated / do_waived apply); when "intermediate", release authority is the DIGITAL RELEASE path (a release_authority record with release_mechanism "digital_release") and the DO-path fields (release_type/do_waived) do NOT apply. This replaces the older implicit "lowest-level HBL is primary" hierarchy reasoning as the authoritative level signal (BR-040). Shown in the HBL list (FR-LSP-02).'},
114{name:'release_status',type:"'digital_release_provided' | 'do_validated' | 'pending'",description:'New (BRD V2.0 §6.1, FR-LSP-02). Phase 1 HBL-level summary of whether release authority is VALIDATED/granted. Intended semantics by level (hbl_level_indicator): INTERMEDIATE HBL → "digital_release_provided" when the digital release has been provided, else "pending". LOWEST-level HBL → "do_validated" when dos_fully_validated is true OR do_waived is true (verified free-release / under-bond), else "pending". The model collapses the waived case into "do_validated" to honour BRD V2.0\'s three-value enum; "do_validated" therefore means "lowest-level release authority granted", whether by a validated DO or a verified waiver. Since the 17 Jul 2026 rule revision, this summary and the booking gate AGREE for lowest-level HBLs: merely uploading a DO leaves release_status "pending" and the HBL unavailable to book; ACFS validation (or a verified waiver) is required first. Whether Phase 1 stores/writes this field directly through the HBL update API or derives it from DO/digital-release state is unresolved (OQ-071). The multi-party/per-tier breakdown and multiple-DO aggregation are deferred beyond the initial release; Phase 1 shows this single HBL summary only (OQ-068 resolution).'},
115{name:'release_type',type:"'do_required' | 'free_release'",description:'DO-path field — applies ONLY to lowest-level HBLs (hbl_level_indicator === "lowest_level"); has no meaning for intermediate HBLs, which use the digital-release path instead. Determines the DO requirement for that lowest-level tier: "do_required" (default — DO must be uploaded and validated) or "free_release" (no DO needed for that tier). free_release can only be set by ACFS staff (BR-002) — LSPs cannot self-mark; they request via offline channels and ACFS records it. Distinct from release_authority.release_mechanism (which records the form of an authority ACT, not the DO requirement).'},
116{name:'free_release_verified',type:'boolean',description:'Whether ACFS has verified the free_release marking. Mirrors under_bond_verified — LSPs cannot self-set release_type; ACFS sets it after offline verification. Set by ACFS staff only.',warn:'Terminology TBD — Matt noted free_release covers multiple scenarios (special-release, off-norm cases) and the name may change post-clarification (2026-05-21).'},
117{name:'do_waived',type:'boolean',description:'DO-path field (lowest-level HBLs only). Derived: true when release_type is "free_release" AND free_release_verified is true, OR when under_bond is true AND under_bond_verified is true. Booking readiness and release_status check this single field instead of inspecting release_type/under_bond separately. For intermediate HBLs this is not evaluated (digital-release path applies).'},
118{name:'assigned_lsp',type:'string',description:'LSP this HBL is currently allocated to — always the LAST hop in the chain (VBS daily standup 2026-06-04). Set by ACFS during HBL/WFF assignment, auto-assigned from data, updated on each delegation, and reverts to the delegator on revoke (lsp:r12). ACFS reassign (acfs:r13) changes this directly; blocked once booked.'},
119{name:'pickup_site',type:'string',description:'Physical site/warehouse where this HBL will be picked up (references site entity). Critical for LSP dispatch planning - determines which warehouse to send truck to. Sourced from Maximus or derived from container unpacking location. Must be visible in HBL list (FR-LSP-02) and filterable/searchable.'},
120{name:'import_ref',type:'string',description:'Import reference from Maximus. Optional field for data matching and integration.'},
121{name:'container_key',type:'string',description:'Maximus container key (OrderNo-NNN). The join key for milestones (EDICommon events) and container holds (IntContainerHold). Identifies the CONTAINER, not the HBL.'},
122{name:'cargo_key',type:'string',description:'Maximus CargoKey — the per-HBL spine (unique per HBL, via IntOrderItem/CfsCargo). THE key for the collected milestone (tally-out) and cargo-hold joins; never identify an HBL by container_key.'},
123{name:'collected_by_code',type:'string',description:'Collecting carrier code (cfsTallyOutHed.ContractorCode), populated at the collected milestone (Tally Out).'},
124{name:'parent_hbl_id',type:'string',description:'Resolved parent (upper-level) HBL. Written by the ingestion hierarchy-matching pass, not sourced directly (BR-034). Present in the production ERD as HBLS.ParentHBLId. NB the production schema holds ONE parent per child, so a rejected or competing candidate match has nowhere to live — the architect guide (LCBP 2685468677) recommended a separate hbl_relationships mapping entity for exactly that reason and the build did not adopt it (OQ-081).'},
125{name:'parent_company_id',type:'string',description:'Production ERD HBLS.ParentCompanyId (Companies FK). SEMANTICS UNCONFIRMED — this field appears NOWHERE in the architect implementation guide (LCBP 2685468677 v32); the build added it without documenting it. "Company that issued the parent HBL" is the obvious reading but it is an inference, and the alternative reading (resolved consignee of the parent row) implies something quite different for visibility. Confirm with Jewel before building anything on it — a per-party reference view is the obvious use and would be wrong if the semantics are the other one (OQ-073).'},
126{name:'relationship_type',type:'string',description:'Outcome of hierarchy matching for this HBL (production ERD HBLS.RelationshipTypeId → HBLRelationshipType). Includes the standalone case "NO_PARENT" — a lowest-level HBL with no valid parent remains VALID, it is not an error (BR-034).'},
127{name:'match_level',type:'string',description:'Confidence band assigned by the hierarchy-matching pass (production ERD HBLS.MatchLevelId → HBLMatchLevel). Bands are 100% / 95% / 90% / 50% / not-scored, per the rule table in BR-034. The bottom two bands force needs_manual_review.'},
128{name:'needs_manual_review',type:'boolean',description:'Set by ingestion when hierarchy matching or party mapping did not produce a reliable result — weak match (50%), no match, consignee mapping failure, or L1 service-provider mapping failure (BR-034). The record is RETAINED, not rejected, and routed to the VBS Admin review queue. This is the data end of the "Correct HBL Hierarchy" ACFS role (Confluence LCBP 2715320321).'},
129{name:'is_manually_updated',type:'boolean',description:'Whether an ACFS admin has hand-corrected this HBL after a manual review. Production ERD HBLS.IsManuallyUpdated. Matters for sync: a later ingestion pass must not silently overwrite a human correction (relates to OQ-060).'},
130{name:'exception_id',type:'string',description:'Link to the recorded ingestion exception for this HBL (production ERD HBLS.ExceptionId → ExceptionType). Exception kinds seen in the integration design include SiteMappingFailed, AccountMappingFailed, MissingCoreKey and DatasetMissing.'},
131{name:'original_msg_ref',type:'string',description:'EDI message reference (EdiRequestedCargo.OriginalMsgRef). Used for de-duplication: where a container has multiple cargo records, the HIGHEST OriginalMsgRef wins, and that selection happens in MuleSoft before the data reaches the portal (LCBP 2760474628).'},
132{name:'cargo_hold_status',type:'string',description:'Cargo-level hold status carried on the HBL (production ERD HBLS.CargoHoldStatus → AQISHoldStatus). The per-hold history rows (hold code, description, hold date, release date, active flag) sit in the integration layer; this field is the current summary the portal reads. customs_clearance_status is derived from these.'},
133{name:'maximus_updated_at',type:'date',description:'Source-side last-updated timestamp from Maximus, for sync/CDC change detection (OQ-063/064/065). Distinct from the portal record timestamps; the exact Maximus audit column is still TBD.'},
134{name:'related_bookings',type:'Booking[]',description:'Bookings this HBL has been included in. Many-to-many relationship via booking_hbls junction table supports rebooking scenarios with full fee history and per-HBL charge tracking (BR-019). Once HBL is booked, both HBL reference and booking reference become equally important for search/display (lsp:r9). BRD v1.5 Section 6.1 lists this as "Related Booking ID(s)" but implementation uses proper junction table pattern.'},
135{name:'dos_fully_validated',type:'boolean',description:'Derived rollup flag — true when every DO in this HBL\'s REQUIRED SET is validated by ACFS: its own DO PLUS all inherited ancestor-tier DOs (BR-002), minus any tier whose own HBL has do_waived = true. NB each "tier" is a distinct ancestor HBL row carrying its own release_type/do_waived — the per-tier waiver is evaluated against THAT ancestor HBL\'s do_waived, not a single shared flag — so partial waivers (tier 2 waived, tier 3 not) are representable. This is NOT just the DOs directly attached to this HBL — it spans the ancestor chain. Computed from related DO records across the hierarchy, not stored independently. Used by ACFS pickup verification to indicate the HBL is ready to proceed (BRD v1.5 §4.5 step 4, §6.1, FR-ADM-05).',warn:'Correctness depends on a resolved parent chain — alt_hbl_reference holds a single parent only, so 3+ tier chains need the full ancestor walk from the AGS hierarchy feed (OQ-034).'},
140{from:'on_vessel',to:'at_wharf',trigger:'Vessel arrives at port',guard:'Maximus milestone via real-time MuleSoft fetch'},
141{from:'at_wharf',to:'in_yard',trigger:'Container moved to yard'},
142{from:'in_yard',to:'unpacked',trigger:'Container unpacked at warehouse'},
143{from:'unpacked',to:'collected',trigger:'Goods physically picked up from warehouse',guard:'Booking in "processed" state + collected milestone synced from Maximus (Tally Out)'},
144],
145warn:'Milestones only — delegation and booking are tracked via hbl_status, a separate dimension whose state machine is documented in BR-038. Delegation can happen at any milestone (BR-001). Booking requires milestone "unpacked" or later (BR-001).',
146},
147},
148{
149id:'booking',
150name:'Booking',
151description:'Groups one or more HBLs into a pickup window, distributed across one or more TRUCKS (BRD V2.0 §4.3, FR-LSP-30). Created by LSP or P4TC. Each truck carries its own driver details and its own assigned HBL list (see truck entity); a single consolidated payment covers the whole booking regardless of truck count (FR-LSP-36). No truck type distinction for Phase 1 — booking party is responsible for bringing the correct truck. Slim audit trail at booking level (created, payment confirmed). Full hop history lives on the HBL entity instead. "Complete" status is derived — booking becomes complete when all its HBLs reach the "collected" milestone (Tally Out; no manual status change). Booking statuses are Open / Processed / Complete / Cancelled (BRD V2.0 §6.1; see lifecycle warn for the mapping from the older standup names). NOTE: BRD V2.0 restructures the former single-driver/single-truck booking into a booking → many-trucks shape; the driver_name/driver_license/truck_rego fields moved off Booking onto the truck entity.',
154{name:'pickup_window',type:'PickupWindow',description:'Selected date/time slot. One slot applies to the entire booking (all trucks share the same slot, BRD V2.0 §8.1). NOT ENFORCED BY THE PRODUCTION SCHEMA (2026-08-20): the booking ERD holds slot_id and slot_date on BookingHBLS, i.e. per booked HBL, not on Bookings. The single-slot rule therefore has to be enforced in application logic, and the schema permits a booking whose HBLs sit on different slots. See OQ-083.'},
155{name:'hbl_ids',type:'string[]',description:'HBLs included in this booking. Can span multiple LSPs. Each HBL is assigned to exactly one truck within the booking via the booking_hbl_link junction (truck_id).'},
156{name:'truck_count',type:'number',description:'New (BRD V2.0 §6.1). Number of trucks assigned to this booking. Driver/truck details live on the truck entity, one row per truck.'},
157{name:'fee_amount',type:'number',description:'Single consolidated total across all trucks (FR-LSP-36): sum of (chargeable_weight × rate) per HBL + minimum charge. Backend-calculated and returned per HBL from the API. Rate and minimum charge are backend-configurable. Frontend displays calculated values only — no fee logic in frontend.'},
158{name:'booking_party',type:'string',description:'LSP or P4TC who created the booking.'},
159{name:'tc_accepted',type:'boolean',description:'Whether the booking party accepted the booking terms and conditions (accepted once per booking). Driver site induction is acknowledged PER TRUCK on the truck entity.'},
160{name:'minimum_charge_applied',type:'boolean',description:'Whether the configured minimum charge was applied to this booking (BRD V2.0 §6.1). True when the sum of per-HBL chargeable amounts fell below the configured minimum and the minimum was used instead. Computed by backend at booking time. Minimum charge is never surfaced to booking parties (BR-037).'},
164warn:'Status names adopted from BRD V2.0 §6.1/§4.7: Open / Processed / Complete / Cancelled (adopted v0.14.0, reversing the 2026-06-04 standup\'s Pending / Ready-to-Collect / Collected naming per the V2.0-wins conflict rule). Mapping for anyone reading older notes: "open" = booked & awaiting processing (former "pending"/"booked"/"pending_processing"); "processed" = ACFS pickup-verified via the manual CTA (former "ready_to_collect"); "complete" = derived, set automatically when all HBLs reach the "collected" milestone (Tally Out) — no manual change (former "collected"). "draft" is a transient pre-confirmation state (booking being assembled / payment pending) — not enumerated in V2.0\'s table but a real implementation state. The ACFS bookings view also shows a "Total" tab, which is a view-all, not a status.',
165transitions:[
166{from:'draft',to:'open',trigger:'LSP or P4TC confirms, accepts T&Cs + site induction, and pays',guard:'All HBLs at milestone "unpacked" or later + (fully customs cleared OR verified under-bond, BR-001/OQ-045) + all required DOs ACFS-validated or waived (do_waived) + T&Cs accepted + payment completed. Payment failure leaves the booking in draft (no transition to open) — see payment entity lifecycle.'},
167{from:'open',to:'processed',trigger:'Driver arrives; ACFS verifies DOs validated + customs cleared and clicks the "Processed" CTA. Partial processing allowed — clear HBLs proceed, blocked ones rebook separately.'},
168{from:'processed',to:'complete',trigger:'Goods physically picked up; "collected" milestone synced from Maximus (Tally Out, after ACFS generates the pick list externally). No intermediate forklift/transit states.'},
169{from:'open',to:'cancelled',trigger:'LSP or ACFS cancels booking — allowed only before "processed". Cancellation reason required (ACFS). Refund processed outside system.'},
170],
171},
172},
173{
174id:'truck',
175name:'Truck',
176description:'New entity (BRD V2.0 §6.1, FR-LSP-30). A vehicle assigned to collect one or more HBLs within a single booking. A booking may contain multiple trucks, each with its own driver details and its own assigned HBL list. Driver details are entered fresh per truck per booking for Phase 1 (saved drivers deferred — A-025). Trucks with unresolved readiness errors or incomplete driver details are visually flagged in the booking UI (FR-LSP-33).',
179{name:'booking_id',type:'string',description:'Parent booking this truck belongs to. NOT PRESENT IN PRODUCTION (2026-08-20): the booking ERD gives Truck no booking FK at all, so a truck row is reachable only through booking_hbls.truck_id. That is the shape reusable trucks/drivers would need, which this model defers to Phase 2 (A-025). Consequence either way: nothing in the schema stops 2 bookings sharing a truck row, so "driver details entered fresh per truck per booking" is not enforceable at the data layer. See OQ-084.'},
183{name:'site_induction_flag',type:'boolean',description:'Whether the driver has completed site induction (Yes/No). When No, the driver site induction T&C acknowledgement is required at booking; when Yes it may be skipped subject to ACFS confirmation (FR-LSP-17). Per-truck, not per-booking.'},
184{name:'tc_acceptance_timestamp',type:'date',description:'Timestamp the driver site induction T&C was accepted for this truck.'},
185],
186lifecycle:{
187states:['active'],
188transitions:[],
189warn:'Truck rows are created/edited within the booking flow (or via ACFS/LSP booking edit) — no independent state machine. Removed when its booking is cancelled.',
190},
191},
192{
193id:'slot',
194name:'Pickup Slot',
195description:'A configurable pickup window at a specific site. Configured by ACFS admin. No truck type distinction for Phase 1. Granularity is AM / PM half-day for Phase 1 (start/end times bound the half-day window). The slot selector is presented INLINE within the booking interface (not a pop-up) and supports week-by-week navigation (BRD V2.0 FR-LSP-14). Each slot card shows the NUMBER OF TRUCKS already booked on that slot for the selected date — the client decided on 2026-07-09 to reveal the actual truck count, reversing the earlier "heatmap without revealing counts" model (see OQ-065; FR-LSP-14 addendum). This count is booked_truck_count (a derived, per-date aggregate, NOT a stored field on the slot template) — see below. The heat_map_threshold is retained to optionally colour the count by busyness band, but the raw number is now the primary display. Booking is never blocked by the count — it is informational only (no hard capacity limits, BR-005). Note: AM/PM half-day granularity is retained as the working assumption.',
198{name:'site',type:'string',description:'Physical site/location for pickup (references site entity).'},
199{name:'days_of_week',type:'string[]',description:'Days this slot template applies to (e.g. Monday-Friday).'},
200{name:'start_time',type:'time',description:'Slot window start. For Phase 1 these bound the AM or PM half-day window rather than an arbitrary hourly slot (VBS daily standup 2026-06-04).'},
201{name:'end_time',type:'time',description:'Slot window end (AM/PM half-day bound for Phase 1).'},
202{name:'booking_cutoff',type:'{ relative_day: string, time: string }',description:'Booking cutoff — relative day (e.g. "previous_working_day", "same_day") + time (e.g. "16:00"). Bookings not accepted after this point.'},
203{name:'change_cutoff',type:'{ relative_day: string, time: string }',description:'Change cutoff — same format as booking cutoff. Changes to slot/date/HBLs not allowed after this point (truck/driver changes exempt).'},
204{name:'heat_map_threshold',type:'number',description:'Optional busyness-band threshold(s) per slot. Since 2026-07-09 (OQ-065) the slot card reveals the actual booked_truck_count, so this threshold no longer drives a count-hiding heatmap — it is retained only to optionally COLOUR the visible number by busyness band (e.g. green/amber once the count crosses the threshold). Never blocks booking; may be null/unused if the client wants the plain number only.'},
205{name:'booked_truck_count',type:'number',description:'DERIVED, per (slot, date) — NOT stored on the slot template. Number of trucks already booked on this slot for a given calendar date: SUM(bookings.truck_count) over bookings WHERE slot_id = this slot AND slot_date = the selected date AND status NOT IN (\'draft\',\'cancelled\'). This is the "number of other trucks using the same slot" surfaced on each slot card (client decision 2026-07-09, FR-LSP-14 addendum, OQ-065). Computed by the backend on read and returned by GET /api/slots/available; an optional exclude_booking_id argument drops the caller\'s own in-progress booking so the card can read as OTHER trucks. Note the count is over TRUCKS (sum of truck_count), not bookings — a multi-truck booking contributes all its trucks (BR-039).'},
206{name:'is_blocked',type:'boolean',description:'Whether slot is blocked due to holiday/blackout date.'},
213{from:'active',to:'past',trigger:'Slot end time passes'},
214],
215},
216},
217{
218id:'site',
219name:'Site',
220description:'Physical warehouse/pickup location. Seeded directly in the database — no admin CRUD UI for Phase 1. The pickup site for an HBL is resolved from its branch code (BRD V2.0 FR-INT-06, BR-043): branch code is the mapping key, with one FAK location per branch/state for the initial mapping (to be validated with ACFS Operations before go-live — OQ-047).',
221key_fields:[
222{name:'site_name',type:'string',description:'Human-readable site name (e.g. "Port Botany Warehouse").'},
223{name:'branch_code',type:'string',description:'Branch code (e.g. "SY", "MB", "BR"). The mapping key from branch → physical site (FR-INT-06). Multiple sites can share a branch code; initial mapping is one FAK location per branch/state.'},
224{name:'warehouse_code',type:'string',description:'Maximus WHCode (IntOrderHd.WarehouseCode). Future-proofing (B5) — branch_code is the live mapping key while there is one warehouse per state; warehouse_code is stored for when a branch spans multiple warehouses.'},
225],
226lifecycle:{
227states:['active'],
228transitions:[],
229warn:'Static entity — DB-seeded, no state transitions in Phase 1.',
230},
231},
232{
233id:'driver_record',
234name:'Driver Record',
235deferred:true,
236description:'Deferred to fast follow (BRD v1.5 treats driver as booking attributes only for Phase 1). Saved driver details for reuse across bookings. Built up organically by booking parties — no pre-population. Scoped per LSP account — drivers are NOT globally visible across accounts.',
237key_fields:[
238{name:'driver_name',type:'string',description:'Driver full name.'},
239{name:'driver_license',type:'string',description:'Driver license number. Paired with name.'},
241{name:'site_induction',type:'boolean',description:'Whether driver has completed site induction. If true, site induction acceptance is skipped during booking.'},
242],
243lifecycle:{
244states:['active'],
245transitions:[],
246warn:'Static entity — created during booking flow, no state transitions.',
247},
248},
249{
250id:'delivery_order',
251name:'Delivery Order (DO)',
252description:'Document (Release Authority) required per HBL for pickup authorization. One-to-many: each HBL can have multiple DOs (one per delegation tier in the hierarchy). Each DO is validated individually by ACFS. Uploaded by LSP or P4TC, validated by ACFS. Uploads remain per-tier (each tier provides its own DO — no auto-copy), BUT the required DO SET for a child HBL is its own DO PLUS all ancestor-tier DOs: a split child inherits every upstream release authority for pickup/validation (VBS daily standup 2026-06-04 — e.g. parent shipment 1 holds DO1, and its split children 2 and 3 each need their own DO plus the parent DO: shipment 2 needs DO1 + DO2, shipment 3 needs DO1 + DO3, so the driver collecting HBL3 carries DO1 + DO3). BRD v1.6 Addendum 1 confirms this as a release-authority chain: each party validates the next lower level and provides a Digital Release Authority, and a shipment must have a release from ALL parties (plus unpacked + customs cleared) to be collectable. Free release removes the DO requirement for that tier. Under-bond HBLs skip DO requirement entirely.',
259{name:'tier_level',type:'string',description:'Which level in the HBL hierarchy this DO covers. Each tier uploads its own; child HBLs inherit all ancestor-tier DOs for the pickup requirement.'},
260{name:'flag_reason',type:'string',description:'Optional comment captured when ACFS flags/invalidates a DO — why it was flagged (wrong DO, wrong content, unreadable upload, etc.). Not required on validate; good practice on reject. Surfaced to the booking party alongside the flagged status and included in the notification (VBS daily standup 2026-06-04).'},
265{from:'not_provided',to:'uploaded',trigger:'LSP or P4TC uploads DO document'},
266{from:'not_provided',to:'not_required',trigger:'HBL do_waived becomes true — free_release + free_release_verified, OR under_bond + under_bond_verified. ACFS verification is required before the DO is waived; the raw flag alone does NOT move the DO to not_required (BR-002).'},
267{from:'uploaded',to:'pending_validation',trigger:'ACFS begins DO review'},
268{from:'pending_validation',to:'validated',trigger:'ACFS confirms DO matches HBL details'},
269{from:'pending_validation',to:'flagged',trigger:'ACFS flags DO as incorrect — requires correction'},
270{from:'flagged',to:'uploaded',trigger:'LSP or P4TC re-uploads corrected DO'},
271],
272},
273},
274{
275id:'release_authority',
276name:'Release Authority',
277description:'FUTURE/DEFERRED entity (BRD V2.0 §3/§6.1, FR-LSP-25) for a detailed log of release-authority acts (who/when/which form) against an HBL. No release_authority API or write path is implemented for the initial release (17 Jul 2026, Roni); Phase 1 instead uses HBL-level release_status plus a single DO-document status. In particular, validating or waiving a DO does NOT create a "do_based" release_authority row in Phase 1 (OQ-069 resolution). The future design is expected to cover digital releases, multiple DOs, per-party/per-tier detail, and aggregation back into the HBL summary, but its exact persistence and rollup rules remain deferred. The fields below preserve the target shape for that later design and must not be read as an active Phase 1 write contract.',
280{name:'hbl_id',type:'string',description:'HBL against which release authority is provided.'},
281{name:'release_mechanism',type:"'digital_release' | 'do_based'",description:'FUTURE target enum for the form of a release act (distinct from hbl.release_type). "digital_release" represents an intermediate-level electronic approval; "do_based" is reserved for the deferred design that may represent a validated DO or verified waiver. Neither value defines an implemented release_authority write path in Phase 1; specifically, "do_based" rows are not written in the initial release (OQ-069).'},
282{name:'acting_lsp_id',type:'string',description:'The LSP (or NVOCC such as AGS) that provided the release.'},
283{name:'release_timestamp',type:'date',description:'When the release was provided.'},
284{name:'status',type:"'provided' | 'superseded'",description:'"provided" once recorded; "superseded" if a later release/reassignment replaces it (e.g. delegation revoked or HBL reassigned).'},
285],
286lifecycle:{
287states:['provided','superseded'],
288transitions:[
289{from:'provided',to:'superseded',trigger:'A later release replaces it, or the delegation/assignment it was based on is revoked or reassigned'},
290],
291},
292},
293{
294id:'delegation',
295name:'Delegation',
296description:'Records the delegation of one or more HBLs from one party to another. Tracks the chain of custody. Revoked by the delegating LSP themselves (lsp:r12) before the HBL is booked or its booking processed — on revoke the HBL returns to the delegator\'s assigned shipments and is removed from the delegatee. ACFS does NOT revoke; ACFS reassigns the assigned (last-hop) LSP instead (acfs:r13). (Revoke ownership moved to the LSP per VBS daily standup 2026-06-04.) Visibility follows hop-by-hop model (C-009): delegator sees immediate downstream only, not full multi-hop chain. ACFS sees full history for audit.',
299{name:'delegator',type:'string',description:'LSP or P4TC who initiated the delegation.'},
300{name:'delegatee',type:'string',description:'Target party — existing LSP (by ID). The "new P4TC (by email)" path is DEFERRED with the p4tc actor and is NOT surfaced in the Phase 1 delegate flow (lsp:r3); the field shape supports it for forward-compat only.'},
301{name:'delegation_method',type:"'existing_lsp' | 'one_off_p4tc'",description:'Whether delegating to a registered LSP or creating a one-off P4TC. For Phase 1 only "existing_lsp" is surfaced — the one-off P4TC path is removed from the delegate flow and deferred (VBS daily standup 2026-06-04); the union value is kept for forward-compat.'},
302{name:'hbl_ids',type:'string[]',description:'HBLs included in this delegation.'},
303{name:'created_at',type:'date',description:'When the delegation was created.'},
304],
305lifecycle:{
306states:['active','revoked'],
307transitions:[
308{from:'active',to:'revoked',trigger:'Delegating LSP revokes the delegation (lsp:r12)',guard:'Not yet booked or processed — HBLs revert to the delegator\'s assigned shipments'},
309],
310},
311},
312{
313id:'payment',
314name:'Payment',
315description:'Records payment transactions for bookings. One payment per booking. Tracks gateway used, amount, and transaction status. Payment gateway is Compay (managed/serviced by One Stop) — confirmed in VBS Screen Review meeting 2026-05-21 (Jason: "it has to be Compay", most carriers already use it). Integration is abstracted behind an adapter so providers can be swapped if needed. Added from BRD v1.5 data model.',
320{name:'payment_gateway',type:'string',description:'Gateway used. Compay for Phase 1 (managed by One Stop; Jason has requested a technical contact for integration). Abstracted behind adapter pattern so provider can be swapped later.'},
321{name:'payment_status',type:"'pending' | 'completed' | 'failed' | 'refunded'",description:'Transaction status. Refunds are processed outside VBS but status may be updated by ACFS.'},
322{name:'payment_timestamp',type:'date',description:'When the payment was processed.'},
328{from:'pending',to:'failed',trigger:'Payment gateway rejects or times out'},
329{from:'completed',to:'refunded',trigger:'ACFS processes refund outside system and updates status'},
330],
331},
332},
333{
334id:'user',
335name:'User / Account',
336description:'Two distinct shapes, managed as separate groups in the admin "Accounts & Users" area (VBS daily standup 2026-06-04; BRD v1.6 also splits the LSP entity from the User entity). (1) ACCOUNTS = LSP company accounts: company name, email (the login), branch, and an internal/auto company_id — no per-user role, one shared company login. (2) USERS = ACFS staff: username + role (Admin / User). ACFS role permissions are preconfigured in the backend per role; there is NO per-feature permission UI. Created by ACFS Admin.',
339{name:'username',type:'string',description:'For ACFS users: username / SSO identifier. For LSP company accounts there is no username — the company email is the login.'},
340{name:'company_name',type:'string',description:'LSP company accounts only: the company name (this is the account identity, not an individual person\'s name). Null/ACFS for ACFS users.'},
341{name:'email',type:'string',description:'LSP company accounts: the login + notification email. ACFS users: contact email.'},
342{name:'branch',type:'string',description:'LSP company accounts: branch. One of the three fields captured when creating an LSP account (company name, email, branch); company_id is internal/auto.'},
343{name:'role',type:"'lsp' | 'acfs_admin' | 'acfs_user'",description:'For ACFS users this is the Admin/User dropdown selection with backend-preconfigured permissions. LSP company accounts are implicitly role "lsp" with equal feature access.'},
344{name:'linked_lsp_id',type:'string',description:'For LSP users: the LSP company this account belongs to. Null for ACFS users.'},
358description:'Junction entity linking bookings to HBLs with per-HBL fee breakdown and the assigned truck. Makes the fee calculation per HBL explicit rather than implicit, and (BRD V2.0 §6.1) records which truck within the booking collects each HBL. Added from BRD v1.5 data model to support BR-019; extended for the multi-truck model (BR-039).',
362{name:'truck_id',type:'string',description:'New (BRD V2.0 §6.1). The truck (within the parent booking) assigned to collect this HBL.'},
363{name:'chargeable_weight',type:'number',description:'Chargeable weight for this HBL at time of booking (max of weight vs volume).'},
364{name:'rate',type:'number',description:'Rate applied to this HBL at time of booking.'},
365{name:'per_hbl_fee',type:'number',description:'Calculated fee for this HBL (chargeable_weight × rate).'},
366],
367lifecycle:{
368states:['active'],
369transitions:[],
370warn:'Junction entity — no state transitions. Created when booking is confirmed.',
371},
372},
373{
374id:'integration_maximus',
375name:'Maximus Integration via MuleSoft (Real-Time, Inbound)',
376is_integration:true,
377description:'Primary data source and single source of truth for HBL shipment data. BRD V2.0 (§6.2/§7, FR-INT-01..06, FR-ADM-16) moves this to a REAL-TIME model: all Maximus data is retrieved via MuleSoft APIs on demand — triggered on each page load of relevant views (HBL list, booking flow, pickup verification) and on a manual refresh action — REPLACING the former once/twice-daily batch sync (supersedes OQ-006). No direct database access from VBS to Maximus is permitted; all reads go through MuleSoft over a secure VPN (or IP whitelisting, TBC with ACFS IT). VBS has READ-ONLY access (no writes to Maximus, FR-INT-03). A transformation/normalisation layer in MuleSoft maps Maximus fields to VBS entities, normalises company names/identifiers across AGS/ICS/Maximus, and routes data-quality exceptions (nulls, rounding, unmatched records) to an exception queue for ACFS review (FR-INT-05, BR-034). Development/testing uses the Maximus UAT environment until sign-off (FR-INT-04). DEPENDENCY/RISK: Maximus is undergoing an Azure migration concurrent with this build — schema/connectivity may change; a go/no-go gate on integration readiness is required before go-live (OQ-046). TWO-TRACK SPLIT (10 Jul 2026 integration call): the MuleSoft/integration layer performs a RAW PULL only, landing Maximus data into OutSystems STAGING TABLES; the HBL hierarchy matching + business-rule transformation runs in the OUTSYSTEMS BACKEND consuming those staging tables — not in Mule. Clean handoff, no crossover, so the core logic sits in the VBS environment. Rule (Matt): EdiRequestedCargo is used ONLY to build the hierarchy — it is an insert-only landing table that never updates after insert, so everything except hierarchy is driven from the other (updatable) source tables. Query design: the initial single ~14-table join was split into order/cargo/container + milestone/hold/activity pulls for performance (Harry).',
378key_fields:[
379{name:'direction',type:'string',description:'Inbound — Maximus → MuleSoft → Portal (read-only).'},
380{name:'frequency',type:'string',description:'Real-time / on-demand: fetched on each page load of relevant views and on user-triggered manual refresh (ACFS-only manual refresh for Phase 1). Non-blocking for the UI — loading states shown while data is retrieved. No periodic batch sync.'},
381{name:'transport',type:'string',description:'MuleSoft middleware APIs over a secure VPN tunnel (preferred) or IP whitelisting (TBC). No direct DB connection from VBS frontend or backend (FR-INT-01/02).'},
383{name:'data_not_provided',type:'string',description:'HBL hierarchy parent-child relationships and per-party reference mappings are not explicit in Maximus — reconstructed via the transformation layer using weight/volume/description matching, with unmatched cases flagged for manual handling (BR-034, integration_ags, OQ-034). VBS cannot connect directly to ICS — all ICS-derived data is sourced via Maximus.'},
384{name:'status',type:'string',description:'Direction confirmed (real-time MuleSoft). Frontend displays customs/milestone status as provided by the API; sync/staleness is a backend/integration concern (OQ-038). UI shows loading states and a refresh control. Volume target ~400 HBLs/day across regions (BRD V2.0 §7.5).'},
385],
386lifecycle:{
387states:['active'],
388transitions:[],
389warn:'Integration spec — no state transitions. Real-time MuleSoft model supersedes the prior batch design (OQ-006).',
390},
391},
392{
393id:'integration_ags',
394name:'AGS Data Feed (Inbound)',
395is_integration:true,
396description:'Provides master HBL references, HBL hierarchy (parent-child relationships), and freight forwarder party data (name, account code). Data is consistent (unlike ICS which has variations across organisations). Matt and William are defining the exact data format and delivery mechanism. CRITICAL GAP: BRD v1.5 Section 6.2 completely omitted AGS. BRD V2.0 (§6.2/§7.6) now explicitly acknowledges the gap: HBL hierarchy reconstruction is performed in the MuleSoft transformation/normalisation layer using weight + volume + description matching where direct parent-child links are unavailable, company names/identifiers are normalised across AGS/ICS/Maximus, and inconclusive matches are flagged and routed to an ACFS exception queue (FR-INT-05, BR-034). Delivery meeting 2026-03-24 confirmed AGS is required for accurate consignee data (Maximus "too inconsistent"). Exact AGS feed format/mechanism still TBD — data discovery blocked until resolved (OQ-034).',
399{name:'frequency',type:'string',description:'TBD — Matt and William resolving (OQ-034).'},
400{name:'data_provided',type:'string',description:'Master HBL references (500-prefix), HBL hierarchy (parent-child), freight forwarder party assignments (account name, account code), consignee at each level.'},
401{name:'data_not_provided',type:'string',description:'Lowest-level HBL details (comes from Maximus instead).'},
402{name:'status',type:'string',description:'BLOCKER — exact data format, delivery mechanism, and frequency TBD. This is the single biggest technical risk. BRD v1.5 does NOT include AGS in integration section - must be corrected.',warn:'Cannot build auto-assignment, HBL hierarchy, or consignee accuracy without this feed. Blocks data discovery (Anoop urgency 2026-03-24). Matt and William working on it (OQ-034).'},
403],
404lifecycle:{
405states:['active'],
406transitions:[],
407warn:'Integration spec — no state transitions.',
408},
409},
410{
411id:'integration_payment',
412name:'Payment Integration (Outbound)',
413is_integration:true,
414description:'Payment processing for booking fees. Compay (managed by One Stop) for Phase 1 — confirmed in VBS Screen Review meeting 2026-05-21. Most carriers already use Compay. Integration is abstracted behind a single checkout redirect — provider can be swapped later if needed.',
417{name:'frequency',type:'string',description:'Real-time — triggered on each booking.'},
418{name:'provider',type:'string',description:'Compay for Phase 1 (One Stop is the account manager — Jason has requested a technical contact for William and Matt to plug into). Abstracted behind checkout redirect so provider can be swapped later.',warn:'Compay/One Stop integration details (API spec, test instance availability) pending — kickoff blocker for backend.'},
419],
420lifecycle:{
421states:['active'],
422transitions:[],
423warn:'Integration spec — no state transitions.',
424},
425},
426{
427id:'integration_email',
428name:'Email Notifications (Outbound)',
429is_integration:true,
430description:'Event-driven email notifications sent by the portal.',
433{name:'triggers',type:'string',description:'Delegation (secure link + OTP), booking confirmation (to account email), booking update (to booking party), booking cancellation (to booking party), DO flagged for correction (to booking party — Phase 1 sends to booking party, future may send to the party who uploaded the DO), user creation (welcome email with signin link).'},
434{name:'not_sent_to',type:'string',description:'Driver — no system emails. Booking party forwards details externally.'},
435],
436lifecycle:{
437states:['active'],
438transitions:[],
439warn:'Integration spec — no state transitions.',
440},
441},
442{
443id:'integration_lsp_registry',
444name:'LSP Registry Seed (One-time)',
445is_integration:true,
446description:'One-time bulk upload of LSP party data from AGS portal/party manager into the portal local DB.',
449{name:'frequency',type:'string',description:'One-time bulk upload at system launch. No ongoing sync.'},
450{name:'data_provided',type:'string',description:'Company name, email, company ID, branch code.'},
451],
452lifecycle:{
453states:['active'],
454transitions:[],
455warn:'Integration spec — one-time seed, no state transitions.',
456},
457},
458],
459journeys:[
460{
461id:'acfs-assigns-hbls',
462name:'ACFS Assigns HBLs to LSP (Remedial)',
463primary_actor:'acfs',
464preconditions:[
465'ACFS admin is logged in',
466'HBLs have been synced from Maximus',
467'Target LSP user exists in the portal',
468'Auto-assignment has failed or data issue exists',
469],
470steps:[
471{order:1,title:'View unassigned shipments',detail:'System lists FAK shipments that are unassigned or incorrectly assigned. Can filter by assignment status.'},
472{order:2,title:'Select and assign',detail:'ACFS selects shipments and assigns them to an LSP. HBL status moves to "assigned". This is a remedial step — primary assignment comes from data integration.'},
473],
474success_outcome:'HBLs are assigned to the target LSP and visible in their shipment list on next login.',
475warn:'Low priority for Phase 1. Matt indicated this may not be needed if auto-assignment is reliable within the 7-week timeline (C-010). Mark as optional.',
476},
477{
478id:'acfs-configures-slots',
479name:'ACFS Configures Pickup Slots',
480primary_actor:'acfs',
481preconditions:[
482'ACFS admin is logged in',
483'Site exists in the database',
484],
485steps:[
486{order:1,title:'Select site',detail:'ACFS selects a site (one at a time — no multi-site simultaneous config).'},
487{order:2,title:'Configure slot template',detail:'Select days of week (typically Mon-Fri). Set AM / PM half-day slots (VBS daily standup 2026-06-04 — AM/PM granularity for Phase 1, not hourly).'},
488{order:3,title:'Configure cutoff rules',detail:'Set booking cutoff (relative day + time, e.g. "previous working day, 4 PM") and change cutoff (same format). Relative to the slot day.'},
489{order:4,title:'Configure busyness thresholds (optional)',detail:'Optionally set busyness-band thresholds for the slot (BRD V2.0 FR-LSP-14/FR-ADM-01). Since 2026-07-09 (OQ-065) the LSP slot card reveals the actual booked-truck count for the date, so these thresholds only colour that number by band rather than hide it; they never block booking.'},
490{order:5,title:'Block holidays',detail:'Overlay holiday calendar to block specific dates.'},
493success_outcome:'Pickup slots are configured and available for LSP/P4TC booking.',
494warn:'Phase 1 implementation: Slot and site configuration is via backend/database (SQL/migrations) per C-006 and FR-ADM-02. UI steps described here are for Phase 2 reference.',
495},
496{
497id:'lsp-provides-release-authority',
498name:'LSP Provides Release Authority',
499primary_actor:'lsp',
500preconditions:[
501'LSP is logged in',
502'LSP has assigned HBLs that require release authority',
503],
504steps:[
505{order:1,title:'View assigned HBLs',detail:'LSP views the HBL dashboard. HBLs show their hierarchy level (lowest vs intermediate, from the FFO flag, BR-040) and current release status (digital release provided / DO validated / pending).'},
506{order:2,title:'Identify HBLs requiring release',detail:'System clearly indicates HBLs awaiting release authority. Non-lowest-level HBLs require only a digital release; lowest-level HBLs require a DO upload and validation.'},
507{order:3,title:'Select HBLs (batch)',detail:'LSP selects one or multiple HBLs. A batch may mix HBLs needing only a digital release with HBLs needing a DO upload (mixed-batch handling, FR-LSP-25/26).'},
508{order:4,title:'Provide digital release (non-lowest-level)',detail:'For selected non-lowest-level HBLs, apply a single digital release action — no documentation required. For Phase 1 the HBL summary records that the digital release was provided; the exact HBL update payload and whether this is stored or derived remain open (OQ-071). A detailed release_authority act record is deferred beyond the initial release (OQ-069). Batch release executes at individual shipment level irrespective of container grouping.'},
509{order:5,title:'Upload DO (lowest-level)',detail:'For selected lowest-level HBLs, upload a DO (by either the originating or the delegated party — DO upload is not restricted to one role, FR-LSP-28). Upload is an independent per-shipment action and lands in the ACFS validation queue. The HBL remains unavailable to book until ACFS validates every required DO (revised 17 Jul 2026, superseding the earlier FR-LSP-29/BRD V2.0 uploaded-only booking gate).'},
510{order:6,title:'Combined with delegation',detail:'Release authority and delegation can be processed seamlessly in the same flow without forcing sequential processing or separate sessions/roles (FR-LSP-27).'},
511],
512success_outcome:'Release authority is recorded per HBL (digital release for non-lowest levels, DO uploaded for lowest levels), allowing downstream parties to proceed toward booking once all required levels have release authority.',
513},
514{
515id:'lsp-delegates-shipments',
516name:'LSP Delegates Shipments',
517primary_actor:'lsp',
518preconditions:[
519'LSP is logged in',
520'LSP has assigned HBLs visible in their list',
521],
522steps:[
523{order:1,title:'Select shipments',detail:'LSP views list of assigned HBLs with shipment status. Can filter by site, milestone, customs status, etc., and sort by LFD to prioritise. Selects one or multiple shipments to delegate.'},
524{order:2,title:'Search and select target LSP(s)',detail:'Search for one or more target LSPs by company name or email address. BRD V2.0 (FR-LSP-34) supports selecting MULTIPLE recipients within a single delegation flow — reversing the 2026-06-04 standup single-recipient-dropdown note. Registered LSPs resolve against existing records; for an unregistered party the user enters an email only and the system records the delegation + sends a secure-link notification (the one-off self-service access flow remains a fast follow). NOTE (OQ-048): V2.0\'s "delegate selected HBLs to all nominated recipients in one operation" is ambiguous — clarify whether this fans the same HBLs out to multiple recipients or assigns different HBLs to different recipients within one flow.',edge:'Multi-recipient semantics pending clarification (OQ-048).'},
525{order:3,title:'Attach DOs or mark free release',detail:'For each lowest-level HBL in the delegation, the LSP (originating OR delegated party — FR-LSP-28) can upload one or more DOs. Delegation proceeds regardless of DO status — the system prompts/flags if a DO is required but does not block (FR-LSP-29). LSPs cannot self-mark HBLs as free release (ACFS-only per BR-002) — for free release the LSP requests offline and ACFS records it.'},
526{order:4,title:'Storage deadline warning',detail:'If any selected HBL has an LFD within 5 days or already exceeded, the system shows a prominent warning before the user confirms delegation (BR-042, FR-LSP-35).'},
527{order:5,title:'Confirm and notify',detail:'User confirms delegation of the selected HBLs to the chosen recipient(s). System updates next-hop assignment + lifecycle to "delegated" and emails the delegated LSP(s) a message with a secure link. No shipment data in the email body — details visible after login/OTP.'},
528],
529success_outcome:'Shipments are delegated to the chosen recipient(s). Target LSP(s) receive email with a secure access link. HBL status moves to "delegated" and assigned_lsp updates to the delegatee (BR-038).',
530},
531{
532id:'lsp-books-pickup',
533name:'LSP Books a Pickup',
534primary_actor:'lsp',
535preconditions:[
536'LSP is logged in',
537'Selected HBLs are at milestone "unpacked" or later (BR-001)',
538'HBLs are not already delegated (BR-004)',
539],
540steps:[
541{order:1,title:'Select shipments and choose Book Pickup',detail:'LSP selects one or multiple HBLs from their assigned list and chooses the action "Book Pickup". Can filter by site to group shipments by warehouse location for dispatch planning.'},
542{order:2,title:'Configure trucks and assign HBLs',detail:'Configure one or more trucks for the booking (BRD V2.0 §4.3, FR-LSP-30). Each truck requires Truck Registration (rego), Driver Name, Licence Number, and a Site Induction flag. Assign HBLs individually or in bulk across trucks. Trucks with unresolved issues are visually flagged (e.g. coloured tag, FR-LSP-33); the user can remove HBLs with unresolved errors from a truck without cancelling the booking (FR-LSP-31).'},
543{order:3,title:'Per-HBL readiness checklist',detail:'System validates each selected HBL and shows a per-HBL readiness checklist (FR-LSP-08/32): (1) milestone "unpacked" or later, confirmed via CFS Tally In Head; (2) fully customs cleared (incl. quarantine) OR a verified under-bond movement permission (BR-001, OQ-045); (3) release authority exists — digital release for non-lowest-level HBLs, OR all required DOs ACFS-validated or marked free-release for lowest-level HBLs. Each condition is flagged individually with a reason on failure. Missing or merely uploaded DOs must be resolved through the separate LSP upload → ACFS validation flow before the HBL can enter booking; HBLs with unresolved errors can be removed from the booking without cancelling it.'},
544{order:4,title:'Load calculation + pricing',detail:'System calculates total load (sum of weights, sum of volumes) and fee per HBL: chargeable_weight (max of weight vs volume) × rate. Sum of per-HBL charges + minimum charge = total booking fee. Displays per-HBL fee (ACFS only — BR-037), per-truck load summary, and total booking fee before payment.'},
545{order:5,title:'Select slot',detail:'LSP selects a single AM or PM slot for the whole booking, inline (not a pop-up) with week-by-week navigation. Each slot card shows the number of trucks already booked on that slot for the selected date (booked_truck_count, from GET /api/slots/available) — client decision 2026-07-09 (OQ-065, FR-LSP-14 addendum) to reveal the actual count. The count is informational and does not block booking.'},
546{order:6,title:'Accept T&Cs and site induction',detail:'Accept (1) booking terms and conditions once per booking, and (2) the driver site induction acknowledgement per truck (may be skipped where Site Induction = Yes, subject to ACFS confirmation — FR-LSP-17). System stores acceptance flags and timestamps.'},
547{order:7,title:'Review and consolidated payment',detail:'Review step summarises all trucks, their assigned HBLs, per-truck load (weight/volume), and total cost. LSP proceeds to a SINGLE consolidated payment for the entire booking regardless of truck count (FR-LSP-18/36) via Compay embedded checkout (managed by One Stop). Booking is confirmed only after payment succeeds.'},
548{order:8,title:'Confirmation',detail:'On success the system generates a unique booking reference, associates all trucks and their assigned HBLs with the booking, and emails confirmation to the account email. No email sent to driver — booking party forwards details externally. The dashboard then distinguishes pending vs booked shipments, with a prominent clickable booking-reference indicator (FR-LSP-37).'},
549],
550success_outcome:'Booking is confirmed with a unique reference, spanning one or more trucks with their assigned HBLs, paid via a single consolidated payment. HBLs move to hbl_status "booked". Confirmation sent to account email.',
551},
552{
553id:'lsp-modifies-booking',
554name:'LSP Modifies a Booking',
555primary_actor:'lsp',
556preconditions:[
557'LSP is logged in',
558'Booking exists in "open" state (not yet processed)',
559],
560steps:[
561{order:1,title:'Open booking (prefilled)',detail:'LSP searches for an existing booking using booking reference, HBL reference, truck registration, or driver name (lsp:r9), or opens it from the Bookings list (lsp:r11). The edit view opens with the current booking configuration prefilled (selected slot, HBLs, driver/truck all shown — VBS daily standup 2026-06-04: it should look like a real edit, not a blank form).'},
562{order:2,title:'Choose modification type',detail:'LSP can: (a) change per-truck driver/truck details (each truck edited independently, FR-LSP-22) — allowed anytime until collection, (b) change slot date/time — allowed before change cutoff only, (c) REMOVE HBLs from the booking — allowed; any refund for removed HBLs is handled offline by ACFS (VBS daily standup 2026-06-04). ADDING HBLs (or trucks) is NOT supported via LSP self-service (BR-035) — to add shipments the LSP makes a separate new booking on the same slot (parallel-booking pattern).'},
563{order:3,title:'System checks cutoff',detail:'If change cutoff has passed: truck/driver changes proceed, but slot/HBL changes are blocked. Cost-impacting changes after cutoff require ACFS admin override (BR-015).'},
564{order:4,title:'Batch submit',detail:'All edits are staged and submitted together via a single Update action (one call), with Update enabled only when something changed, alongside Cancel — not instant per-change saves (VBS daily standup 2026-06-04). Slot changes re-validate availability; removing HBLs recalculates the displayed total.'},
565{order:5,title:'Confirmation',detail:'Updated booking confirmation sent to account email. Booking reference remains the same.'},
566],
567success_outcome:'Booking is updated with new details. Confirmation sent. If fee changed, payment difference handled.',
568},
569{
570id:'p4tc-books-pickup',
571name:'P4TC Books a Pickup',
572deferred:true,
573primary_actor:'p4tc',
574preconditions:[
575'P4TC has received email with shipment roster and portal URL',
576'HBLs are at milestone "unpacked" or later',
577],
578steps:[
579{order:1,title:'Access portal',detail:'P4TC clicks link in email to access portal. No login required. Verifies via OTP sent to the same email. OTP verification serves as email security validation.'},
580{order:2,title:'View assigned HBLs',detail:'P4TC sees list of assigned HBLs from the delegation.'},
581{order:3,title:'Choose action',detail:'P4TC can either delegate shipments further (enter P4TC name + email, optionally upload new DO) or proceed to book pickup.'},
582{order:4,title:'Validate booking readiness',detail:'System checks unpacked status, customs clearance, and ACFS-validated DO status. A missing or uploaded-but-unvalidated DO blocks booking; it must be uploaded independently and validated by ACFS first. P4TC can contact ACFS for support.'},
584{order:6,title:'Select slot',detail:'Select an available AM or PM slot for a date (AM/PM half-day granularity for Phase 1; no density indicator). Does not block.'},
585{order:7,title:'Enter truck and driver details',detail:'Enter driver name, license#, truck rego. No saved driver list for P4TC (one-off users).'},
586{order:8,title:'Accept T&Cs and site induction',detail:'Accept booking terms and conditions + driver site induction acknowledgement.'},
587{order:9,title:'Make payment',detail:'Payment via Compay (managed by One Stop).'},
588{order:10,title:'Confirmation',detail:'Booking confirmation sent to P4TC email containing: booking reference, pickup slot (date/time), HBL numbers with weight/volume, fee total, and site address. No upstream delegation chain or LSP details exposed. No email to driver.'},
589],
590success_outcome:'Booking confirmed. Confirmation sent to P4TC email. HBLs move to "booked".',
591},
592{
593id:'acfs-validates-dos',
594name:'ACFS Validates Delivery Orders',
595primary_actor:'acfs',
596preconditions:[
597'One or more HBLs have uploaded DOs awaiting ACFS validation',
598],
599steps:[
600{order:1,title:'View unvalidated DOs',detail:'ACFS views the pre-booking validation queue of HBLs with uploaded DOs. The queue is HBL-centric and prioritised by upload date; no booking or slot exists yet.'},
601{order:2,title:'Review DO against HBL',detail:'View lowest-level HBL details alongside the uploaded DO and its uploader/upload timestamp.'},
602{order:3,title:'Validate or flag',detail:'If the DO matches the HBL details, mark it validated (no comment needed), which makes the HBL eligible for booking once its other readiness checks pass. If incorrect, flag it and optionally add a reason (wrong DO / wrong content / unreadable upload, etc.); the HBL/shipment detail shows "flagged" with the reason and the uploader is notified to re-upload.'},
603],
604success_outcome:'DO is marked as validated for that HBL, or flagged for correction.',
605warn:'DO validation can be done by offshore team independently from pickup verification. Same people doing pickup verification can also validate DOs, but DO validation is a separate capability.',
606},
607{
608id:'acfs-verifies-pickup',
609name:'ACFS Verifies Pickup',
610primary_actor:'acfs',
611preconditions:[
612'Booking exists in "open" state',
613'Typically triggered when the driver arrives at the warehouse',
614],
615steps:[
616{order:1,title:'Search booking',detail:'When a driver arrives, ACFS searches bookings by booking ref# or by driver name / license / truck rego to find all bookings that driver is collecting (a driver may carry multiple bookings).'},
617{order:2,title:'Review details',detail:'View booking details + DO validation status + customs clearance + audit tracking history. Includes DO validation if not already done.'},
618{order:3,title:'Mark processed or reject',detail:'If DOs are validated and customs cleared, click the "Processed" CTA (BRD V2.0 §4.7; the 2026-06-04 standup had briefly called this "ready to collect", reverted in v0.14.0). If validation fails, booking is flagged — does not proceed. After "processed", ACFS generates the pick list externally and the only next state is "complete" (collected milestone synced from Maximus/Tally Out).'},
619],
620success_outcome:'Booking moved to "processed" (ready for physical pickup), or flagged for issues.',
621warn:'Detailed field-level requirements for this view TBD — to be covered in next session with Matt.',
622},
623{
624id:'lsp-cancels-booking',
625name:'LSP Cancels a Booking',
626primary_actor:'lsp',
627preconditions:[
628'LSP is logged in',
629'Booking exists in "open" state (cancellation allowed only before "processed")',
630],
631steps:[
632{order:1,title:'View bookings',detail:'LSP views current and past bookings from the Bookings view (lsp:r11).'},
633{order:2,title:'Open booking details',detail:'LSP opens the booking they want to cancel.'},
634{order:3,title:'Cancel booking',detail:'LSP initiates cancellation — allowed any time before the booking is "processed"; blocked after (BR-022). Refund is processed outside the system (C-003).'},
635],
636success_outcome:'Booking is cancelled. HBLs revert to previous hbl_status and become available for rebooking. Refund handled offline by ACFS.',
637},
638{
639id:'acfs-cancels-booking',
640name:'ACFS Cancels a Booking',
641primary_actor:'acfs',
642preconditions:[
643'ACFS admin is logged in',
644'Booking exists',
645],
646steps:[
647{order:1,title:'Search booking',detail:'ACFS searches by booking ref, truck rego, or driver name/license.'},
648{order:2,title:'Cancel booking',detail:'ACFS initiates cancellation. Must provide cancellation reason.'},
649{order:3,title:'Notification',detail:'Cancellation update sent to the booking party via email.'},
650],
651success_outcome:'Booking is cancelled. HBLs revert. Refund processed outside the system. Booking party notified.',
652},
653{
654id:'p4tc-manages-booking',
655name:'P4TC Manages Booking (One-off)',
656deferred:true,
657primary_actor:'p4tc',
658preconditions:[
659'P4TC has an active booking',
660],
661steps:[
662{order:1,title:'Contact ACFS',detail:'P4TC contacts ACFS for any booking modifications. No self-service modification for one-off booking parties.'},
663],
664success_outcome:'ACFS handles the modification on behalf of the P4TC.',
665},
666{
667id:'acfs-creates-user',
668name:'ACFS Creates a User',
669primary_actor:'acfs',
670preconditions:[
671'ACFS admin is logged in',
672],
673steps:[
674{order:1,title:'Choose Account or User',detail:'Two separate creation paths (VBS daily standup 2026-06-04): "Add new Account" for an LSP company, or "Add new User" for ACFS staff. They capture different data and are visually distinct.'},
675{order:2,title:'Enter details',detail:'Account (LSP company): company name, email (the login), branch — only these three; company_id is generated internally. No role, no per-feature permissions. User (ACFS): username, role via Admin/User dropdown (permissions preconfigured in the backend per role). SSO-based access for ACFS.'},
676{order:3,title:'System sends welcome email',detail:'Welcome email with signin link sent to the account email / ACFS user. Link expires in 72 hours.'},
677{order:4,title:'Activate',detail:'LSP account: clicks link and sets password. ACFS user: clicks link and SSO login is requested. Successful login completes activation.'},
678],
679success_outcome:'User account is created and active. User can log in.',
680},
681{
682id:'acfs-manages-user-accounts',
683name:'ACFS Manages User Accounts',
684primary_actor:'acfs',
685preconditions:[
686'ACFS admin is logged in',
687'User account exists',
688],
689steps:[
690{order:1,title:'Find in Accounts or Users',detail:'ACFS navigates the two groups — Accounts (LSP companies) and Users (ACFS staff) — and searches by company name / email (accounts) or username (users). No combined "all users" view (VBS daily standup 2026-06-04).'},
691{order:2,title:'View details',detail:'Account: company name, email, branch, status. User: username, role (Admin/User), status. No per-feature permission list — permissions are preconfigured per role in the backend.'},
692{order:3,title:'Update',detail:'Account: update company name, email, branch. User: update details and change the role via the Admin/User dropdown. There is no per-feature permission toggling.'},
693{order:4,title:'Deactivate or reactivate',detail:'ACFS can deactivate an LSP account or ACFS user (prevents login). Can reactivate later if needed. Deactivated accounts retain all historical data.'},
694{order:5,title:'Confirmation',detail:'User account updated. Email notification sent to user if contact details changed or account status changed.'},
695],
696success_outcome:'User account is updated with new details or status. User notified if applicable.',
697},
698{
699id:'acfs-updates-user',
700name:'ACFS Updates a User',
701primary_actor:'acfs',
702preconditions:[
703'ACFS admin is logged in',
704'Target user exists',
705],
706steps:[
707{order:1,title:'Select account or user',detail:'Search and select an LSP account (from Accounts) or an ACFS user (from Users).'},
708{order:2,title:'Update details',detail:'LSP account: update company name, email, branch (company_id is internal). ACFS user: update details and role (Admin/User), except SSO identity. No per-feature permission editing.'},
709],
710success_outcome:'User details are updated.',
711},
712{
713id:'acfs-removes-user',
714name:'ACFS Removes a User',
715primary_actor:'acfs',
716preconditions:[
717'ACFS admin is logged in',
718'Target user exists',
719],
720steps:[
721{order:1,title:'Select user',detail:'Search and select the user to remove.'},
722{order:2,title:'Archive user',detail:'User is archived on removal. Access is disabled and email notification is disabled.'},
723],
724success_outcome:'User is archived. Cannot log in. No further notifications sent.',
725},
726],
727business_rules:[
728{
729id:'BR-001',
730description:'Delegation can happen at any milestone — no unpack gate. Booking requires all included HBLs to have milestone "unpacked" or later (confirmed via a CFS Tally In Head record, BRD V2.0 §3/§4.3) AND fully customs cleared (including quarantine) AND release authority granted — EXCEPT under-bond HBLs, whose verified movement permission stands in for customs clearance. Release authority for the BOOK gate means a DIGITAL RELEASE for non-lowest-level HBLs, or all required DOs ACFS-VALIDATED (or do_waived) for lowest-level HBLs. REVISED 17 Jul 2026 (Jaffar update from Matt/Roni): merely uploaded or pending-validation DOs no longer permit booking. LSPs upload DOs independently from the shipment page; ACFS validates them on the Documents queue; only then does the HBL become available to book. This supersedes the BRD V2.0 FR-LSP-08/29 uploaded-only wording and removes the former asymmetry between release_status and the booking gate. The gate is therefore: milestone "unpacked"-or-later (Tally In) AND (customs cleared OR under_bond_verified) AND (release authority: digital release [non-lowest] OR DOs validated/do_waived [lowest]). Delegate remains available independently of booking readiness. (Under-bond customs substitution is an inference pending confirmation — OQ-045.) CLARIFIED 2026-08-20 (VBPP-226 BR-4, VBPP-227): the hbl.release_status SUMMARY FIELD is not itself an eligibility condition at any of its values — including "Override". Eligibility is evaluated on HBL status, customs status and DO docs status only. This is not a loosening of the gate: for a LOWEST-level HBL the DO-docs condition already carries the release requirement, and an INTERMEDIATE HBL cannot initiate a booking at all (only the lowest-level reference holder can), so there is no case where an intermediate\'s pending release should block someone else\'s booking. Read release_status as reporting, and the three conditions above as gating.',
731applies_to:['hbl','booking'],
732source:'BRD s4.2 + discussion between Rahul, Roni, and Matt on 2026-03-17 and 2026-03-18; validated-before-booking revision communicated by Jaffar from Matt/Roni on 2026-07-17',
733},
734{
735id:'BR-002',
736description:'Release authority per HBL has TWO forms selected by hbl_level_indicator (BR-040): a DIGITAL RELEASE for intermediate HBLs (owned by BR-041) or a DO-based release for lowest-level HBLs (owned by THIS rule). A shipment cannot be collected unless release authority is satisfied at ALL required levels; release_status is the derived per-HBL rollup. This rule governs the LOWEST-LEVEL DO/waiver chain. DO requirement per (lowest-level) HBL: each delegation tier uploads its own DO (uploads are per-tier, not auto-copied), but the required DO SET for a child HBL is its own DO PLUS all ancestor-tier DOs — release authority cascades down the split chain (VBS daily standup 2026-06-04: parent shipment 1 holds DO1; child shipment 2 needs DO1 + DO2, child shipment 3 needs DO1 + DO3, so the driver collecting HBL3 carries DO1 + DO3). BRD v1.6 Addendum 1 frames this as a release-authority chain: each party validates the next lower level and provides a Digital Release Authority, and a shipment must have a release from ALL parties (plus unpacked + customs cleared) to be collectable. ACFS validates each DO individually (HBL-centric). DO requirement is waived by under_bond flag OR free_release flag, both of which require ACFS verification outside the portal before do_waived becomes true. Set-by-party differs: under_bond can be marked by LSP or ACFS (manual flag, ACFS-verified), but free_release is ACFS-only — LSPs cannot self-mark and must request offline; ACFS then sets and verifies in the admin portal. (free_release ACFS-only confirmed in VBS Screen Review meeting 2026-05-21 — Matt: "it would definitely need to be verified [by ACFS]".) Bottom-most party must have all applicable tiers\' DOs present (own + inherited).',
739warn:'Under-bond and free_release are manual flags — not lifecycle or automated processes. Matt flagged that "free_release" name may change as it covers multiple off-norm release scenarios (2026-05-21) — terminology pending clarification with stakeholders.',
740},
741{
742id:'BR-004',
743description:'An LSP can either delegate OR book a given HBL — never both — for the hop they currently hold. Mutual exclusivity is per-HBL AND per-hop: once the active party (assigned_lsp) delegates the HBL onward, THEY can no longer book it (it has left their hands), but the delegatee — now the assigned_lsp — can. Enforce against assigned_lsp + the viewing party, NOT by reading the global hbl_status "delegated" value (which would wrongly block the delegatee). See the hbl_status field note and BR-038.',
744applies_to:['hbl','lsp'],
745source:'OQ-003 resolution + March 18 flow + VBS daily standup 2026-06-04 (assigned_lsp = last hop; per-hop gating clarified v0.10.1)',
746},
747{
748id:'BR-005',
749description:'Slots are AM / PM half-day windows. Slot cutoffs are relative day + time (e.g. "previous working day, 4 PM" or "same day, 10 AM"). Booking cutoff and change cutoff configured separately per slot template. Per-site configuration. No hard capacity limits. BLACKOUT DATES (added 2026-08-20): blackout dates are slot configuration data written through the same admin API as the slot itself and must round-trip to the slot read (VBPP-212). They are not merely display — "previous working day" arithmetic for BOTH cutoffs must SKIP blackout dates and non-working days when resolving the actual cutoff datetime (VBPP-256). Cutoff enforcement is server-side: a booking or change attempt after the resolved cutoff is refused with a cutoff notice, not silently accepted (VBPP-202, VBPP-232, VBPP-253, VBPP-254). Two cutoff questions remain open — whether cutoff times resolve in each site\'s local timezone (OQ-079) and whether a site may be configured with no booking cutoff at all (OQ-080); this rule currently assumes a cutoff always exists. The slot selector is inline (not a pop-up) with week-by-week navigation and each slot card shows the NUMBER OF TRUCKS already booked on that slot for the selected date (slot.booked_truck_count) — client decision 2026-07-09 (OQ-065, FR-LSP-14 addendum), which reveals the actual count and supersedes the earlier "heatmap without revealing counts" model. heat_map_threshold now only optionally colours that visible number by busyness band. The count is informational and NEVER blocks booking (no hard capacity limits).',
750applies_to:['booking','slot'],
751source:'discussion between Roni and Matt on 2026-03-18 + VBS daily standup 2026-06-04 (AM/PM slots) + BRD V2.0 FR-LSP-14/FR-ADM-01 (busyness indicator) + client decision 2026-07-09 (reveal actual truck count per slot, OQ-065 / FR-LSP-14 addendum). Absorbs former C-001 (capacity constraint).',
752},
753{
754id:'BR-007',
755description:'ACFS can partially process bookings — HBLs that have cleared customs proceed to "processed" while blocked ones are rebooked separately.',
756applies_to:['booking','acfs'],
757source:'discussion between Rahul, Roni, and Matt on 2026-03-17',
758},
759{
760id:'BR-009',
761description:'LSP can only view shipments allocated to them. Shipment visibility is scoped per LSP — no cross-LSP visibility.',
762applies_to:['hbl','lsp'],
763source:'March 18 flow diagram',
764},
765{
766id:'BR-010',
767description:'HBL/milestone/customs/tally data is retrieved from Maximus in REAL TIME via MuleSoft APIs on each page load of relevant views (HBL list, booking flow, pickup verification) and on a user-triggered manual refresh (BRD V2.0 §6.2/§7.3, FR-ADM-16). This REPLACES the former once/twice-daily batch sync (supersedes OQ-006). Data fetch is non-blocking for the UI — loading states are shown while data is retrieved. Manual refresh remains ACFS-only for Phase 1; LSP self-service refresh is not in scope. ACFS cannot control when Maximus updates, so manual refresh lets staff pull the freshest state on demand (VBS Screen Review 2026-05-21 — Welliam: "we\'re gonna need a manual option as well to sync it").',
773description:'Missing doc request aborts the booking process. Booking is blocked (offline) until the DO is received. This is a hard stop, not a warning.',
774applies_to:['booking','hbl'],
775source:'March 18 flow diagram',
776},
777{
778id:'BR-012',
779description:'Booking confirmation, modification, and cancellation notifications sent to booking party email (LSP account email or P4TC email). Driver receives nothing from the system — booking party forwards details externally via their own rostering process.',
780applies_to:['booking','acfs'],
781source:'discussion between Roni and Matt on 2026-03-18. Consolidates former BR-012 and BR-020.',
782},
783{
784id:'BR-013',
785description:'P4TC can delegate shipments further to another P4TC by entering name + email. The new P4TC receives an email with shipment roster and secure link. Chain delegation is supported.',
786applies_to:['p4tc','hbl'],
787source:'March 18 flow diagram',
788},
789{
790id:'BR-014',
791description:'ACFS manages two distinct groups, not one combined user list (VBS daily standup 2026-06-04): Accounts (LSP company accounts — company name, email, branch) and Users (ACFS staff — username + role). Feature permissions are PRECONFIGURED in the backend per role; there is no per-feature permission UI. Lifecycle: create, update, deactivate within each group. Removal is soft-delete — access and notifications disabled, data retained. Welcome/activation link expires in 72 hours. ACFS ROLES REVISED 2026-08-20 — the flat Admin / User pair is superseded by EIGHT granular roles (Confluence LCBP 2715320321 "Roles & Functions", Matt Drake, 10 Aug 2026): (1) Gatehouse — read-only access to bookings, searchable by truck rego, and the DEFAULT level; (2) Validate Delivery Orders; (3) Apply Override Release; (4) Correct HBL Hierarchy — the human end of the ingestion manual-review queue (BR-034), a capability with no prior counterpart in this model; (5) FAK Frontdesk — view bookings and amend driver details; (6) Amend Bookings — amend, cancel and create bookings; (7) Create New LSP Accounts; (8) Full Admin. Roles are capability grants, so a member of FAK front-desk staff may hold several. Gatehouse is an operational role, not an observer: it polices site access and only admits trucks that hold a booking. NOTE the LSP side still has NO role concept — one shared company login, no per-user role. That was a deliberate simplification and Matt has now flagged its absence as a defect (OQ-074).',
792applies_to:['acfs','lsp'],
793source:'March 18 flow diagram + Miro board + VBS daily standup 2026-06-04 (Accounts vs Users; role-based, no per-feature UI). Consolidates former BR-014, BR-024, BR-025. Eight-role ACFS model from Confluence LCBP 2715320321 "Roles & Functions" (10 Aug 2026), reconciled 2026-08-20.',
794},
795{
796id:'BR-015',
797description:'Booking modifications: (1) LSP can change truck/driver anytime until collection (no cutoff, no fee). (2) LSP can change slot date/time before change cutoff (no fee). (3) LSP CAN remove HBLs from an existing booking (refund for removed HBLs handled offline by ACFS) but CANNOT add HBLs — to add shipments they create a new booking on the same slot (parallel-booking pattern, BR-035). (Updated per VBS daily standup 2026-06-04 — previously LSPs could neither add nor remove.) (4) ACFS admin can do all of the above plus add HBLs on existing bookings — all ACFS-side amendments are fee-free in the portal for Phase 1 (BR-036). Any extra payment for added volume is collected off-system. (5) ACFS admin can override all cutoffs. (6) Admin and no-show rebookings are fee-free inline edits on the existing booking. (7) Edits open prefilled and submit as a single batched Update action, not instant per-change saves (BR-030). (8) P4TC cannot self-service modify — must contact ACFS.',
798applies_to:['booking','lsp','p4tc','acfs'],
799source:'discussion between Roni and Matt on 2026-03-18 + 2026-03-20 + VBS Screen Review 2026-05-21 + VBS daily standup 2026-06-04. Consolidates former BR-006, BR-015, BR-023, BR-027.',
800},
801{
802id:'BR-016',
803description:'Driver record scoping (DEFERRED to Phase 2): Driver records will be scoped per LSP account when driver reuse is implemented. Phase 1 treats driver details as booking attributes entered fresh each time per assumption A-025.',
804applies_to:['driver_record'],
805source:'Assumption A-023 (deferred per A-025)',
806warn:'Driver reuse functionality deferred to Phase 2/fast follow',
807},
808{
809id:'BR-017',
810description:'Booking requires acceptance of two separate documents: (1) booking terms and conditions (legal), (2) driver site induction acknowledgement. If the selected driver already has site_induction = true, the induction acceptance is skipped.',
811applies_to:['booking','driver_record'],
812source:'discussion between Roni and Matt on 2026-03-18',
813},
814{
815id:'BR-018',
816description:'DO validation is HBL-centric, not booking-centric. It is a separate capability from pickup verification. Can be performed by an offshore team. Warehouse staff doing pickup verification may also validate DOs inline.',
817applies_to:['hbl','acfs'],
818source:'discussion between Roni and Matt on 2026-03-18',
819},
820{
821id:'BR-019',
822description:'Fee calculation: chargeable_weight (max of weight vs volume) per HBL × rate (single flat value). Sum individual HBL charges + minimum charge = total booking fee. Rate is a single configurable value for Phase 1 — may become per-slot or per-region in future.',
823applies_to:['booking','hbl'],
824source:'discussion between Roni and Matt on 2026-03-18',
825},
826{
827id:'BR-022',
828description:'Booking cancellation: allowed any time BEFORE the booking reaches "processed"; not after (once processed, the only next state is "complete" — and neither ACFS nor the LSP may cancel a processed or collected booking, VBPP-266). LSP can cancel their own bookings. ACFS can cancel any booking (requires cancellation reason). Cancellation notification sent to booking party. HBLs revert to previous status and become available for rebooking. REFUND REVISED 2026-08-20: the portal is NO LONGER refund-agnostic. A refund is INITIATED in-portal on cancellation and on HBL removal (US-066 / VBPP-113), and where a paid booking is cancelled the payment CARRIES FORWARD to the rebooking at no charge rather than being refunded and re-collected — the booking party is shown a "Paid — carries forward from a cancelled booking at no charge" indicator on the affected HBLs (VBPP-167, VBPP-204, VBPP-203). Rebooking a previously-paid cancelled HBL must therefore NOT prompt for payment again. Settlement of an initiated refund still happens through Compay/finance outside the portal; what changed is that the portal now records and displays the refund/carry-forward state instead of ignoring it.',
834description:'Slots with active bookings cannot be removed or modified in Phase 1. ACFS must cancel or reschedule bookings before removing a slot. Blackout dates enforced via holiday calendar overlay.',
835applies_to:['slot','acfs'],
836source:'March 18 Miro board. Absorbs former C-002 (temporal constraint).',
837},
838{
839id:'BR-027',
840description:'HBLs track two orthogonal dimensions: (1) milestone — physical progress through the supply chain (on_vessel → at_wharf → in_yard → unpacked → collected), and (2) hbl_status — business/booking state (unassigned → assigned → delegated → booked). Both dimensions exist simultaneously and independently. An HBL can be "in_yard" (physical location) while "delegated" (business state). BRD v1.5 presents these as a flattened single lifecycle for UI simplicity, but the implementation must maintain both dimensions independently in the data model.',
846description:'HBL list views (FR-LSP-02) must display pickup site as a visible column and support filtering/searching by site. Critical for LSP dispatch planning — determines which warehouse to send truck to. BRD v1.5 omits this from FR-LSP-02 spec but field is present in data model and operationally required.',
852description:'Once an HBL is booked, both HBL reference and booking reference become equally important identifiers and must be displayed side-by-side in HBL table views. LSPs must be able to search by either identifier (lsp:r9). BRD FR-LSP-20 allows booking search but does not explicitly specify search keys — must support booking reference, HBL reference, truck registration, and driver name.',
864description:'Booking "complete" status is derived, not manually set. A booking becomes "complete" when all its HBLs reach the "collected" milestone (Tally Out). No manual status change needed. (Booking status "complete" — BRD V2.0 §6.1; the HBL milestone stays "collected".)',
865applies_to:['booking','hbl'],
866source:'discussion between Rahul and Roni on 2026-03-20',
867},
868{
869id:'BR-029',
870description:'Audit trail: slim version on booking (booking created, payment confirmed). Full hop history lives on the HBL — shows all delegation chain hops, assignment changes, and status transitions per shipment.',
871applies_to:['booking','hbl'],
872source:'discussion between Rahul and Roni on 2026-03-20',
873},
874{
875id:'BR-030',
876description:'The LSP portal has TWO distinct views (VBS daily standup 2026-06-04): "Shipments" (assigned HBLs not yet acted on, with delegated/booked sub-states) and "Bookings" (a booking-reference-keyed list, each booking expanding to its multiple HBLs). The Bookings view reuses the same booking list/detail component as the ACFS admin bookings interface (different permissions). Edit booking opens prefilled with the current configuration and batches all changes into a single Update action (one call) — Update enabled only when something changed, alongside Cancel; not instant per-change saves. LSP can edit truck/driver anytime, and slot or remove-HBLs before change cutoff (per BR-015).',
877applies_to:['booking','lsp'],
878source:'discussion between Rahul and Roni on 2026-03-20 + VBS daily standup 2026-06-04 (Shipments vs Bookings split, prefilled batch edit).',
879},
880{
881id:'BR-034',
882description:'HBL hierarchy reconciliation. CONFIRMED AND IMPLEMENTED 3 Aug 2026 (Confluence LCBP 2760474628) — the matching parameters that were pending in May are now settled. The ingestion compares FOUR cargo attributes between an upper-level and a lower-level HBL: Quantity, Gross Weight, Net Weight, Volume. More attributes matching = higher confidence. Bands (hbl.match_level): all 4 match uniquely = 100%; 3 match and one is MISSING = 95%; 3 match and one has a SMALL DIFFERENCE = 90%; only weight OR only volume matches = 50%; nothing matches = not scored. The top three bands auto-link silently. The bottom two set hbl.needs_manual_review and route to the ACFS admin review queue — as do a consignee mapping failure and an L1 service-provider mapping failure, which are evaluated INDEPENDENTLY of relationship confidence (either can trigger review on its own, or both together). A record routed for review is RETAINED with its exception recorded, never rejected. On a valid match the upper-level HBL becomes parent, the lower-level becomes child, and parent_hbl_id is written to the child; an existing HBL is updated rather than duplicated. Where no valid parent exists the lower-level HBL is still VALID with relationship_type "NO_PARENT" — a standalone shipment is a normal outcome, not an error. Ordering constraints: the container must be processed before its HBLs, and parent-child matching runs only AFTER HBL synchronisation completes. Level classification is separate and deterministic (BR-040): lower-level = CargoType LCL with FFIndicator blank/NULL; upper-level = CargoType LCL with FFIndicator = FFO. The human end of this rule is the "Correct HBL Hierarchy" ACFS role (BR-014). NOTE the unresolved consequence: until a relationship is linked, downstream parties cannot see the shipment under their own reference — which is the mechanism behind the production visibility failure in OQ-073.',
884source:'VBS Screen Review meeting 2026-05-21 (original) — Welliam: "we can have a screen... 100% we can automatically identify... partial match or no match, we need input from the user to fix it or to manually link it." Matching rules, confidence bands and manual-review triggers CONFIRMED by Confluence LCBP 2760474628 "VBS Shipment – HBL Staging to Master Business Rules" (Hariharan Chandrasekaran, 3 Aug 2026), reconciled 2026-08-20.',
885warn:'The review fields exist (needs_manual_review, match_level, exception_id) but the production schema holds only ONE parent per child, so a competing candidate match cannot be persisted for the admin to choose between, and a re-deriving review screen would be the only way to offer one. CORRECTED 2026-08-21 after reading the frontend build: there is NO review UX. ACFS has 5 routes (bookings, documents, shipments, users, slots) and none is a hierarchy, match or exception queue; needs_manual_review and exception_id are declared on the API types and read by nothing. So the "Correct HBL Hierarchy" role in BR-014 currently has no screen, and the re-derive-on-read fallback has nothing to re-derive into. See OQ-081.',
886},
887{
888id:'BR-035',
889description:'LSP HBL-list edits on an existing booking: BOTH add and remove are allowed. REVISED 2026-08-20 to match what was built — this supersedes the parallel-booking pattern entirely. ADD: the LSP adds HBLs to an existing booking and pays the BALANCE difference in-portal (US-060 / VBPP-107); the added HBLs must independently pass the booking readiness gate (BR-001). REMOVE: the LSP removes HBLs and a REFUND IS INITIATED in-portal (US-061 / VBPP-108) — see BR-022 for the refund mechanics, which are no longer offline. Removing the LAST HBL from a booking automatically cancels the booking rather than leaving an empty one (VBPP-265). Both operations are subject to the change cutoff (BR-015) and blocked once the booking is processed. The former rationale — "avoids triggering a secondary in-portal payment flow from LSP self-service; keeps Phase 1 payment scope minimal" — no longer holds: balance payment and refund initiation are both implemented. The parallel-booking-on-the-same-slot workaround is REMOVED from the model; do not design around it. ACFS-side add/remove remains fee-free and payment-free (BR-036) — the LSP and ACFS paths differ deliberately.',
890applies_to:['booking','lsp','acfs'],
891source:'VBS Screen Review 2026-05-21 + VBS daily standup 2026-06-04 (original: LSP remove w/ offline refund, add not allowed). SUPERSEDED by the built implementation — Jira US-060 (VBPP-107, add HBLs with balance payment), US-061 (VBPP-108, remove with refund initiated), US-066 (VBPP-113), VBPP-265 (last-HBL removal auto-cancels). Reconciled 2026-08-20.',
892warn:'The build moved ahead of this rule without the rule being restated — worth confirming with Roni that in-portal balance payment and refund initiation were an intended scope change and not drift, since BR-036 still keeps the ACFS path fee-free and the asymmetry is now load-bearing.',
893},
894{
895id:'BR-036',
896description:'ACFS-side booking amendments (add/remove HBLs, change slot, change truck/driver) are fee-free in the portal for Phase 1. Even when HBLs are added and the total recalculates, no in-portal payment is collected — any additional payment is handled off-system. Stakeholders confirmed no fee for amending booking time. Volumetric/quantity changes triggering additional charges are a debated edge case (Jason vs Matt) and were parked for Phase 1 with the understanding that ACFS staff use judgment and collect off-system if needed. Revisit for Phase 2 in-portal surcharge support.',
897applies_to:['booking','acfs'],
898source:'VBS Screen Review meeting 2026-05-21 — Matt: "in the initial release... that would be off system." Jason confirmed: "no fee for amending a booking time." Pickup-amount fee debate parked.',
899warn:'Edge case: when an amendment increases pickup volume substantially, business may want in-portal surcharge in future. Track usage post-launch to inform Phase 2 scope.',
900},
901{
902id:'BR-037',
903description:'Fee display visibility (VBS daily standup 2026-06-04): the LSP/booking party sees a flat total only — no itemised per-HBL breakdown (the section is labelled "Fees", not "Fee breakdown"). ACFS admin MAY see the per-HBL breakdown, but the minimum charge is never shown to any party (including in the ACFS breakdown). Reintroducing the itemised breakdown for LSPs later is just re-enabling the component. minimum_charge_applied stays a backend/booking attribute, not surfaced to booking parties.',
904applies_to:['booking','lsp','acfs'],
905source:'VBS daily standup 2026-06-04 — Roni/Rahul on fee breakdown vs flat fee, hide minimum charge.',
906},
907{
908id:'BR-038',
909description:'hbl_status transitions — the booking/delegation dimension (the HBL entity lifecycle models milestones only, BR-027). States and transitions: unassigned → assigned (ACFS or auto-assignment sets assigned_lsp); assigned → delegated (the current assigned_lsp delegates onward — assigned_lsp moves to the delegatee, who becomes the actionable party); delegated → assigned (delegation revoked by the delegating LSP (lsp:r12) or reassigned by ACFS (acfs:r13) — assigned_lsp reverts to the prior hop); assigned/delegated → booked (the current assigned_lsp books a pickup); booked → assigned (booking cancelled, BR-022 — HBLs revert and become available for rebooking). "collected" is a MILESTONE, not an hbl_status. Crucially, who may delegate or book is always evaluated against assigned_lsp relative to the VIEWING party — never by reading the global hbl_status string (BR-004): a downstream delegatee whose assigned_lsp == themselves can book even though the canonical status reads "delegated".',
910applies_to:['hbl','lsp','acfs'],
911source:'Derived from BR-004, BR-022, lsp:r12, acfs:r13 + VBS daily standup 2026-06-04 (assigned_lsp = last hop). Makes the second HBL dimension an explicit state machine (the entity lifecycle carries milestones only). Added v0.10.1 (internal-consistency pass).',
912},
913{
914id:'BR-039',
915description:'Multi-truck booking (BRD V2.0 §4.3, FR-LSP-30/31/33/36): a single booking may contain multiple trucks. Each truck has its own driver details (Driver Name, Licence Number, Site Induction flag) and its own list of assigned HBLs (booking_hbl_link.truck_id). HBLs can be assigned individually or in bulk across trucks. Trucks with unresolved readiness errors or incomplete driver details are visually flagged; HBLs with unresolved errors can be removed from a truck without cancelling the booking or affecting other trucks. All trucks in a booking share ONE slot and are covered by ONE consolidated payment (BR-019 fee total across all trucks + minimum charge). The former single-driver/single-truck booking fields moved onto the truck entity.',
921description:'HBL hierarchy level is determined by the FFO flag from the EDI Requested Cargo table (BRD V2.0 §3, FR-ADM-17) — the authoritative classifier. Records WITHOUT an FFO flag are lowest-level HBLs; records WITH an FFO flag are intermediate/upper-level. hbl_level_indicator is derived from it and is THE SINGLE SWITCH selecting the release path: "lowest_level" ⇒ DO path (release_type / dos_fully_validated / do_waived; release authority via a validated DO or verified waiver, see BR-002); "intermediate" ⇒ DIGITAL RELEASE path (Phase 1 HBL summary; a detailed release_authority act log is deferred, see BR-041/OQ-069). The DO-path fields (release_type/do_waived) are evaluated ONLY for lowest-level HBLs. Where direct parent-child links are unavailable, hierarchy is reconstructed in the MuleSoft transformation layer using weight/volume/description matching with inconclusive cases flagged for manual handling (BR-034, OQ-034).',
927description:'Digital release (BRD V2.0 §3/§4.1, FR-LSP-25/26) — the INTERMEDIATE-level release path (hbl_level_indicator === "intermediate", BR-040). An LSP applies a digital release against one or more intermediate HBLs; it represents approval for goods to be released and requires NO supporting documentation. In Phase 1 this is represented through the HBL-level release_status summary; the exact update payload and stored-versus-derived mechanism remain open (OQ-071). Writing a detailed release_authority act (release flag + acting LSP + timestamp) is a deferred future design, not an initial-release API contract (OQ-069). Multiple HBLs can be batch-selected and released in a single operation; batch release executes at individual shipment level irrespective of container grouping. Digital release and delegation can be provided in the same combined flow (FR-LSP-27). For lowest-level HBLs the release path is the DO/waiver chain (BR-002), not a digital release.',
933description:'Storage-deadline warnings (BRD V2.0 §4.2, FR-LSP-35): the HBL list displays the LFD (Last Free Day) with a prominent warning indicator when the LFD is within 5 days or has already crossed, and the list is sortable by LFD so users can prioritise which HBLs to action first. During delegation, a prominent warning is shown before the user confirms if any selected HBL is at/over LFD. LFD comes from Maximus storage/LFD data; storage-fee calculation itself is out of VBS scope (the indicator only signals potential outstanding fees).',
939description:'Branch-code-to-site mapping (BRD V2.0 FR-INT-06): the pickup site for an HBL is determined using branch code as the mapping key, resolved to the corresponding ACFS physical site. Initial mapping is one FAK location per branch/state, to be validated with ACFS Operations before go-live (OQ-047).',
945description:'Session management (BRD V2.0 FR-ADM-18, §9): the system enforces session expiry after a configurable period of user inactivity. Users are prompted before session expiry and redirected to the login page on timeout. Applies to all logged-in users (LSP, ACFS Admin, ACFS User).',
951description:'Bulk LSP onboarding (BRD V2.0 §4.9, FR-ADM-19): an initial bulk import of LSP accounts can be performed via a backend process for onboarding, without individual account creation in the UI. Source data may come from Maximus, ICS-derived data, AGS exports, or business-provided datasets. Ongoing single-account creation still uses the Accounts UI (acfs:r7, BR-014).',
957description:'A truck is not book-ready until ALL of its driver/vehicle details are present: truck registration (rego), driver name, and driver licence number (BRD V2.0 §4.3, FR-LSP-30 — each truck carries rego + name + licence). This is per-truck: a booking with multiple trucks is blocked until every truck is complete, and a truck missing any of the three is visually flagged (FR-LSP-33) and can be removed without cancelling the booking (FR-LSP-31). Distinct from the site-induction acknowledgement, which is governed separately (BR-017). Driver details are entered fresh per truck per booking for Phase 1 (reuse deferred, A-025/BR-016).',
965constraint:'Driver has no portal access. Booking party manages driver communication externally.',
966type:'access',
967},
968{
969id:'C-005',
970constraint:'P4TC (one-off) has no persistent credentials. Services shipments via magic link + OTP only. No account history. No saved driver records.',
971type:'access',
972},
973{
974id:'C-006',
975constraint:'Site management is DB-seeded for Phase 1 — no admin CRUD UI. Sites have name + branch code only.',
976type:'admin',
977},
978{
979id:'C-007',
980constraint:'Desktop/laptop only. No tablet or mobile responsive design required. Portal is not meant for warehouse staff walking around — it is for counter/desk use.',
981type:'platform',
982},
983{
984id:'C-008',
985constraint:'Email is the primary notification channel. In-app notifications are available for logged-in users (LSPs, ACFS) but are not a Phase 1 blocker. P4TC (no login) receives email only.',
986type:'notification',
987},
988{
989id:'C-009',
990constraint:'Delegation chain visibility follows industry standard: hop-by-hop opacity. An LSP who delegates an HBL sees (1) who assigned it to them (upstream), (2) who they delegated it to (immediate downstream), and (3) whether the HBL reached "collected" milestone. They do NOT see multi-hop chains or booking details made by downstream parties. Exception: ACFS has full chain visibility for audit/operations. Rationale: commercial sensitivity, pricing confidentiality, liability boundaries (see knowledge base Section 5.2).',
991type:'access',
992},
993{
994id:'C-010',
995constraint:'Phase 1 delivery target is 7 weeks from build commencement (BRD V2.0 §1.6/§8.2). This governs scope-simplification decisions across the data model, integration approach, and UI/UX. Any item that cannot be delivered within this window must be explicitly deferred to a fast-follow phase. (Supersedes the earlier "8-week" framing.)',
996type:'temporal',
997},
998{
999id:'C-011',
1000constraint:'Export flow (import/export identifiers, countdown timers for drop-offs) is explicitly OUT OF SCOPE for Phase 1 (BRD V2.0 §1.4/§8.1/§8.2) and deferred to a future phase. Other deferrals reaffirmed: one-off party self-service flows, on-screen slot/site configuration modules, advanced driver/vehicle management, and expanded reporting/analytics.',
1001type:'platform',
1002},
1003{
1004id:'C-012',
1005constraint:'VBS has READ-ONLY access to Maximus (BRD V2.0 FR-INT-03, §7, §9). No write access to Maximus by default (write requires explicit approval). All Maximus reads go through MuleSoft middleware over a secure VPN (or IP whitelisting, TBC) — no direct database connection from VBS frontend or backend. Integration build uses the Maximus UAT environment until sign-off (FR-INT-04).',
1013question:'What are the confirmed milestone statuses from the client?',
1014reason:'Current list (on_vessel, at_wharf, in_yard, unpacked, collected) is based on PM knowledge. Client confirmation needed before finalising the state machine.',
1015status:'resolved',
1016resolution:'Milestone statuses confirmed: on_vessel, at_wharf, in_yard, unpacked, collected. Matches the shipment/HBL lifecycle state machine. Confirmed via Roni review (2026-06); the review status was left pending, but the milestone list is confirmed.',
1017},
1018{
1019id:'OQ-022',
1020question:'What is the full list of release types and their DO rules?',
1021reason:'Only free_release is confirmed. Need the complete list to build release-authority logic and DO validation.',
1022status:'resolved',
1023resolution:'Two release types — DO-required and free release. Free release grants release authority without a Delivery Order document. Terminology may still change (see OQ-040); the concept is providing release authority with or without documentation. Confirmed via Roni review (2026-06).',
1024},
1025{
1026id:'OQ-023',
1027question:'What is the minimum charge amount and is the rate truly flat across all scenarios?',
1028reason:'Fee formula is now: (chargeable_weight × rate) per HBL, summed + minimum charge. Rate is confirmed as a single flat value for Phase 1, but minimum charge amount is TBD. Matt mentioned rate may become per-slot or per-region in future.',
1029status:'resolved',
1030resolution:'Rate and minimum charge are backend-derived and configurable — not a user-facing config module; set at implementation time. Single flat rate for Phase 1 (chargeable_weight × rate + minimum charge — see OQ-002). Actual figures to be supplied by ACFS (Roni to follow up). Confirmed via Roni review (2026-06).',
1031},
1032{
1033id:'OQ-025',
1034question:'What is the exact definition and lifecycle of under-bond shipments?',
1035reason:'Under-bond is confirmed as a flag (not a lifecycle state) that skips DO requirements. But the full concept — triggers, verification steps, and edge cases — needs deeper clarification for implementation.',
1036status:'resolved',
1037resolution:'Under-bond is a customs-bond flag that bypasses the DO requirement. Verification is a manual, external checklist performed by the ACFS team before release — no specific in-portal process change. The flag is set manually (OQ-008). Confirmed via Roni review (2026-06). (See OQ-045 for the customs-gate interaction, still open.)',
1038},
1039{
1040id:'OQ-026',
1041question:'What is the first-time signup flow for a booking party (LSP)?',
1042reason:'March 18 flow notes "first time sign up flow of booking party — RONI TO FILL IN AND GET CONFIRMATION". This flow is undefined and pending.',
1043status:'resolved',
1044resolution:'LSP onboarding is admin-initiated only — ACFS creates the account. There is no self-registration / first-time signup flow for booking parties. Confirmed via Roni review (2026-06); supersedes the earlier "RONI TO FILL IN" note.',
1045},
1046{
1047id:'OQ-027',
1048question:'What is the P4TC email security validation process?',
1049reason:'March 18 flow notes an OE security concern: "is this a Dir confirmed email, if no SW check free for service". Need to define what validation is required before P4TC can access the portal.',
1050status:'resolved',
1051resolution:'OTP verification IS the P4TC security validation. P4TC is out of Phase 1 scope; for a future phase OTP is the security validation, with the final flow to be confirmed in a detailed ACFS discussion (next phase / fast-follow). Confirmed via Roni review (2026-06).',
1052},
1053{
1054id:'OQ-028',
1055question:'What existing HBL information is shared with P4TC on booking confirmation?',
1056reason:'March 18 flow notes "Existing HBL? (What info?)" in the P4TC booking confirmation step. Need to define what data is shown.',
1057status:'resolved',
1058resolution:'On booking confirmation P4TC sees: booking reference, slot, HBLs, fee, and site address. Detailed P4TC booking confirmation is deferred to the next phase (P4TC out of Phase 1 scope). Confirmed via Roni review (2026-06).',
1059},
1060{
1061id:'OQ-029',
1062question:'Should truck type selection happen before or after delegation for P4TC?',
1063reason:'March 18 flow notes "need to define if this step should be shown before the delegate to pick up — same to more discussion". Moot for Phase 1 since truck type was removed, but may resurface in later phases.',
1064status:'resolved',
1065resolution:'Not applicable for Phase 1 — truck type selection was removed. May resurface in a later phase. Confirmed via Roni review (2026-06).',
1066},
1067{
1068id:'OQ-030',
1069question:'What does the driver selection UX look like — dropdown, search, or both?',
1070reason:'Drivers are confirmed as account-scoped and built up organically. UX pattern (dropdown vs search by name) needs finalisation. "PH" reference from flow diagram is unclear. Scoped to Phase 2 — driver reuse is deferred (A-025), so this UX is not required for Phase 1 (drivers are entered fresh each booking).',
1071status:'resolved',
1072resolution:'No driver selection/autocomplete for Phase 1 — driver details (name, license, truck registration) are entered manually, fresh each booking. Saved-driver search/autocomplete is deferred to Phase 2 (A-025). Confirmed via Roni review (2026-06).',
1073},
1074{
1075id:'OQ-031',
1076question:'What is the ECST assignment flow?',
1077reason:'March 18 flow shows "ECST Assignment" as a distinct ACFS admin function but provides no detail on what ECST is or how assignment works.',
1078status:'resolved',
1079resolution:'ECST/ECTS assignment is parked (out of scope) for Phase 1. Confirmed via Roni review (2026-06).',
1080},
1081{
1082id:'OQ-032',
1083question:'What is the auto-WFF assignment logic?',
1084reason:'March 18 flow shows "Auto WFF Assignment?" as a decision point but does not define the rules or triggers for automatic assignment.',
1085status:'resolved',
1086resolution:'Auto-WFF assignment is out of scope for the Phase 1 frontend — assignment is manual. Roni (review 2026-06): auto-assignment of HBLs "will not be as straightforward as we hoped", so the earlier assumption no longer holds. Review status disputed — revisit if/when the assignment rules are defined.',
1087},
1088{
1089id:'OQ-034',
1090question:'What is the exact data source for HBL hierarchy relationships, per-party references, and consignee data? (BLOCKER - CRITICAL)',
1091reason:'Maximus provides individual HBL references but NOT parent-child relationships or per-party reference mappings. VBS Screen Review 2026-05-21 surfaced a deeper issue (Matt: "the $1,000,000 question, because at the moment there isn\'t [a system-wide mapping]"): each party in the delegation chain knows the same shipment by a different reference (WFF sees one ref, downstream FF sees another). AGS feed is required for: (1) HBL hierarchy (Master HBL → House HBL chain), (2) Per-party reference mapping, (3) Accurate consignee identification (account name/code) - Maximus consignee data is "too inconsistent" per Delivery meeting 2026-03-24. Welliam confirmed (2026-05-21): even with volume+weight matching, only ~70% accuracy — a reconciliation UI is needed (BR-034). Current status: Matt and William resolving integration approach; Roni promised a follow-up discovery session. Impact: data discovery blocked, HBL hierarchy blocked, per-party views blocked, auto-assignment unreliable. BRD v1.5 Section 6.2 must be updated to include AGS as integration source. Roni (review 2026-06) clarified the HBL-level semantics: the same shipment carries multiple HBL references used at different levels by different parties — the lowest-level HBL is the one used for booking pickup / delegation to the transport carrier, while the upper-level HBL is the reference the NVOCC/WFF uses to provide release authority on the goods to the downstream freight forwarder. HBL hierarchy clarification still pending. 24 Jun 2026 Data Mapping call (hierarchy/visibility deep-dive) advanced the method but did not close it: the portal transposes EdiRequestedCargo into a relationship table {primary ref, alternative ref, logistic provider}, login-scoped (each party sees the reference it issued); the parent↔lowest link is built by weight+volume matching of FFO vs blank rows (~70% reliable, manual queue for consolidations); AGS ≈ 85% of containers, ~half with an intermediary; depth 1–2 (occasionally 3). The end consignee (e.g. DATAMARS on sample TRHU2650107) does not log in — only the logistics providers do. ACFS is still pursuing a direct parent-download feed, and the consignee name→code matching rule remains undecided.',
1092status:'resolved',
1093resolution:'STILL RESOLVED as of 2026-08-20 — and the missing piece has now arrived. The DESIGN question ("each party sees the reference it issued" — how?) is answered by the architect implementation guide §15 (Confluence LCBP 2685468677 v32), which specifies the three structures it takes: a PartyAccountMapping alias layer (§15.2: RawSourceName, NormalisedName, MappedCompanyId, SourceType, Confidence, IsActive, ApprovedBy/At), a dedicated HBL relationship entity (§9.3, explicitly "rather than trying to store parent-child information only on the HBL row"), and per-party custody/visibility rows derived from the resolved hierarchy. §15.3 gives the per-party matrix outright: highest-level provider → digital release on issued upper HBLs; intermediate issuer → digital release on its issued HBL; lowest-level issuer → uploads DO, provides release authority, books pickup, OR NOMINATES ANOTHER PARTY; nominated transport carrier → books collection, may upload DO; end consignee → NO default action ("do not grant booking/release permission solely because they are consignee"). Company mapping order is settled too: L1 provider from IntOrderHd.CustomerCode FIRST, CustomerName/L1ServiceProviderName for display and fallback only, EDI ConsigneeName through an alias table because it is free-text, and AccountMappingFailed restricts risky visibility rather than guessing. THE PROBLEM IS NO LONGER DESIGN — IT IS THAT PRODUCTION IMPLEMENTS NONE OF THE THREE (see OQ-073). Original resolution, unchanged: 29 Jun 2026 — ACFS signed off the FALLBACK: DBIZ builds the hierarchy + runs the exception queue via weight+volume matching; each party sees the reference it issued; the end consignee does not log in. The direct ICS parent feed is still explored but uncertain (Matt suspects the rights to pull it may not exist) — build to the matching approach, do not wait on the feed. Matching specifics resolved: tier order does not matter (OQ-049), no aggregate matching (OQ-050 → exceptions), tolerance = 1 decimal place / ~0.1 absolute (OQ-051), ACFS admin owns the exception queue (OQ-052). 1 Jul 2026: the HBL→company mapping (accounts, email logins, consignee resolver) lives in VBS, not Maximus (little/no reusable Maximus company data). Exceptions are raised at ingestion; no write-back to Maximus (OQ-062). Composite-key + ~6.5% ICS non-match sign-off still with the ACFS Master Data team (C3).',
1094},
1095{
1096id:'OQ-035',
1097question:'Stripe or Compay for payment integration?',
1098reason:'Matt raised that most customers are already registered with Compay and suggested moving to Compay. Roni\'s team has Stripe experience but not Compay. Need business decision on payment provider.',
1099status:'resolved',
1100resolution:'Compay (managed/serviced by One Stop). Confirmed in VBS Screen Review meeting 2026-05-21 — Jason: "it has to be Compay" and "most of the carriers use Compay apparently." Jason has put in a request with One Stop for a technical resource so William and Matt can integrate. Test instance also requested. Stripe is no longer in scope for Phase 1. NOTE: BRD V2.0 (§4.3/§8.3) phrases this more loosely as "Stripe or an alternative such as Compay; final selection to be confirmed by ACFS" — the model keeps Compay as the working assumption per the 2026-05-21 review; treat V2.0\'s wording as not-yet-finalised rather than a reversal.',
1101},
1102{
1103id:'OQ-036',
1104question:'Is the heat map / density indicator required for Phase 1 MVP?',
1105reason:'Matt and Roni agreed it\'s nice-to-have and "not going to stop anything" if removed. Need to confirm priority — could be deferred to Phase 2.',
1106status:'resolved',
1107resolution:'REVERSED by BRD V2.0. The 2026-06-04 standup removed the density/heat-map for Phase 1 (Roni: "we don\'t need that density at all"). BRD V2.0 (dated 12 June, FR-LSP-14 + FR-ADM-01) REINSTATES a visual busyness heatmap indicator — shown WITHOUT revealing actual booking counts — in the inline week-by-week slot selector. Per the agreed conflict rule (V2.0 wins as the latest authority), the model reinstates the heatmap (slot.heat_map_threshold, BR-005, acfs:r3, slot-config + booking journeys). Flagged here for the team to sanity-check that the reinstatement is intended and not a carry-over the BRD author missed updating. AM/PM half-day granularity is retained. SUPERSEDED 2026-07-09: the client decided to reveal the ACTUAL truck count per slot (not just a colour band) — see OQ-065 and the FR-LSP-14 addendum. The heatmap "without revealing counts" framing no longer holds.',
1108},
1109{
1110id:'OQ-065',
1111question:'Reveal the actual number of trucks already booked per slot on the LSP slot selector — confirm the count definition and edge cases.',
1112reason:'The 2026-07-09 client decision reverses the long-standing "show busyness WITHOUT revealing actual booking counts" rule (FR-LSP-14, BR-005, OQ-036). Each slot card must now show a literal number of trucks already using that slot for the selected date. This resolves the display question but leaves the exact count semantics to confirm, and it reopens the privacy rationale that originally motivated hiding counts.',
1113status:'resolved',
1114resolution:'DECISION (client, 2026-07-09): reveal the actual truck count per slot/date on the LSP booking slot selector. Implemented as slot.booked_truck_count (derived, per (slot, date)) surfaced via GET /api/slots/available; FR-LSP-14 gains an addendum; BR-005, acfs:r3, lsp:r4, the slot entity and both slot journeys updated; heat_map_threshold demoted to an optional colour band. WORKING DEFINITIONS applied (confirm with Roni/Matt): (1) COUNT = SUM(bookings.truck_count) over bookings on that slot_id + slot_date, i.e. trucks not bookings, so a multi-truck booking contributes all its trucks (BR-039). (2) STATUS FILTER = exclude \'draft\' and \'cancelled\'; count \'open\'/\'processed\'/\'complete\'. (3) "OTHER" trucks = total across all parties; the endpoint accepts exclude_booking_id so an in-progress edit can subtract its own booking. (4) NO per-party / per-company breakdown is exposed — only the aggregate number (avoids leaking who booked). OPEN sub-points to confirm: whether draft/in-progress bookings should count toward the number; whether the count should be capped/hidden above some value; and whether revealing counts is acceptable to all LSP tenants now that the original privacy rationale (OQ-036) is being reversed.',
1115},
1116{
1117id:'OQ-037',
1118question:'What are the detailed field requirements for the DO validation and pickup verification views?',
1119reason:'Meeting ran out of time at this point. Roni and Matt agreed to continue in the next session covering DO validation details, pickup verification flow, and user management.',
1120status:'resolved',
1121resolution:'Field requirements for DO validation and pickup verification are defined by the current ACFS UI designs — there are no special DO-validation fields; the actions to mark a DO valid or flag it are already covered in the designs. Confirmed via Roni review (2026-06).',
1122},
1123{
1124id:'OQ-038',
1125question:'How frequently does Maximus update customs clearance status from ICS?',
1126reason:'Customs clearance (including quarantine) is a booking prerequisite. Matt noted the update frequency from ICS is unclear — affects how stale the data might be at booking time.',
1127status:'resolved',
1128resolution:'The frontend displays customs clearance status from the API; sync/staleness frequency is a backend integration concern (to be covered in the Data Mapping workshop), not a frontend choice. Confirmed via Roni review (2026-06).',
1129},
1130{
1131id:'OQ-039',
1132question:'What is the external user booking modification flow?',
1133reason:'Rules are defined (BR-015) but the UI flow for external users modifying their own bookings was not fully designed in the meeting. Roni noted he would add this to the Miro board.',
1134status:'resolved',
1135resolution:'External/LSP booking modification reuses the admin bookings UI (resolved v0.6.0 — My Bookings reuses the ACFS bookings list/detail component, BR-030). Confirmed via Roni review (2026-06).',
1136},
1137{
1138id:'OQ-040',
1139question:'Is "free_release" the right name, and what scenarios does it actually cover?',
1140reason:'VBS Screen Review 2026-05-21 — Matt: "it\'s not, and it\'s maybe just not pre-release. There\'s certain scenarios that don\'t follow the norm where we want to... we\'re happy to let those goods go without, you know, for whatever reason." The current free_release flag is being used as a catch-all for multiple off-norm release scenarios. Need to confirm: (a) the canonical name, (b) the full list of scenarios, (c) whether each scenario should be a distinct flag or all collapse into one. Matt to clarify with stakeholders.',
1141status:'resolved',
1142resolution:'Free release covers movement of shipments that do not require a document to be uploaded and can be picked up without a Delivery Order. A terminology change has been advised by the ACFS team but is not yet confirmed — keep "free_release" until ACFS confirms a new name. Scenario scope confirmed via Roni review (2026-06); the canonical name is still pending ACFS.',
1143},
1144{
1145id:'OQ-041',
1146question:'Should LSPs be able to request a free release from within the portal, or stay offline?',
1147reason:'VBS Screen Review 2026-05-21 — Matt was uncertain: "whether it\'s something they can request within the platform, and then we verify that that\'s a legitimate case, or whether we go down the other things it\'s done off platform when we just verified." Agreed it\'s an edge case for Phase 1 and to keep it offline for now, but flagged for future revisit if volume justifies in-portal request flow.',
1148status:'resolved',
1149resolution:'LSP free-release requests stay offline for Phase 1. The request is an offline action; during delegation to the transport carrier the LSP can mark it as a free release (indicating no DO is required) while booking a pickup. NB: "mark" here means the LSP signals free-release intent via the offline request — it does NOT let the LSP self-set the flag. free_release remains ACFS-only and ACFS-verified (BR-002, release_type field); the LSP delegation/booking flow does not set free_release_verified. Confirmed via Roni review (2026-06).',
1150},
1151{
1152id:'OQ-042',
1153question:'How should volumetric/quantity changes via ACFS amendment be handled — fee or no fee?',
1154reason:'VBS Screen Review 2026-05-21 — Jason argued a volume increase (e.g. 3 → 4 pallets) "definitely will be a fee" using the same chargeable_weight × rate formula. Matt argued Phase 1 should keep all ACFS amendments fee-free in the portal and collect any difference off-system. Parked for Phase 1 with BR-036 (fee-free). Needs business decision (Diane, Daniela) before Phase 2 to determine in-portal surcharge requirement. Roni (review 2026-06): the Phase 1 proposal is that booking changes (HBL removal/addition) are performed by the ACFS admin, fee-free. There is in-principle agreement to the proposal, but it is likely to change once other business stakeholders are involved; currently superseded by other priorities.',
1155status:'resolved',
1156resolution:'29 Jun 2026 — payment/state is tracked at the HOUSE-BILL level: each truck = one booking, a paid HBL can move between trucks freely, and ADDING an HBL incurs an additional fee. Make changes at HBL level, not transaction level. Phase-1 ACFS amendments remain fee-free in the portal (BR-036), with any difference settled offline; an in-portal surcharge is a Phase-2 business decision.',
1157},
1158{
1159id:'OQ-043',
1160question:'Should container-level bulk delegation (select containers → delegate all child HBLs) be supported, and for whom?',
1161reason:'VBS daily standup 2026-06-04 — Matt noted AGS (wholesale freight forwarder) works at container level and would delegate whole containers at once (e.g. 3 containers = 45 shipments to DHL in one action). Roni judged this AGS-specific ("the way AGS works, not the rest of the people") and deferred it: day one is just a container reference column + sort + accordion grouping by container; shipment-level multi-select delegation remains the generic path. Revisit once AGS\'s delegation logic is understood post-launch.',
1162status:'resolved',
1163resolution:'29 Jun 2026 — NOT deferred; Matt wants it in Phase 1, implemented simply as two switchable HBL-list views: (a) grouped by container (collapsible; mass-select-all then deselect — not an atomic action) for AGS/L1 who process whole containers, and (b) grouped by milestone status (reverse-chronological) for lowest-level parties working across containers. "Group by container" can be as simple as sorting in container order.',
1164},
1165{
1166id:'OQ-044',
1167question:'Can ACFS mark an HBL as free release from the shipments module, or only via the booking/DO flow?',
1168reason:'VBS daily standup 2026-06-04 — Roni was unsure whether the ACFS shipments view should expose a free-release marking action and said he\'d check with the client. Relates to OQ-040 (free_release naming/scenarios) and OQ-041 (in-portal vs offline free-release request). free_release is ACFS-only and verified (BR-002); the open part is which screen exposes the action. 29 Jun 2026: confirmed free-release marking is an ELEVATED / restricted action (heavy legal/fines exposure, very few users) — the firm requirement is tight access control on the action; the exact screen placement is still TBD.',
1169status:'open',
1170},
1171{
1172id:'OQ-045',
1173question:'Does a verified under-bond movement permission fully substitute for customs clearance at the booking gate?',
1174reason:'Under-bond goods move between bonded facilities BEFORE customs clearance, yet the booking gate requires "fully customs cleared". Taken literally these contradict — an under-bond HBL could never be booked. The model now ASSUMES under_bond_verified substitutes for the customs-cleared check at booking (the movement permission replaces both the DO requirement AND the customs gate for that movement) — see BR-001. Confirm with ACFS/Matt that under-bond pickups are bookable on a verified movement permission alone, and whether any partial/quarantine customs state should still block them.',
1175status:'resolved',
1176resolution:'29 Jun 2026 — YES, handled as a MANUAL ACFS-admin exception override (elevated role). It waives the release-authority requirement ONLY; the standard gate (unpacked + customs cleared) still applies. New admin-UI build item; detail deferred.',
1177},
1178{
1179id:'OQ-046',
1180question:'How will the concurrent Maximus Azure migration affect the real-time MuleSoft integration, and what is the go/no-go gate?',
1181reason:'BRD V2.0 (§7.6/§8.3/§10) flags that Maximus is undergoing an Azure migration concurrent with the 7-week Phase 1 build. Schema and connectivity may change mid-build, risking integration delays or rework. V2.0 calls for a clear go/no-go gate tied to integration readiness before committing to a go-live date, and confirmation of the migration schedule/impact on API availability before the integration build commences. Owner: ACFS IT / Maximus Product Owner.',
1182status:'resolved',
1183resolution:'29 Jun 2026 — Matt frames the Azure migration as a source-swap ("bolt the hosepipe off one and onto another") with no schema change expected, so integration risk is LOW. Still get the cutover date for the timeline, but the break-mid-build fear is downgraded.',
1184},
1185{
1186id:'OQ-047',
1187question:'Is the branch-code-to-site mapping one FAK location per branch/state, and is it validated with ACFS Operations?',
1188reason:'BRD V2.0 (FR-INT-06, BR-043) sets pickup-site resolution by branch code, with an initial mapping of one FAK location per branch/state "to be validated with ACFS Operations before go-live". Need the confirmed branch→site table and validation sign-off.',
1189status:'resolved',
1190resolution:'29 Jun 2026 — pickup site = branch code + site code together (use both). Definitive. New sites simply add another option to the location dropdown.',
1191},
1192{
1193id:'OQ-048',
1194question:'What are the exact semantics of bulk delegation to multiple recipients (FR-LSP-34)?',
1195reason:'BRD V2.0 §4.2/FR-LSP-34 says the LSP can "search for and assign multiple recipients within a single delegation flow, delegating selected HBLs to all nominated recipients in one operation." Read literally this fans the SAME HBLs out to multiple recipients, which is semantically odd (an HBL has a single next hop). More likely the intent is: within one flow, assign different HBLs to different recipients (a batch with per-selection targets). This also reverses the 2026-06-04 standup single-recipient-dropdown decision (now applied per the V2.0-wins conflict rule). Clarify the precise interaction model before building the delegation UI.',
1196status:'resolved',
1197resolution:'29 Jun 2026 — delegation transfers the ABILITY TO BOOK A PICKUP only (never release authority). One shipment → one party; you can batch many shipments to one party in a single flow (NOT one shipment fanned out to many). Redelegation is allowed. A delegated party may upload a DO/date, but ACFS must validate it.',
1198},
1199{
1200id:'OQ-060',
1201question:'How is a scheduled Maximus re-pull reconciled against manual ACFS-admin corrections so it does not overwrite them?',
1202reason:'NEW (29 Jun / 1 Jul 2026). ICS data often arrives late or gets re-pulled, so a scheduled re-pull can land AFTER an ACFS admin has manually corrected or processed a container and silently overwrite that work. Today in Maximus a re-pull simply overwrites. No reconciliation/merge-protect rule for VBS-side edits vs incoming Maximus data has been agreed — Matt: "we might have to look into that... might not know until we put it into practice." VBS is a non-destructive superset (no write-back to Maximus, OQ-062), which makes the protect-VBS-edits rule the crux.',
1203status:'open',
1204},
1205{
1206id:'OQ-063',
1207question:'What drives incremental sync — is there a change-detection field/watermark, and how are insert-only and deleted records handled?',
1208reason:'NEW (1 Jul 2026). The hourly scheduler needs to pull only changed records, but no master-level "changed" flag/watermark was found: child-table changes (EDI, cargo hold) do not surface on IntOrderHD, and EdiRequestedCargo is insert-only (a change writes a NEW record, though it carries a confirmed lastModifiedDate). The full pull is ~2.5M records, so a watermark / insert-vs-update / delete strategy is needed (interim: last-one-month filter). Owner Matt → Jason/William. Underpins OQ-059 (volume filter) and OQ-060 (overwrite). Also OQ-064: no rules yet for which tables to re-read per milestone on re-pull (Jason + William). 10 Jul: raw pull lands in OutSystems staging (matching runs OutSystems-side, not in Mule); Welliam suggested IntActivity as a lighter milestone source than parsing 30M-row EDICommon XML — but change-detection itself is still unsolved.',
1209status:'open',
1210},
1211{
1212id:'OQ-059',
1213question:'What is the exact filter/criteria for the order pull, so the sync does not push stale/completed shipments?',
1214reason:'NEW (29 Jun / 1 Jul 2026). The full order pull is ~2.5M records (larger than the earlier 100k–200k estimate). An active-set filter (e.g. start from tally-in; exclude collected/completed) is needed but not yet defined. Interim: a last-one-month filter (approved) to populate dev/test; the final production filter is still with Matt. 10 Jul: the raw pull lands in OutSystems staging tables and the original ~14-table mega-join was split into order/cargo/container + milestone/hold/activity pulls for performance — but the record-selection criteria remain undefined. Owner: Matt. Ties to OQ-063 (change-detection) and OQ-067 (full-dataset refresh).',
1215status:'open',
1216},
1217{
1218id:'OQ-064',
1219question:'Which tables must be re-read for each milestone when a record changes on an incremental re-pull?',
1220reason:'NEW (1 Jul 2026). Each milestone updates in different child tables that are NOT reflected on the IntOrderHD pull, and no rules exist for which tables to re-read per milestone on re-pull. Without this map the incremental sync cannot keep milestones current after the initial pull. Owner: Jason + William. Ties to OQ-063.',
1221status:'open',
1222},
1223{
1224id:'OQ-067',
1225question:'Is there an identifier to fetch a single Order/Container/HBL, or must manual refresh and the hourly scheduler share one API returning the full eligible dataset?',
1226reason:'NEW (1 Jul 2026). VBS has no confirmed key to fetch a single affected record, so the manual refresh (FR-ADM-16) and the hourly scheduler may have to share one API that returns the COMPLETE eligible dataset. Combined with ~2.5M EDI rows and no master change-tracking on IntOrderHd (OQ-063), this is an execution-time/memory risk on both refresh and sync. Owner: DBIZ + ACFS.',
1227status:'open',
1228},
1229{
1230id:'OQ-068',
1231question:'How should the HBL view display release-authority status across MULTIPLE parties — who has/has not released, and what is missing?',
1232reason:'NEW (10 Jul 2026 integration call, Matt). All mockups to date are from a single provider\'s lens. When a shipment needs releases from multiple parties across the chain, a nominated booker cannot currently tell who has vs has not provided their release, or what is outstanding (which party still owes a digital release or DO). Release is already a standalone attribute (separate from DO upload) with a per-HBL history timeline; the gap is a clear per-party/per-tier release breakdown in the HBL detail view, with the same shipment showing each party its own relevant reference. DBIZ to produce a dedicated multi-party mockup. Open design point: whether 3+ tiers need additional columns. See the release_status field and the party_references field.',
1233status:'resolved',
1234resolution:'18 Jul 2026 — INITIAL RELEASE SCOPE: show only the single HBL-level release_status and single DO-document status needed to complete the one-tier/one-DO cycle. Do not build the per-party/per-tier breakdown or multiple-DO summary in Phase 1. Roni confirmed that the richer release_authority entity, multiple-DO representation, and aggregation back into the HBL are a future pass. This resolves the initial-release decision by deferral; the future detailed design remains intentionally out of scope rather than implicitly solved.',
1235},
1236{
1237id:'OQ-069',
1238question:'Does the DO-based release path write a "do_based" release_authority record, or does release_authorities only log digital-release acts?',
1239reason:'NEW (17 Jul 2026, surfaced while tracing the release write path). The release_authority entity is described as the authoritative LOG of release-authority acts and defines release_mechanism = "do_based" for lowest-level HBLs. But the documented derivation of hbl.release_status for LOWEST-level HBLs reads dos_fully_validated / do_waived and never consults release_authorities — so nothing in the model requires a do_based row to exist, and the enum value is currently unreachable. Two coherent readings: (a) release_authorities logs BOTH paths, so validating the last required DO (or verifying a waiver) must also insert a do_based row — making it a genuine single source of release acts; or (b) release_authorities covers only the digital-release path, in which case do_based should be dropped from the release_mechanism enum and the entity rescoped to say so. This directly affects OQ-068: a per-party/per-tier "who has released" breakdown is far simpler to build against one act log than against a union of release_authorities + delivery_orders + per-HBL waiver flags. Touches the release_authority entity, the release_mechanism enum (acfs-production-schema.dbml), and BR-041. Owner: Roni/Matt.',
1240status:'resolved',
1241resolution:'18 Jul 2026 — NO for the initial release: validating a DO or verifying a DO waiver does not write a "do_based" release_authority row. No release_authority API/write path has been implemented; Phase 1 works with the HBL-level release_status plus a single DO-document status. Keep release_authority and the "do_based" mechanism only as a clearly deferred target design for the future multi-party/multiple-DO pass, not as an active Phase 1 contract.',
1242},
1243{
1244id:'OQ-070',
1245question:'What is the exact Phase 1 single-enum contract for DO-document status on an HBL — field name, allowed values, and transition meanings?',
1246reason:'NEW (18 Jul 2026, Roni follow-up). Phase 1 is expected to expose one summarized DO-document status on the HBL rather than the future multiple-DO breakdown, but the API contract is not yet confirmed. Candidate states seen across the model/front end include not_provided, uploaded, pending_validation, flagged, validated, and not_required; it is unclear which subset the HBL update API accepts/returns, whether uploaded and pending_validation are distinct, and how free-release/override is represented. Jewel/Jaffar to confirm the exact backend field name, enum values, and transitions before the HBL update API and generated schema are changed.',
1247status:'open',
1248},
1249{
1250id:'OQ-071',
1251question:'For Phase 1, is hbl.release_status directly writable through the HBL update API, or read-only and derived from digital-release/DO state?',
1252reason:'NEW (18 Jul 2026, 17 Jul HBL update API meeting). Roni proposed using release_status and the DO-document attribute directly on the HBL for the first pass, and the backend team plans to expand the currently incomplete HBL update API. That does not settle whether callers set release_status explicitly or update the underlying DO/digital-release state and let the backend derive the summary. The current model historically calls release_status derived, while the meeting language about "updating the status of an HBL" could imply a writable field. Jewel/Jaffar to confirm the write contract and source-of-truth rule before API regeneration.',
1253status:'open',
1254},
1255
1256// --- Resolved (decision log, kept for traceability) ---
1257{
1258id:'OQ-001',
1259question:'How is Tier-2 FF data sourced? Are they registered in Maximus or only in the portal?',
1260reason:'Delegation flow depends on knowing which LSPs exist in the system.',
1261status:'resolved',
1262resolution:'Global registry maintained by ACFS. One-time bulk upload from AGS portal/party manager into the portal local DB. No Maximus sync. LSP manually assigns delegate per HBL via delegation.',
1263},
1264{
1265id:'OQ-002',
1266question:'What is the exact fee method — flat rate per HBL or percentage of declared value?',
1267reason:'Fee calculation logic in the booking flow depends on this decision.',
1268status:'resolved',
1269resolution:'Chargeable weight (max of weight vs volume) per HBL × rate (single flat value) + minimum charge. Rate is a single configurable value for Phase 1. Per Roni/Matt meeting 2026-03-18.',
1270},
1271{
1272id:'OQ-003',
1273question:'Can an LSP both delegate and book directly on the same HBL?',
1274reason:'Determines whether the UI allows both actions or enforces mutual exclusivity per HBL.',
1275status:'resolved',
1276resolution:'Either/or per HBL. LSP either delegates or books directly — never both on the same HBL.',
1277},
1278{
1279id:'OQ-004',
1280question:'How do delegated parties (P4TC) authenticate?',
1283resolution:'Magic link + OTP for P4TC. Secure link sent to nominated email on delegation. OTP verification. No account creation. Portal access scoped to assigned shipments only.',
1284},
1285{
1286id:'OQ-005',
1287question:'Does the one-off customer (P4TC) get a dashboard or booking history?',
1288reason:'Affects whether P4TC users need persistent state or session-only access.',
1289status:'resolved',
1290resolution:'No dashboard. No account, no history. Link expires when shipment is collected. Repeat users should be onboarded as a proper LSP.',
1291},
1292{
1293id:'OQ-006',
1294question:'How fresh is the data from Maximus?',
1295reason:'Determines whether UI needs real-time indicators or can rely on periodic state.',
1296status:'resolved',
1297resolution:'SUPERSEDED by BRD V2.0 (§6.2/§7.3, FR-ADM-16). Original Phase-1 answer was periodic batch (once or twice daily, no real-time). BRD V2.0 replaces this with a REAL-TIME MuleSoft model: data is fetched on each page load of relevant views and on manual refresh, with no periodic batch sync. See integration_maximus and BR-010.',
1298},
1299{
1300id:'OQ-007',
1301question:'Can an HBL skip delegation and go straight from unpacked to booked?',
1302reason:'Affects state machine transitions and whether delegation is a required step.',
1303status:'resolved',
1304resolution:'Always valid. LSP can book directly without delegating. No precondition on delegation.',
1305},
1306{
1307id:'OQ-008',
1308question:'How does the portal know an HBL is under-bond?',
1309reason:'Determines whether under-bond status is synced from Maximus or manually flagged.',
1310status:'resolved',
1311resolution:'Manual flag set by LSP or ACFS staff in the portal. Not synced from Maximus.',
1312},
1313{
1314id:'OQ-009',
1315question:'What is the multi-level DO hierarchy — does it cascade or is each level independent?',
1316reason:'Determines upload UX and validation logic for delivery orders.',
1317status:'resolved',
1318resolution:'Both: uploads are per-tier (each party uploads its own DO — not auto-copied), BUT the requirement cascades — a child HBL\'s required DO set = its own DO + all ancestor-tier DOs. Clarified at VBS daily standup 2026-06-04 (driver for HBL3 carries DO3 + DO1; shipment 2 needs DO + DO2; shipment 3 needs DO + DO3) and confirmed by BRD v1.6 Addendum 1 (release-authority chain: each party validates the next lower level + provides a Digital Release Authority; a shipment needs a release from all parties). This refines the earlier "no inheritance" note — the *uploads* don\'t inherit, the *requirement* does. Free release removes the DO requirement for that tier. See BR-002.',
1319},
1320{
1321id:'OQ-010',
1322question:'What are the ACFS override rules for missing DOs?',
1323reason:'Determines role restrictions, audit requirements, and override lifecycle.',
1324status:'resolved',
1325resolution:'Only ACFS Admin role can override. Audit trail with reason is required. Override is one-time per HBL and lives until the HBL is collected.',
1326},
1327{
1328id:'OQ-011',
1329question:'Can HBLs from different LSPs be combined in one booking?',
1330reason:'Affects booking selection UI and potentially the auth model.',
1331status:'resolved',
1332resolution:'Yes. HBLs from different LSPs can be combined into a single booking.',
1333},
1334{
1335id:'OQ-012',
1336question:'What payment integration is expected for Phase 1?',
1337reason:'Determines whether to build a custom payment UI or embed a third-party checkout.',
1338status:'resolved',
1339resolution:'Stripe embedded checkout for Phase 1. Compay is a potential alternative (OQ-035). (SUPERSEDED by OQ-035 — Phase 1 payment is Compay, managed by One Stop; Stripe is no longer in scope.)',
1340},
1341{
1342id:'OQ-013',
1343question:'How are refunds handled?',
1344reason:'Determines whether the portal needs refund state, UI, or processing.',
1345status:'resolved',
1346resolution:'Completely outside the portal. Refund-agnostic. Handled offline by ACFS.',
1347},
1348{
1349id:'OQ-014',
1350question:'What are the booking and change cut-off rules?',
1351reason:'Determines slot configuration UI and booking validation logic.',
1352status:'resolved',
1353resolution:'Cutoffs are relative day + time per slot template (e.g. "previous working day, 4 PM"). Booking cutoff and change cutoff configured separately. Per-site configuration. Updated from absolute to relative per Roni/Matt meeting 2026-03-18.',
1354},
1355{
1356id:'OQ-015',
1357question:'What does the ACFS processing workflow look like?',
1358reason:'Determines the ops dashboard layout, queue structure, and validation sequence.',
1359status:'resolved',
1360resolution:'Search bookings → view details + DO + audit tracking → validate or reject → mark "processed". Partial processing supported. HBL data is fetched from Maximus in real time via MuleSoft on view load (BR-010; supersedes the earlier "7 days before vessel via Maximus batch" framing). DO validation is a separate flow from pickup verification. (Booking status names use BRD V2.0 §6.1/§4.7 — Open / Processed / Complete; the 2026-06-04 standup\'s "ready to collect" was reverted to "processed" in v0.14.0 — see booking lifecycle.)',
1361},
1362{
1363id:'OQ-016',
1364question:'What slot configuration options does ACFS need?',
1365reason:'Determines the admin configuration UI for pickup windows.',
1366status:'resolved',
1367resolution:'Select site → select days of week → configure AM/PM half-day slots → configure booking/change cutoff (relative day + time) → holiday calendar overlay. No truck type distinction for Phase 1. (Superseded 2026-06-04: AM/PM granularity instead of arbitrary hourly start/end; heat-map threshold removed — see OQ-036.)',
1368},
1369{
1370id:'OQ-017',
1371question:'What does FOC rebooking look like?',
1372reason:'Determines whether free rebooking needs a separate flow or is an admin override.',
1373status:'resolved',
1374resolution:'ACFS admin only. Overrides all fees. Reason/justification required for audit trail.',
1375},
1376{
1377id:'OQ-018',
1378question:'Single app with role-based routing or separate apps per actor?',
1379reason:'Determines deployment architecture, routing strategy, and shared component scope.',
1380status:'resolved',
1381resolution:'Single app with role-based routing.',
1382},
1383{
1384id:'OQ-019',
1385question:'What is the auth strategy across all actor types?',
1386reason:'Determines auth implementation, session management, and middleware design.',
1387status:'resolved',
1388resolution:'LSP: username/password (created by ACFS admin). P4TC: magic link + OTP (no account). ACFS Internal: SSO-based access. Driver: no portal auth (no system emails). (The former separate "Gatehouse" actor was retired in v0.14.0 — no BRD references it; gate-side verification is covered by ACFS Pickup Verification, acfs:r6.)',
1389},
1390{
1391id:'OQ-020',
1392question:'What happens when an LSP requests a missing HBL be added?',
1393reason:'Determines whether a request flow is needed or just search.',
1394status:'resolved',
1395resolution:'No request flow exists. LSP can search by HBL only. Missing HBL requests are not part of the BRD or Phase 1 scope.',
1396},
1397{
1398id:'OQ-024',
1399question:'Will the auth model for delegated parties change from magic links to a persistent login?',
1400reason:'Cross-LSP booking requires parties to see HBLs from multiple delegations. Magic links are scoped to a single delegation.',
1401status:'resolved',
1402resolution:'March 18 flow clarifies: LSPs have persistent login (username/password). Only P4TC (one-off) uses magic link + OTP. This resolves the cross-delegation visibility concern for registered LSPs.',
1403},
1404{
1405id:'OQ-033',
1406question:'Is ACFS Internal auth SSO (OAuth/Okta) or portal-native (username/password)?',
1407reason:'v0.2.0 had SSO, v0.3.0 changed to username/password without clear meeting discussion.',
1408status:'resolved',
1409resolution:'SSO-based access. Confirmed by March 18 Miro board — user management section shows "ACFS USER DETAILS: SSO BASED ACCESS" for ACFS users, while LSP users get "USERNAME + PASSWORD BASED ACCESS".',
1410},
1411{
1412id:'OQ-072',
1413question:'Are "custody delegation" and "carrier nomination" one action or two? VBPP-226 gives DELEGATION to the intermediate HBL holder and BOOKING to the lowest-level holder; Matt Drake\'s UAT note says "only lowest level HBL issuers should be able to delegate a pickup" — the opposite assignment for delegation.',
1414reason:'The two statements only reconcile if there are two distinct actions sharing one name: an intermediate FF passing accountability DOWN the chain (what the delegation entity models today), versus the lowest-level holder nominating a TRANSPORT CARRIER to collect on its behalf. Confluence LCBP 2715320321 supports the split by listing "Book Pickup Or Nominate another Party" as one choice belonging to the party that would otherwise book. If they are two actions, the model has one entity where the business has two, BR-004\'s delegate-or-book exclusivity is wrong for the nomination case, and the Delegated tab is conflating both under one label. Every open DO-counting question (OQ-075) depends on this, because "delegation hop" denotes something different under each reading. EVIDENCE ADDED 2026-08-20 — the two-action reading is now backed by THREE independent sources against VBPP-226\'s single bullet. The architect implementation guide §15.3 (LCBP 2685468677 v32) tabulates it explicitly: the LOWEST-LEVEL ISSUER "uploads DO, provides release authority, books pickup, OR NOMINATES ANOTHER PARTY", the nominated transport carrier "books collection and may upload DO", and the guide instructs "model nomination/delegation SEPARATELY from release authority". The intermediate issuer\'s only listed action is "must provide digital release for its issued HBL" — no delegation. That matches Matt\'s UAT rule and Roles & Functions ("Book Pickup Or Nominate another Party"). RECOMMENDATION: adopt the two-action split, and correct VBPP-226 BR-2, which grants delegation to the intermediate holder and is the outlier. Left open because rewriting a rule already specified in a Jira story is Roni\'s call, not a documentation fix. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source): the build does NOT implement the two-action split, and the API does not encode it either. The live delegation surface is /vbs-delegate (it calls the real createDelegation service); note src/components/lsp/lsp-delegate-panel/ is ORPHANED prototype code running on mock-data imports and is not routed from any page, so it should not be read as evidence of anything. In the live flow the create payload hardcodes delegation_method: 0 and the service type documents that enum as "0 = existing_lsp, 1 = one_off_p4tc" (services/vbs/delegations.ts). That enum distinguishes RECIPIENT TYPE (an existing LSP account versus a one-off party-to-collect), NOT custody-delegation versus carrier-nomination, so the production API has no field in which the OQ-072 distinction could currently be recorded. There is also NO HBL-level gate anywhere in the delegate flow: nothing checks intermediate versus lowest-level before allowing delegation, so today any holder may delegate any shipment. One historical signal worth knowing when deciding: use-delegate-state.ts carries a per-recipient method of "delegate" or "release" and a page-level mode frozen to "delegate", with the comment "the old Delegate/Release toggle was removed". So the UI once distinguished 2 modes at page level and was deliberately collapsed to one. Adopting the two-action split therefore needs a backend field as well as a UI change; it is not a relabelling. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): the backend confirms the single-action build from its side. HBLCustodyChain.DelegationMethod records RECIPIENT TYPE only, existing_lsp (1) or one_off_p4tc (2); no attribute records whether a hop is an intermediate\'s custody handover or a lowest-level holder\'s carrier nomination, and both kinds of hop are stored identically and both increment ExpectedDOCount, since that count is a plain row count over active hops. No HBL-level gate exists in the backend either: any holder may delegate any of their HBLs to any company, and the resulting hop is written without reference to HBLLevelIndicator. So the earlier conclusion stands with backend confirmation: adopting the 2-action split needs a new backend attribute (action type on the hop) plus a delegation gate, not a relabelling. The decision remains with Roni.',
1415status:'open',
1416},
1417{
1418id:'OQ-073',
1419question:'Is fixing per-party HBL reference visibility in R2 scope? Every party currently sees the LOWEST-LEVEL HBL reference and the END consignee rather than their own.',
1420reason:'This is OQ-034 / hbl.party_references reaching production unresolved — the design was open, and the build shipped the default. Matt\'s 19 Aug UAT confirms the consequences: as AGS he saw only 8 of 17 shipments in container CSLU2245875 and none of his own references or consignees; as ACFS he saw 12 DUPLICATE rows generated from intermediate references with no indication who the primary customer or intermediates are; as Expeditors he saw none of the 3 shipments where Expeditors is an interested party and must upload a DO. His words: "there does not appear to be any mechanism to link intermediate HBL references to the primary shipment using the lowest-level HBLs". AGS is 85% of container unpacks (LCBP 2726133761), so this is the difference between the portal being usable by its primary customer and not. DIAGNOSIS SHARPENED 2026-08-20 — this is an IMPLEMENTATION gap, not a design gap. OQ-034 is resolved and the architect guide §15/§9.3 specifies the mechanism in full; production implements none of the three structures it calls for. (1) No relationship entity — parent_hbl_id/relationship_type/match_level are collapsed onto the HBLS row, so there is no IsActive to correct a link without losing history and no MatchNotes to explain a block (§9.3, OQ-081). (2) No PartyAccountMapping table — no alias, confidence, or approval layer, which is what the guide requires because EDI ConsigneeName is free-text and inconsistent (§15.2). (3) No per-party visibility rows. AND THE LIKELY ROOT CAUSE: the party that ISSUED an HBL reference is not stored on the HBL row at all. HBLS carries AssignedCompanyId — documented in the field mapping as "resolved consignee company from consigneeName", i.e. ONE company per row, the consignee — plus the undocumented ParentCompanyId. The issuing L1 provider is resolved from IntOrderHd.CustomerCode, which is ORDER/CONTAINER-level, not per-HBL. So visibility can only be computed from consignee, and AGS is an ISSUER rather than a consignee on its own upper-level rows — which is exactly why it drops out of the result set while its rows demonstrably exist (Matt saw them as ACFS, as 12 duplicates). If that holds, no query fix reaches it; a per-HBL issuer/visibility structure has to exist first. PARTLY ANSWERED BY JEWEL, 2026-08-20: "logged in user should belongs to this ParentCompanyId. then only he can see that hbl." So ParentCompanyId IS the visibility key — the company whose users may see that HBL row. My "issuer not stored" framing was therefore too pessimistic: per-party visibility IS partly implemented, and this is closer to a display bug than a missing structure. THE LIKELY REMAINING FAULT: the visibility key attaches a party to the row it can see, but the portal then renders THAT ROW\'S OWN reference and consignee. On a child (lowest-level) row whose ParentCompanyId points at AGS, AGS is correctly granted visibility and then shown the CHILD\'s HBL number and the child\'s consignee, which is the end importer — exactly Matt\'s complaint ("always showing the Lowest-Level HBL references and Consignees, not AGS relevant information"). The data to fix it exists: parent_hbl_id resolves to the parent HBLS row, which carries the reference and consignee AGS actually issued. And the 8-of-17 shortfall is consistent with ParentCompanyId only being populated where hierarchy matching resolved a parent (BR-034 bands), leaving unmatched children invisible to the upper-level party. STILL TO CONFIRM: (a) is ParentCompanyId set on the CHILD row, the PARENT row, or both; (b) is it populated only on a successful match; (c) how is a party linked when relationship_type is NO_PARENT. Jewel also confirmed HBLCustodyChain rows are inserted only when an HBL is delegated, so custody is not the visibility path for undelegated shipments. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source): the display-side fix is unbuilt too, so this is a two-sided gap rather than a backend query bug. All 7 hierarchy fields (ParentHBLId, ParentCompanyId, RelationshipTypeId, MatchLevelId, NeedsManualReview, IsManunallyUpdated [sic], Exceptionid [sic]) are declared in the API response types (services/vbs/shipments.ts, delivery.ts) and are then read by NOTHING anywhere in the application. Both HBL adapters (lib/vbs-hbl-adapter.ts for the LSP side, app/acfs/shipments/_lib/shipment.adapters.ts for the ACFS side) resolve the displayed reference as HBLNumber then AltHBLReference then Description, and the consignee straight from the row\'s own ConsigneeName, with no parent lookup on either side. So even if ParentCompanyId grants the right party sight of the right row, no code path exists that would render the parent\'s reference to that party. CONSEQUENCE FOR SEQUENCING: the display fix is independent of the backend visibility question and can proceed in parallel, since parent_hbl_id already resolves to the row carrying the reference and consignee the upper-level party issued. SEE ALSO the level-wiring defect recorded on OQ-077, which blocks the related intermediate-versus-lowest-level behaviour. BACKEND AS-BUILT ANSWERS 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): all 3 STILL TO CONFIRM items are now answered, and the remaining fault is confirmed display-side. (a) ParentCompanyId is written on EVERY HBL, at 2 points: at staging insert it is assigned from the container\'s L1ServiceProviderName regardless of FFOFlag, then hierarchy mapping refines lower-level rows to the parent HBL\'s AssignedCompanyId once a parent resolves. The result is a single-hop chain of sight: the L1 service provider sees the upper-level references it issued, and the issuer of each upper-level reference sees the lower-level references beneath it, with no level filter applied at any point. (b) Not match-gated at insert, BUT where hierarchy mapping resolves no parent, ParentCompanyId becomes 0 and the row is visible to ACFS ONLY until ACFS manually assigns the LSP, and no review screen exists to surface such rows (OQ-081). That is a confirmed mechanism for Matt\'s 8-of-17 shortfall, alongside outright non-creation: an HBL is not created at all when no site resolves from the branch code or when either the assignee or the L1 service provider fails company resolution via CompanyAlias (exception raised, loop continues). (c) NO_PARENT rows follow the same ParentCompanyId = 0 path. THE LIST QUERY IS CONFIRMED to have no parent-row projection: it returns the row\'s own HBLNumber and ConsigneeName, joins Companies twice for display only, and AssignedCompanyId is display and optional-filter only, not part of the visibility predicate (visibility = ParentCompanyId match, plus delegatee of the latest active delegation, plus delegator of an active delegation; ACFS sees every row). So the backend grants the right party sight of the right rows and the portal then shows that party the wrong reference and consignee, exactly as diagnosed; the display fix (project the parent row\'s reference and consignee via ParentHBLId) remains the work, now unblocked on both sides. Also corrected from Jewel\'s 20 Aug reply: custody rows are NOT delegation-only, an initial HBLCustodyChain hop (FromCompanyId = ParentCompanyId, ToCompanyId = AssignedCompanyId) is created for every lower-level HBL at insert. One more behaviour worth knowing when reading Matt\'s reports: an HBL at HBLStatus 3 (delegated) is presented as 1 (unassigned) to the company that currently holds it by delegation; every other caller sees the stored value.',
1421status:'open',
1422},
1423{
1424id:'OQ-083',
1425question:'Is the pickup slot per BOOKING or per BOOKED HBL? The production booking ERD holds slot_id and slot_date on BookingHBLS, not on Bookings.',
1426reason:'BR-005 and the booking entity both state that one slot applies to the entire booking and that all trucks share it (BRD V2.0 §8.1). The production schema does not express that: with slot on the junction row, a single booking can carry HBLs on different slots and different dates, and nothing at the data layer prevents it. Either the rule is enforced only in application code (in which case say so, because it is then a validation that can be bypassed by any other write path), or the rule has quietly changed and a booking may span slots. The second reading would have real consequences — slot capacity counting (slot.booked_truck_count sums bookings.truck_count per slot/date, BR-039) assumes one slot per booking and would miscount, and the cut-off check would need evaluating per HBL rather than once per booking. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — THIS IS NOW EFFECTIVELY ANSWERED: the second reading is correct, and per-truck slots are the built model rather than a latent schema permission. The decisive evidence is the WRITE contract, not the read shape: CreateBookingWithTrucksParams (services/vbs/bookings.ts) has NO booking-level slot field at all; it carries truck_details[], and TruckDetail declares slot_id and slot_date as REQUIRED non-optional fields alongside its own hbl_ids. UpdateTruckDetail is identical. So the API the portal actually calls cannot express "one slot for the booking" and requires a slot per truck. The UI exposes this deliberately: booking-api-slice.ts builds each TruckDetail from that truck\'s own slotDate/slotTime, truck-slice.ts sets slot per individual truck, and DispatchTruckSlotCard is a per-truck slot picker. On read, useBookingsState.ts resolves the line-item slot in preference to the booking-level one. CONSEQUENCE: BR-005\'s "one slot applies to the entire booking, all trucks share it" is contradicted by the build, and slot.booked_truck_count (BR-039) which sums bookings.truck_count per slot/date will miscount whenever a booking spans slots. Note the frontend ships its own copy of this model\'s contract and that copy still asserts "All trucks in a booking share ONE slot", so the frontend contradicts itself as well. RECOMMENDATION: reconcile BR-005 and BR-039 to the per-truck reality, or rule per-truck slots out explicitly, and re-derive the capacity count per truck rather than per booking. Left open because that is a rule decision, not a documentation fix. Related defect found while verifying: the read path groups HBLs under trucks by the response\'s Truck.Id with a fallback of `Truck?.Id || Bookings?.Id || 0`, so if Truck is absent every HBL collapses into one pseudo-truck; and the truck\'s slot is taken from only its FIRST HBL, silently discarding divergent slots the schema allows. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): per booked HBL, confirmed from the backend. slot_id and slot_date were deliberately moved off Bookings onto BookingHBLS, Bookings holds no slot fields at all, and each BookingHBLS row carries its own slot_id, slot_date and truck_id. Explicitly NOT ENFORCED by the backend: that rows sharing a truck_id hold the same slot_id and slot_date, and that a slot_date\'s weekday matches the slot\'s configured DayOfWeek. On the capacity half: no capacity counting is built at all, Slots.HeatMapThreshold exists with no consuming logic, so BR-039 describes logic that does not exist yet and can be re-derived per truck without unwinding anything.',
1427status:'open',
1428},
1429{
1430id:'OQ-084',
1431question:'Are truck rows reusable across bookings? Production Truck has no booking_id — it is reachable only via booking_hbls.truck_id.',
1432reason:'Our model has trucks owned by a parent booking, with driver details entered fresh per truck per booking for Phase 1 and saved drivers deferred (A-025). The production booking ERD gives Truck no booking FK: just Id, UUID, TruckRego, DriverName, DriverLicense, SiteInductionFlag, TCAcceptanceTime and audit columns. That is exactly the shape reusable trucks and drivers require, and it matches Matt\'s "Feature to Add Later: Store Truck Drivers & Trucks info" — so the build may have laid the groundwork deliberately. Either way the effect today is that nothing stops 2 bookings referencing the same truck row, so "fresh details each booking" is not enforceable in the schema, and editing a shared truck row would silently change another booking. Also note driver_records already exists as the intended saved-driver home, which would make Truck a second, competing place to store the same thing. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source): the no-booking-FK shape is confirmed from the API response type (services/vbs/bookings.ts) — Truck carries Id, UUID, TruckRego, DriverName, DriverLicense, TCAcceptanceTime and audit columns only. CORRECTION TO THIS ENTRY: the API response shape does NOT include SiteInductionFlag, which the text above lists as part of production Truck; site induction appears instead as Bookings.site_induction_completed. The ERD and the API projection may legitimately differ, so treat this as "the field is not exposed to the portal" rather than proof the ERD is wrong, but the model should not assert induction lives on Truck without rechecking. On the substantive question, booking_hbls.truck_id is never consumed by the frontend; the UI reconstructs which HBLs a truck collects by grouping the response rows on Truck.Id instead. So nothing in the portal today depends on truck rows being booking-scoped, which means the reusable-truck direction stays open at no additional frontend cost. RELATED DEFECT: booking creation hardcodes site_induction_completed: true on every booking regardless of what the driver actually confirmed, which matters because induction is a site-access safety gate rather than a preference. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): confirmed, Truck has no BookingId and is reached only through BookingHBLS.truck_id, so its lifecycle is not tied to a booking. The CORRECTION TO THIS ENTRY above can itself be corrected: the deployed Truck entity DOES carry SiteInductionFlag (plus TCAcceptanceTime), it is simply not projected into the booking API response. Induction is confirmed recorded in 2 places, Truck.SiteInductionFlag and Bookings.site_induction_completed, which makes the frontend defect of hardcoding site_induction_completed: true a 2-place inconsistency risk rather than a single wrong flag.',
1433status:'open',
1434},
1435{
1436id:'OQ-074',
1437question:'Does the LSP side get users and roles, or does the one-shared-company-login model stand?',
1438reason:'The model deliberately made LSP access company-account level with no per-user role (lsp.auth, BR-014). Matt\'s UAT records "There is no role for LSP accounts" as a defect. This cascades directly into US-AM01–06 (VBPP-281 to 286), all of which are still To Do and unbuilt — so it is cheap to change now and expensive after account management ships. Related: Matt also reports the Profile screen showing a different email address and organisation than the account he logged in as, which suggests the account/user distinction is already blurred in the implementation. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — THE PREMISE NEEDS NARROWING, AND A LIKELY CAUSE OF MATT\'S PROFILE BUG WAS FOUND. (1) Per-user LSP accounts are a real backend concept: the users service carries RoleId/RoleName per user, createUser posts a role plus company_id, and getUsers accepts IsExternalUsers/IsInternalUsers flags. But the admin UI still presents LSP as COMPANY accounts (companies are adapted into the accounts list, and any lsp-role individual is filed under the Accounts tab), so there is no LSP per-user management surface even though the backend would support one. "One shared company login" is therefore too strong, and "individual LSP users exist" is too strong as well; the accurate statement is that the backend models per-user external accounts and the portal does not yet surface them. (2) Role gating is REAL, not cosmetic: the Next proxy hard-redirects an lsp role away from /acfs/* and an admin away from /lsp and /vbs. But it is strictly binary. The auth layer resolves only "lsp" or "admin" from the token and FALLS THROUGH TO lsp for any unrecognised or missing role value, which is a fail-open into the wrong tenant class rather than a refusal. (3) There is no trace of the 8 granular ACFS roles anywhere in the build; the DO validate, override-release and flag handlers exist and are gated by nothing, so any admin gets every capability. (4) LIKELY CAUSE OF THE PROFILE DEFECT Matt reported: the create-user screen offers only Admin and User, and maps anything that is not acfs_admin to the role string VBS_LSP. So creating an ACFS staff "User" provisions them as an LSP, which the proxy then bars from /acfs/* entirely and which would present them with the wrong organisation. That is a concrete bug to fix regardless of how the roles decision lands. BACKEND NOTE 2026-08-28 (Jewel, VBS Backend As-Built Reference): UserExtension exists as an entity in VBS_Master_CS; the ERD export was scoped to the shipment and booking domains, which is why users never appeared in it. No further role detail was provided, so the decision content of this question is unchanged.',
1439status:'open',
1440},
1441{
1442id:'OQ-075',
1443question:'Is the required DO set derived from HBL hierarchy ancestry or from delegation hops? And if the booking party may upload other parties\' DOs, what does "correct sequencing at validation" then mean?',
1444reason:'BR-002 and hbl.dos_fully_validated walk the PARENT CHAIN — own DO plus all ancestor-tier DOs. VBPP-279 instead states "the expected DO count (y) is derived from the number of delegation hops on the HBL. A chain of N hops requires N DOs" — that is hbl_custody_chain.hop_sequence, a different structure with different cardinality, since a shipment can have hierarchy tiers with no delegation and delegation hops with no hierarchy tier. VBPP-279 also reverses the model\'s no-auto-copy stance by letting the final nominated party upload whichever upstream DOs are missing, while still asserting that validation needs "the correct sequencing of documentation" — unspecified as to what enforces sequencing when one party supplied everything. Note the underlying business practice is not in doubt: carriers already bring one paper DO per FF in the supply chain (LCBP 2726133761). What is in doubt is which portal structure counts them. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — THE BUILD HAS ALREADY CHOSEN, AND IT CHOSE VBPP-279. The DO upload dialog builds its list of required DOs from HBLCustodyChains sorted by HOPSequence, one DO slot per hop, matching uploaded documents back by CustodyChainId then TierLevel then IssuedToCompanyId; HOPSequence is likewise read in the shipment actions hook and the ACFS documents queue. There is NO parent-chain or ancestry walk anywhere in the DO logic, consistent with the finding on OQ-073 that no code reads ParentHBLId at all. So the delegation-hop model is what is running, and BR-002 plus hbl.dos_fully_validated, which walk the hierarchy, do not describe the build. TWO REFINEMENTS THAT CHANGE WHO OWNS THIS QUESTION: (1) the expected DO count is NOT derived client-side at all; it arrives as DOCount.Expected on the API response and the frontend only renders it, so "which structure counts them" is now a BACKEND question about what populates Expected, and asking the build team what that field is computed from is the fastest way to close this. (2) On the sequencing half of the question: nothing enforces sequencing. The hops are sorted and displayed in order, but no check prevents uploading the hop-2 document before hop-1, so "correct sequencing at validation" is currently presentation only. That half remains a genuine product decision. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): the factual half is now CLOSED. DOCount.Expected is the number of ACTIVE HBLCustodyChain rows for the HBL, a plain row count: the hop model, with no ancestry walk over ParentHBLId anywhere in the counting logic. UploadedDOCount, ValidatedDOCount and FlaggedDOCount are hops whose most recent DO sits at ValidationStatus 2, 4 and 5 respectively, attributed exactly via DeliveryOrders.CustodyChainId. The count consults neither DOWaived nor ReleaseType, and because an initial custody hop is created for every lower-level HBL at insert (FromCompanyId = ParentCompanyId, ToCompanyId = AssignedCompanyId), a free-release HBL still returns an expected count of at least 1, while upper-level HBLs get no initial hop and count 0. Sequencing is confirmed unenforced end to end: a DO attached to hop 2 can reach ValidationStatus 4 while hop 1 has no DO at all, so ValidatedDOCount reflects how many hops are validated, not how far the chain has progressed in order. BR-002 and hbl.dos_fully_validated, which walk the hierarchy, definitively do not describe the build on either side of the API. What remains is purely the product half: whether the count SHOULD consult DOWaived and ReleaseType, and whether sequencing should be enforced, both downstream of OQ-072.',
1445status:'open',
1446},
1447{
1448id:'OQ-076',
1449question:'Should BR-010 be amended to describe scheduled synchronisation, and what data-staleness window should LSPs be told to expect?',
1450reason:'BR-010 says HBL/milestone/customs/tally data is fetched from Maximus in REAL TIME on each page load. The built architecture (AMP 2741501953) is scheduled push: four MuleSoft schedulers (Shipment, EDI Requested Cargo, Container Hold, Cargo Hold) at 30-minute intervals writing into OutSystems, plus an on-demand real-time refresh for specific scenarios. The portal therefore reads its own synced copy on page load, not Maximus. Matt\'s "Not pulling updated data from Maximus" and "This data has been updated in Maximus but not showing in portal" are the user-visible symptom. A 30-minute window on CUSTOMS STATUS in particular will keep generating "the data is wrong" reports, since that is the field gating booking. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — AND A SPECIFIC MECHANISM FOR MATT\'S REPORTS. The frontend ships its own copy of this model\'s contract and BR-010 there still reads "retrieved from Maximus in REAL TIME via MuleSoft APIs on each page load", so the contract the build was written against still describes the superseded design; amending BR-010 will need that copy regenerated, not just this model edited. NOT A DEFECT, recorded so it is not raised as one: the LSP side has no manual refresh control, but the same BR-010 says "Manual refresh remains ACFS-only for Phase 1; LSP self-service refresh is not in scope", and refresh does exist on the ACFS toolbar. THE REAL FINDING: the "Last sync" timestamp shown to users is the BROWSER CLOCK stamped at fetch time, not a Maximus or scheduler timestamp, and the accompanying toast says "HBL data synced from Maximus". So a user looking at data the scheduler last refreshed 29 minutes ago is told it synced just now, and told it came from Maximus when it came from the portal\'s own copy. That makes the staleness window structurally invisible at exactly the moment a user is checking whether their change landed, and it converts an expected-latency situation into an apparent data-correctness bug, which is the shape of Matt\'s "updated in Maximus but not showing in portal" reports. Whatever staleness window gets agreed, the label must show the sync time the backend reports rather than the client clock, or the window cannot be communicated at all. Response caching is not a contributor: only the sites list and company lists are cached, everything else is no-store. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified), WITH A CADENCE CORRECTION: the ingest is a SINGLE triggered API running EVERY HOUR, delivering into 4 staging tables, not 4 schedulers at 30-minute intervals as recorded above from AMP 2741501953. So the staleness window to communicate is up to an hour plus run duration, twice what this entry previously assumed, and the backend states this is the designed behaviour of the integration. On the label fix: confirmed impossible without new API surface. Timestamps exist on the Staging master (CreatedAt, UpdatedAt, CompletedAt) but are not exposed through any API, and there is no sync run log, so no backend sync time is currently available for the portal to show. Amending BR-010 therefore needs 3 things: the rule rewritten to hourly scheduled sync, the staleness window stated to LSPs, and a small backend API addition exposing the last completed run time so the frontend\'s browser-clock "Last sync" label can be replaced with the truth.',
1451status:'open',
1452},
1453{
1454id:'OQ-077',
1455question:'What shape should a top-level Digital Release action take — a third top-level view alongside Shipments and Bookings, or an action on the Shipments list?',
1456reason:'Digital Release is currently reachable only inside the delegation flow, and the release still has to be performed as part of delegating. Matt: "The Digital Release is hidden away under delegation. This is a primary action unrelated to delegation... Should be independent of Delegation. Should have a button on the main screen matching booking and delegation." For L1 customers such as AGS, release is the only thing they routinely do. The instruction is clear; the shape is a design call that restructures the lsp-provides-release-authority journey and the two-view split in BR-030, which is why it is recorded here rather than rewritten. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — THE SHAPE QUESTION IS NOT THE BLOCKER; THE STANDALONE ACTION IS BUILT BUT NON-FUNCTIONAL. There are 2 release surfaces and they are in very different states. (1) INSIDE THE DELEGATE FLOW, release works and persists: a per-recipient card can be set to method "release", and confirming calls updateHbl with ReleaseStatusId 1 (Digital Release Provided). This is the release Matt found and objected to being buried. (2) ON THE SHIPMENTS LIST, the standalone action Matt asked for already exists as a "Provide release" button in the bulk action bar, but it is broken in 2 independent ways. First, it never persists: confirming only adds ids to a local React state set, initialised empty on every mount, with NO API call anywhere in that path, so a release granted there is forgotten on reload. Second, it is permanently disabled against real data, for the reason below. THE ROOT CAUSE, WHICH ALSO BLOCKS OQ-072 AND OQ-078: the button is enabled only for HBLs whose level resolves to "intermediate", and level is resolved by a helper that tests the HBL id against a HARDCODED SET OF 3 PROTOTYPE IDS (dh-03, dh-07, dh-12) in lib/dispatch-data.ts. Live rows are keyed by UUID, so that test never matches, every real HBL is classified lowest-level, and the button is permanently greyed with the tooltip "Digital release applies to intermediate HBLs only, lowest-level HBLs need a DO". Separately the LSP adapter hardcodes level: "lowest_level" behind a TODO reading "wire from API ffo_flag / hbl_level when available", and nothing anywhere reads that field. THE TODO IS FACTUALLY STALE AND THIS IS A SMALL FIX: FFOFlag and HBLLevelIndicator are ALREADY present on the shipments API type, and lib/vbs-booking-adapter.ts already consumes FFOFlag correctly with the comment "FFOFlag is present in the booking response, use it directly". So one adapter reads the flag and the other does not; there is no backend dependency to wait on. PRACTICAL CONSEQUENCE FOR THE DECISION: an L1 customer such as AGS, whose main action is release, cannot currently perform one from the shipments list at all, which is the behaviour Matt experienced. Wiring level from FFOFlag and giving the button a real API call matters more than choosing between a separate section and a list action, and the list action is already in place if that shape is acceptable. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): the backend release model exists in full (ReleaseAuthority with ReleaseAuthorityStatus and ReleaseMechanism, plus HBLReleaseStatus), but there is NO STANDALONE RELEASE ENDPOINT: release is persisted only through the delegate flow, so a party whose only action is release has no independent path to perform it. One correction to the frontend evidence above: ReleaseStatusId is a DENORMALISED CACHE, and the release values the portal renders derive from ReleaseAuthority and DeliveryOrders, not from that attribute. So the working in-delegation release path (updateHbl with ReleaseStatusId 1) writes the cache rather than the source of record, and giving the shipments-list button a real persistence path needs a backend release endpoint, not just the API call the frontend forgot. The level-wiring half is unchanged: FFOFlag and HBLLevelIndicator (2 upper, 1 lower) are both populated on HBLS, so classifying rows client-side still has no backend dependency.',
1457status:'open',
1458},
1459{
1460id:'OQ-078',
1461question:'Do we build tier-aware filter sets for the shipment list, or accept one filter set for all LSP tiers in R2?',
1462reason:'Two findings, one root. The narrow one: "Available" is being read as "all", and Matt wants default = All with Available meaning genuinely ready-to-book (see also VBPP-164, VBPP-210, VBPP-305 — the filter is returning ineligible HBLs anyway). The structural one: "filter buttons give quick access to items that have been processed, not items that need to be processed. The type of processing depends on the LSP and where they sit in the HBL hierarchy" — an L1 NVOCC needs "needs release", a nominated carrier needs "needs DO", and they are currently offered the same tabs. Related and cheap by comparison: view state (site, grouping, selected fields) must PERSIST per account rather than resetting after every action, since AGS always works in container lots — BR-033 covers column persistence only. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source): R2 has shipped the single shared set. The shipments toolbar defines 5 hardcoded filter chips (Available, Booked, Delegated, Released, Collected) with no conditioning on role, tier or hierarchy position anywhere in the component or its controller, and there is no tier concept in the LSP constants at all. Note the tier-aware version is currently BLOCKED by the same defect recorded on OQ-077: a "needs release" versus "needs DO" split depends on knowing whether an HBL is intermediate or lowest-level, and that classification is presently decided by a hardcoded set of 3 prototype ids, so every live row reads lowest-level. Wiring level from FFOFlag is a prerequisite for tier-aware filters, not a separate piece of work. ALSO RELEVANT TO THE NARROW HALF of this question, which reports that "Available" behaves like "all": there is a concrete cause. The adapter computes an availability flag whose release test ORs together every value the release enum can produce, so the release condition is always true and does nothing, and the surrounding comment states the opposite intent ("an unpacked/collected HBL with customs pending or do_required must still show Not yet available for pickup"). The same flag also accepts milestone at_wharf and later, whereas the canonical booking gate requires unpacked. So "Available" is computed from a looser rule than "bookable" and will list shipments that the booking gate then refuses, which is the reported symptom and is consistent with VBPP-164, VBPP-210 and VBPP-305. The canonical gate itself is correct, so this is a defect in the availability flag rather than in the booking rule. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): the list query applies no level filter, upper and lower HBLs are returned together wherever ParentCompanyId matches, and HBLLevelIndicator (1 lower, 2 upper) is populated but unreferenced by the list query. So the level data a tier-aware chip set needs is already present on every row, and both blockers are frontend-side: wire level from FFOFlag / HBLLevelIndicator (see OQ-077), then condition the chips.',
1463status:'open',
1464},
1465{
1466id:'OQ-079',
1467question:'Do slot cutoff times resolve in each site\'s LOCAL timezone?',
1468reason:'Matt: "Does the system adjust for the time zones of each Site in relation to cut off times?" ACFS operates sites across multiple Australian timezones, so "previous working day, 4 PM" is ambiguous without an answer. This has a rework consequence rather than just a gap: VBPP-232, 253, 254 and 256 are all cutoff-enforcement bugs now marked Ready for UAT, and if the underlying arithmetic is timezone-naive several of them will resurface at go-live on non-Melbourne sites. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — THE RISK IS CONFIRMED AND THERE IS ALREADY AN ACTIVE DEFECT, not merely an absence. Cutoffs are stored and edited as a relative-day offset plus a bare "HH:MM:SS" wall-clock string with no zone marker, no timezone field exists on Site, SlotConfig or Cutoff, and no date library is installed so all arithmetic is native Date. Worse, the ACFS bookings screen renders booking date and time with timeZone hardcoded to "UTC", so for Australian sites at UTC+8 to UTC+11 the displayed time is already wrong by hours and an evening booking can show the wrong calendar day. That is a present-tense bug on the bookings list, independent of the cutoff question. One point in favour of a cheap fix: Site already carries a State value, so a site timezone is derivable without new data capture, it is simply never derived. Recommend treating the UTC rendering as a bug to fix now and the cutoff timezone as the design decision this question actually asks about. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): no, they do not. No timezone is stored anywhere: no timezone attribute on Sites, Slots or any cutoff field, and cutoff comparisons resolve against PLATFORM SERVER TIME for every site regardless of state. So the timezone-naive arithmetic is confirmed on both sides of the API and the fix needs a backend representation as well as the frontend one. Sites.State (AUState) is confirmed populated and mandatory on every site, so a per-site timezone remains derivable without new data capture.',
1469status:'open',
1470},
1471{
1472id:'OQ-080',
1473question:'May a site be configured with NO booking cutoff, other than the slot end time itself?',
1474reason:'Matt: "Slot Config - looks as if you must have a booking cut off? Can we have the option for no cut off - other than the end of the slot?" BR-005 assumes a cutoff always exists and the slot entity types booking_cutoff as a required relative-day + time pair. Allowing an empty cutoff changes both the config UI and the enforcement path, which must then fall back to the slot end. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source): confirmed not built, and confirmed to need a type change rather than a config toggle. The cutoff type list is exactly 5 literals (Same day, Previous working day, 2 days before, 1 hour before slot, 2 hours before slot) with no None option, the Cutoff type declares both type and time as required with no null path, and the default-cutoff builder always populates both the booking and change cutoffs. SEPARATE DEFECT FOUND WHILE VERIFYING, worth fixing whichever way this question lands: the cutoff round-trip is lossy. Both "1 hour before slot" and "2 hours before slot" serialise to offset 0 with a pre-computed absolute time, and the reader only decodes offsets 0, 1 and 2 back into Same day, Previous working day and 2 days before. So an admin who selects "1 hour before slot", saves and reloads is shown "Same day" instead, and because the relative-to-slot meaning was not persisted, later changing the slot start time leaves the cutoff frozen at the old absolute time rather than moving with the slot. Enforcement is correct at the moment of saving, so this is silent configuration drift rather than an immediately visible failure. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): no. Both cutoff fields are REQUIRED in the data model, which expresses only offset-day plus absolute time; a relative-hours cutoff is NOT EXPRESSIBLE either. That explains the lossy round-trip recorded above at its root: "1 hour before slot" and "2 hours before slot" cannot be stored as stated, only pre-computed into a fixed time that stops tracking the slot if StartTime later changes. So a no-cutoff option needs a backend type change (nullable cutoff with fallback to slot end), and honest relative-hours options need a cutoff-mode attribute, before any config UI work is worth doing.',
1475status:'open',
1476},
1477{
1478id:'OQ-081',
1479question:'Should the HBL parent-child relationship move to a separate hbl_relationships entity as the architect guide recommends, or does ParentHBLId-on-HBLS stand?',
1480reason:'The architect implementation guide (LCBP 2685468677 v32) §9.3 does not merely recommend this, it opens with "use a dedicated relationship entity RATHER THAN trying to store parent-child information only on the HBL row", and specifies the attributes: ContainerId (scopes the match to the right container), ParentHBLId, ChildHBLId, RelationshipType (ONE_TO_ONE, ONE_TO_MANY, MANUAL_LINK, NO_PARENT, UNKNOWN), MatchLevel (FOUR_FOUR, THREE_BLANK_FOUR, THREE_LOW_FOUR, TWO_FOUR, NO_MATCH), ConfidencePercent, NeedsManualReview, MatchNotes ("human-readable reason explaining why the link was created or blocked"), SourceBatchId, IsActive ("allows relationship correction without losing history"). Production collapsed all of it onto the HBLS row and dropped four attributes outright: ContainerId, MatchNotes, SourceBatchId and IsActive. The practical losses are specific — no competing candidate can be persisted for an admin to choose between, no reason can be shown for why a link was blocked, a correction overwrites history rather than superseding it, and a bad batch cannot be traced. That is most of what a manual-review queue needs to be usable (BR-034, needs_manual_review). Either raise it with Jewel now, or accept it and require the review screen to re-derive candidates and reasons on read. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — CONFIRMED, AND THE FALLBACK OPTION IN THE SENTENCE ABOVE IS NOT AVAILABLE, BECAUSE THERE IS NO REVIEW SCREEN TO RE-DERIVE INTO. A targeted search for the 4 dropped attributes (ChildHBLId, MatchNotes, SourceBatchId, ConfidencePercent) and for any relationship entity returns zero hits across the whole application, so they are definitively absent rather than merely unused. More consequentially, ACFS has exactly 5 routes (bookings, documents, shipments, users, slots) and none of them is a hierarchy, match, exception or review queue; NeedsManualReview and Exceptionid are declared on the API type and read nowhere. So the "Correct HBL Hierarchy" ACFS role listed in BR-014 has no screen at all, and the note recorded elsewhere in this model that "the review UX is now backed by real fields" is wrong as of this build: the fields exist, the read side does not. This raises the cost of the accept-as-built option, because accepting it assumes a review screen that would then have to be written from nothing, and without MatchNotes it would have no stored reason to display for why a link was blocked. Recommend deciding the entity question and the review-screen question together rather than separately. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): DELIBERATE. ParentHBLId, RelationshipTypeId and MatchLevelId are held on HBLS so the list query needs no join. Confirmed not stored anywhere: match notes, competing candidate matches, confidence scores, and a per-relationship IsActive; SourceBatchId exists only at staging level as the correlation id. Confirmed no review screen on the OutSystems side either, so the absence is total: NeedsManualReview and ExceptionId are written by the matcher and consumed by nothing in the entire stack (deployed spelling note: IsManunallyUpdated is the ACFS-correction flag that gates the matcher from re-running over a corrected row). The interaction the backend itself flags: a row flagged for review keeps ParentCompanyId = 0 and stays ACFS-only, because the only post-mapping writer of ParentCompanyId is an ACFS assignment and nothing currently performs one, so flagged rows silently vanish from every LSP list. That binds this question directly to OQ-073\'s 8-of-17 shortfall and raises the cost of accepting the flat shape: the entity decision, the review screen and LSP visibility of unmatched rows now have to be decided together.',
1481status:'open',
1482},
1483{
1484id:'OQ-082',
1485question:'Do Dangerous Goods + classification, CHEP pallet data, goods Description and kg weight display come back into R2 scope?',
1486reason:'hbl.un_code, dangerous_goods, pallet_quantity and pallet_type are all marked "OUT OF INITIAL RELEASE (1 Jul)", and the architect guide marks the CHEP mapping "Not required". Matt\'s UAT asks for DG + classification and CHEP pallet data as missing from display, plus weight shown in kg. Description is a separate case and looks like an oversight rather than a deferral — it exists as a field in the model and simply is not rendered; Matt suggests a hover/popup if horizontal space is tight. Note DG has a compliance dimension that the other three do not, so it may warrant a different answer. FRONTEND CODE EVIDENCE 2026-08-21 (vbs-frontend build, verified in source) — 3 of the 4 items resolve differently from how this question frames them. (1) DESCRIPTION IS NOT MERELY UNRENDERED, IT IS MISUSED. Both HBL adapters resolve the displayed HBL reference as HBLNumber, then AltHBLReference, then DESCRIPTION, then a synthesised "HBL-{id}". The LSP adapter\'s own comment states "hbl_number is \\"\\" in current data", so this fallback is live rather than theoretical, and when both reference fields are blank the HBL Reference column renders free-text cargo description where an identifier belongs, sortable and searchable as if it were a reference. There is no standalone description field on either display type, so Description is never shown AS a description. This is a bug to fix rather than a scope decision, and it should be fixed even if Description display stays out of scope. (2) WEIGHT is rendered, but as tonnes to 1 decimal place on the shipment list and detail, so anything under 50 kg displays as 0.0 t; kg is shown correctly on the P4TC screen and in the manage-booking shipment list, so the fix is to align the main surfaces with the ones that already do it right, not to add a new capability. (3) DANGEROUS GOODS AND PALLET DATA are absent further down the stack than this question assumes: IsDangerousGood, UNCode, IMOCode, PalletQuantity and PalletType exist ONLY on the raw API types and have no corresponding field on either display type, so bringing them into scope requires adapter and type changes, not just switching on a display. Note also that DG exists as a bare boolean plus UN and IMO codes, with no classification field, so "DG plus classification" as Matt asked for it is not merely hidden, it has nowhere to live yet. (4) CHEP is confirmed absent everywhere by name, consistent with the integration spec marking it not required. BACKEND AS-BUILT ANSWER 2026-08-28 (Jewel, VBS Backend As-Built Reference, verified): storage is not the constraint. IsDangerousGood, IMOCode, UNCode, PalletQuantity, PalletType and Description are ALL stored on HBLS, fed from staging (OrderItem_IMOCode, OrderItem_UNCode, plus the UOM and quantity fields). Confirmed absent at the source: a DG CLASSIFICATION attribute and any CHEP-named attribute. That splits the scope decision cleanly: displaying what exists (DG boolean plus UN and IMO codes, pallet quantity and type, Description, kg weights) is API projection and adapter work only, while "DG plus classification" and CHEP each need a new backend attribute and a Maximus mapping before there is anywhere for the data to live.',