Skip to content

MK Physical Scale Capability Rebuild Packet

  • Packet status: DETAILED SOURCE-RECONCILED REBUILD INPUT / POLICY, DEVICE, TARGET-ROLE AND RUNTIME REVIEW REQUIRED
  • Capability: physical Scale Check-in, Check-out, reweigh, ticket lineage and owner handoff
  • Process owner: PROC-YMS-SCALE-TICKET-EXECUTION-MK
  • Operating profile: mk-order
  • Current module: yms.scale
  • Current primary records: T_SCALE_TICKET, T_SCALE_TICKET_EVENT
  • Current links: T_LOAD.TICKET_NUMBER, T_TRANSLOAD.SCALE_TICKET_ID, T_EQUIPMENT_LOAD.SCALE_TICKET_ID
  • Related owners: MK Inbound Purchase, MK Outbound Sales, Transload, Equipment, Inventory, Allocation and document outputs
  • Current source authority: MK_PHYSICAL_SCALE_SOURCE_AUTHORITY.md
  • Current Process contract: MK_SCALE_TICKET_EXECUTION_WORKFLOW.md
  • Target stack: React + Next.js + framework-independent TypeScript application/domain/repository contracts + MySQL first
  • Device status: no accepted physical-device adapter is established by current repository source
  • Worker requirement: none for the synchronous core ticket transaction; a worker is optional only for a separately approved asynchronous device/provider channel
  • Later database target: PostgreSQL after accepted React + Next.js + TypeScript + MySQL stabilization
  • Important: this packet does not approve the unresolved Gross/Tare flow contract, device policy, role policy, zero-weight policy or cross-surface BMS ownership.

1. Capability Outcome

1.1 Business problem

Physical vehicle/equipment movement can require two trusted Scale stages. The system must capture the correct stage, preserve the exact accepted values and actor/time provenance, connect the ticket to the correct business record, distinguish Scale completion from downstream business completion and recover safely from timeout, duplicate, correction or reversal.

The capability must preserve:

physical movement
+ operator-selected flow
+ stage direction
+ accepted reading
+ ticket identity
+ order/transload/equipment link
+ correction/reversal lineage
+ exact readback

without collapsing these separate outcomes:

Scale Check-in
!= Scale Check-out
!= Purchase receipt finalize
!= Inventory Lot materialization
!= Outbound order close
!= Packing / Delivery
!= document print

1.2 Required user-visible result

An authorized Scale operator can:

  1. enter the Scale Workspace through the assigned menu;
  2. identify the exact intended business flow and physical movement;
  3. distinguish Purchase, Doortrade, Sales and Export direction;
  4. verify the exact order, equipment, company, commodity, quantity and current ticket state;
  5. capture or manually enter a first-stage reading;
  6. submit Check-in once and receive exact ticket/order/link readback;
  7. reopen the active ticket by stable identity;
  8. correct the first stage before Check-out only through a reasoned reweigh command;
  9. capture and submit the second stage once;
  10. verify both stages and net calculation;
  11. see independent downstream child dispositions;
  12. continue to Purchase finalize or Outbound close only through the owning process;
  13. recover from a timeout without blind replay;
  14. void/reverse only through an authorized, reasoned and downstream-safe command;
  15. print the intended active ticket without treating print as completion;
  16. retain the same Wiki topic when the PHP page later becomes React + Next.js.

1.3 Non-goals

This packet does not approve:

  • one generic Scale lifecycle status stored on unrelated business records;
  • all-flow Gross Check-in;
  • all-flow Tare Check-in;
  • numeric-client or numeric-role policy;
  • device text injected directly into a business table;
  • browser time as authoritative physical event time;
  • BMS generic mutation as a second YMS ticket owner;
  • ticket deletion as ordinary Undo;
  • hidden Purchase receipt or Outbound close inside a Scale success message;
  • blind retry after timeout;
  • a generic table mutation API;
  • durable print status;
  • PostgreSQL in the first Scale migration wave.

2. Current Truth Table

Statement Current source-reconciled truth
YMS Schedule/ticket/detail/event reads are tenant scoped Yes
YMS write routes require module/menu entry Yes
Integrated Check-in saves order/items/ticket/link in one local transaction Yes
Check-out saves all header/items/ticket/downstream state in one transaction No
Current client request timeout 30 seconds
Client abort cancels server commit No
YMS reweigh requires reason Yes, before second stage
YMS reweigh records immutable event Yes
YMS stage update uses compare-and-swap snapshot Yes
YMS second stage requires first stage Yes
YMS duplicate identical completed stage is idempotent in-process Yes
Durable request token across lost responses No
YMS delete/reversal checks downstream execution Yes
YMS delete/reversal records reason/event Yes
BMS PATCH/delete uses the full YMS stage/reversal contract No
Current physical print is tenant/active scoped Yes
Current physical print is a durable effect No
Current page has an accepted device adapter No
Current page starts with 00000 lb Yes
Purchase/Doortrade UI schema is Gross-in/Tare-out Yes
Sales/Export UI schema is Tare-in/Gross-out Yes
Integrated Check-in writes Tare for Sales/Export No; it currently writes Gross for every flow
Existing static contract test detects Sales/Export direction mismatch No; it requires the all-flow Gross behavior
Existing local smoke covers Purchase Gross-in/Tare-out Yes, when run locally
Existing local smoke covers Sales/Export Tare-in/Gross-out No source-confirmed coverage found

3. Actors, Capabilities And Denied Behavior

3.1 Actors

Scale Operator

Responsible for:

  • selecting the correct flow and record;
  • verifying physical and system identity;
  • entering/accepting stage values;
  • Check-in and Check-out;
  • exact readback;
  • stopping on mismatch or unknown result.

Must not:

  • bypass menu/record scope with copied IDs;
  • change an already completed stage through generic edit;
  • repeat Check-in/Check-out after timeout without reread;
  • finalize Purchase receipt by direct table edit;
  • repair Outbound close through Scale resubmission;
  • directly delete or restore ticket/link rows.

Receiving / Inbound Purchase Operator

Responsible for:

  • Purchase order and item source values;
  • Scale-to-receipt finalize;
  • receipt/Transload/Lot reconciliation;
  • post-receipt correction.

Must not classify Scale stage completion as receipt completion.

Shipping / Outbound Sales Operator

Responsible for:

  • Outbound order/items/equipment context;
  • Outbound close/status after accepted Scale evidence;
  • downstream Packing/Delivery continuation.

Must not use ordinary Outbound Save to overwrite Scale-owned stage evidence.

Scale Recovery Manager

Responsible for:

  • reweigh/reversal authorization where policy requires;
  • unknown-result reconciliation;
  • event timeline review;
  • competing-writer escalation;
  • fixture/recovery cleanup in non-Production environments.

Support / Migration Operator

Responsible for:

  • request/ticket/order/link trace;
  • current-versus-target parity;
  • one-writer cutover and rollback;
  • caller-zero evidence.

Device Integration Owner — future/optional

Responsible for:

  • device identity and connection;
  • reading session and provenance;
  • transport/reconnect behavior;
  • device health and diagnostics.

Must not mutate ticket/order tables directly.

3.2 Proposed semantic capabilities

yms.scale.view
yms.scale.check-in
yms.scale.check-out
yms.scale.reweigh
yms.scale.reverse
yms.scale.events.view
yms.scale.print
yms.scale.reconcile
yms.scale.device.use

These are target semantic names. Current role/menu mapping must be characterized before activation.

3.3 Authorization dimensions

Every query/command evaluates:

authenticated actor
+ tenant/profile
+ capability
+ current menu/page compatibility
+ record tenant
+ record state
+ flow/stage eligibility
+ downstream lock

The client never sends an actor or tenant ID to gain access.


4. Flow And Stage Contract

4.1 Current intended UI matrix

Flow Business direction UI Check-in UI Check-out Related owner
Purchase inbound Gross Tare Inbound Purchase
Doortrade inbound local Gross Tare Inbound Purchase
Sales outbound local Tare Gross Outbound Sales
Export outbound ocean Tare Gross Outbound Sales / Booking

Other is not an approved long-term MK business flow. Current fallback behaves as Tare-in/Gross-out but requires Product disposition.

4.2 Current implementation contradiction

Integrated Check-in currently forces Gross for all flows. Therefore the accepted target matrix is not established by current source alone.

Activation blocker:

SCALE-POL-010 must be accepted
and
SCALE-SCN-010 through SCALE-SCN-040 must pass
before a target write cutover

4.3 Target policy representation

Do not hardcode the direction in React components or route handlers.

interface ScaleFlowPolicy {
  flow: 'PURCHASE' | 'DOORTRADE' | 'SALES' | 'EXPORT';
  entryStage: 'GROSS' | 'TARE';
  exitStage: 'GROSS' | 'TARE';
  requireOrder: boolean;
  requireEquipment: boolean;
  requireBooking: boolean;
  requireContainerSize: boolean;
  zeroWeightPolicy: 'FORBIDDEN' | 'EXPLICIT_EXCEPTION';
}

Policy is selected through Operating Profile and typed configuration, never numeric Client ID.


5. State Model

5.1 Persisted ticket evidence

Persisted evidence is the two stage timestamps/axle snapshots plus lifecycle deletion.

GROSS stage
TARE stage
DELETED_AT

5.2 Derived ticket states

NOT_STARTED
ENTRY_RECORDED
COMPLETED
VOIDED
REVERSED
CONFLICT
UNKNOWN

Derivation requires the selected flow policy.

State Derivation
NOT_STARTED neither accepted entry nor exit stage exists
ENTRY_RECORDED accepted entry exists and exit does not
COMPLETED accepted entry and exit exist and Gross/Tare validation passes
VOIDED non-completed ticket soft-deleted with TICKET_VOID event
REVERSED completed ticket soft-deleted with TICKET_REVERSAL event
CONFLICT stages, links, flow or events disagree
UNKNOWN request outcome cannot yet be classified

Do not infer ENTRY_RECORDED merely from “exactly one timestamp” without the flow policy.

5.3 Composite process state

Scale ticket state remains separate from:

Order state
Transload/receipt state
Inventory Lot state
Equipment Load state
Outbound close state
Packing/Delivery state
Print state

Target UI displays independent child dispositions rather than one “Complete” status.


6. Identity Model

6.1 Required stable identities

Identity Purpose
tenantId / tenant UUID tenant scope
scaleTicketId current local relational identity
scaleTicketUuid durable ticket identity when exposed safely
ticketNumber operator-facing reference, not sole relational key
scaleRequestToken idempotency across duplicate/response loss
flow accepted business flow
orderId Purchase or Sales owner record
orderItemIds[] exact source item context
transloadId Purchase ticket link/receipt handoff
equipmentLoadId Sales ticket link
deviceId future physical device identity
deviceSessionId future connected weighing session
deviceReadingId future immutable source reading
ticketEventId / UUID reweigh/void/reversal lineage
requestId request tracing; not sufficient alone for business idempotency

6.2 Ticket number

Ticket number is human-facing and must be unique in the accepted tenant scope. Target generation must not rely on an unguarded “latest + 1” read.

Accepted target alternatives:

  • tenant-scoped DB sequence table with conditional update;
  • UUID identity plus separately reserved display number;
  • retry-safe unique insert bound to scaleRequestToken.

Final choice is a DB/application decision, not a React concern.

Exactly one accepted link path per flow:

Purchase/Doortrade:
Scale Ticket -> Transload -> Inbound Purchase

Sales/Export:
Scale Ticket -> Equipment Load -> Outbound Sales

T_LOAD.TICKET_NUMBER is a compatibility projection. It is not the target canonical relationship.


7. Device And Reading Envelope

7.1 Current status

No accepted device adapter is source-confirmed. Current operation is manual-entry capable and the “Live Weight” display is not authority.

7.2 Target device-neutral envelope

interface ScaleReadingEnvelope {
  deviceId: string;
  deviceSessionId: string;
  readingId: string;
  source: 'DEVICE' | 'MANUAL';
  capturedAt: string;
  receivedAt: string;
  inputUom: 'LB';
  canonicalUom: 'LB';
  value: string;
  stability: 'STABLE' | 'UNSTABLE' | 'UNKNOWN';
  rawReference?: string;
}

The application records which reading the operator accepted.

interface AcceptedScaleStageInput {
  flow: ScaleFlow;
  stage: 'GROSS' | 'TARE';
  axles: {
    steering: string;
    drive: string;
    rear: string;
    fourth: string;
    fifth: string;
  };
  acceptedReadingId?: string;
  acceptedAt: string;
  acceptedBy: string;
  reason?: string;
}

7.3 Device rules

  • Device disconnect does not erase a captured business ticket.
  • Unstable reading is not silently accepted.
  • Device time and server receive time remain distinguishable.
  • Manual fallback is explicit and auditable.
  • One reading may be displayed many times but accepted once per stage/version.
  • Device adapter never owns tenant, order, ticket or role policy.
  • Raw device payload retention is a separate security/retention decision.

8. Data Field Dictionary

8.1 T_SCALE_TICKET

Field Current meaning Target rule
ID local ticket identity immutable
UUID row identity immutable, unique per accepted schema
CLIENT_ID current tenant scope resolved server-side
TICKET_NUMBER operator reference tenant-scoped unique reservation; immutable after create unless a separate correction policy exists
REFERENCE_NUMBER business reference snapshot bounded text; source and mutability policy required
COMPANY_NAME company snapshot not a company master key
TRACTOR_NUMBER vehicle snapshot bounded text
EQUIPMENT_NUMBER equipment/container snapshot must agree with accepted link when required
DRIVER_NAME operator-entered driver snapshot bounded text
WEIGHER_NAME operator-entered weigher snapshot actor identity remains separate
COMMODITY_NAME ticket commodity summary derived/validated from exact item set where linked
COMMODITY_QUANTITY ticket quantity snapshot UOM/quantity authority policy required
GROSS_TIME accepted Gross stage server time immutable except reasoned pre-completion correction policy
GROSS_*_WEIGHT accepted Gross axle snapshot integer LB in current schema; exact target precision required
TARE_TIME accepted Tare stage server time immutable except reasoned pre-completion correction policy
TARE_*_WEIGHT accepted Tare axle snapshot integer LB in current schema
REMARK operator/support note not the only correction lineage
DRIVER_SIGNATURE legacy signature payload ownership/retention/security review required
WEIGHER_SIGNATURE legacy signature payload ownership/retention/security review required
BAD_BALE_* legacy quality fields separate Product owner/disposition required
DELETED_AT soft-delete/void/reversal marker only through owner command
CREATED_AT, UPDATED_AT row timestamps not physical stage timestamps

8.2 Derived totals

Gross = sum Gross axles
Tare = sum Tare axles
Net = Gross - Tare

Rules:

  • no negative axle value;
  • Gross and Tare each follow accepted zero-weight policy;
  • completed ticket requires Gross >= Tare unless an explicit exceptional process exists;
  • all calculations use exact decimal/integer rules, not JavaScript floating inference;
  • canonical UOM is explicit.

8.3 T_SCALE_TICKET_EVENT

Field group Meaning
SCALE_TICKET_ID, TICKET_NUMBER parent identity snapshot
EVENT_TYPE REWEIGH_CORRECTION, TICKET_VOID, TICKET_REVERSAL
WEIGHT_PREFIX affected stage or NONE
input/canonical/display UOM unit provenance
before/after stage time and axles immutable transition evidence
REASON_TEXT required human reason
actor ID/username action actor
REQUEST_ID request trace
lifecycle/UUID immutable event identity and soft-delete infrastructure

Target event rules:

  • append only;
  • no event overwrite;
  • stable event UUID;
  • reason required for every corrective/destructive action;
  • event and ticket update commit in the same local transaction;
  • correction event is not a substitute for business idempotency token.
Field Meaning Target disposition
T_TRANSLOAD.SCALE_TICKET_ID Purchase/Transload link typed repository relation
T_EQUIPMENT_LOAD.SCALE_TICKET_ID Sales/Equipment link typed repository relation
T_LOAD.TICKET_NUMBER compatibility display pointer retire after caller-zero or retain as projection only

9. Semantic Query Contracts

9.1 GetScaleSchedule

Input:

{
  dateFrom?: string;
  dateTo?: string;
  keyword?: string;
}

Returns:

  • exact order/flow identity;
  • accepted flow projection and reason;
  • linked ticket ID/number;
  • entry/exit stage disposition;
  • order/transload/equipment child disposition;
  • allowed actions;
  • warnings/conflicts.

No mutation.

9.2 GetOpenScaleTickets

Returns active tickets whose accepted flow has entry stage and lacks exit stage.

Do not implement as “exactly one timestamp” without flow policy.

9.3 GetScaleTicketDetail

Returns:

  • ticket identity;
  • accepted flow and link;
  • both stage snapshots;
  • computed totals;
  • order/item/equipment summary;
  • correction/reversal eligibility;
  • exact child dispositions;
  • current version/freshness;
  • stable errors/warnings.

9.4 GetScaleTicketTimeline

Returns ordered immutable events and ticket creation/completion references.

Normal user UI may summarize; support UI can show full bounded evidence.

9.5 GetScaleCommandResultByToken

Input:

{ scaleRequestToken: string }

Returns:

NOT_FOUND
IN_PROGRESS
COMMITTED
FAILED_DEFINITE
UNKNOWN_REVIEW

with exact ticket/order/link IDs when known.

9.6 GetDeviceSessionState — future/optional

Returns device connection, last stable reading, reading age and diagnostic state. It never implies a business stage was accepted.


10. Semantic Command Contracts

10.1 ExecuteScaleCheckIn

Purpose: submit the accepted first stage exactly once.

Input:

interface ExecuteScaleCheckInCommand {
  scaleRequestToken: string;
  flow: ScaleFlow;
  orderContext:
    | { mode: 'EXISTING'; orderId: string; expectedVersion: string }
    | { mode: 'WALK_IN'; orderDraft: WalkInOrderDraft };
  itemSnapshot: ScaleOrderItemInput[];
  stage: AcceptedScaleStageInput;
  ticketMetadata: ScaleTicketMetadataInput;
}

Server behavior:

  1. authenticate and resolve tenant/profile/capability;
  2. resolve accepted flow policy;
  3. verify command stage equals policy entry stage;
  4. claim request token;
  5. validate order/items/references;
  6. save/create order through the owning application contract;
  7. create ticket and typed link;
  8. exact ticket/order/link readback;
  9. commit once;
  10. return stable result.

Current integrated Check-in provides a useful one-transaction baseline. Target implementation must correct the flow-stage contradiction and add durable idempotency/freshness.

10.2 CorrectScaleEntryStage

Preconditions:

  • ticket active;
  • exit stage absent;
  • actor authorized;
  • reason present;
  • expected ticket version matches;
  • new values satisfy flow/UOM/weight policy.

Transaction:

conditional ticket stage update
+ correction event
+ exact readback

Do not update through generic table PATCH.

10.3 PrepareScaleCheckOut

This command belongs to the relevant Order owner, not the Scale ticket.

Purpose:

  • validate/edit allowed header and item values before Scale Out;
  • save all intended owner changes atomically where approved;
  • return exact order/item snapshot and version.

Current browser-sequenced header/item writes are not the target contract.

10.4 CompleteScaleCheckOut

Input:

interface CompleteScaleCheckOutCommand {
  scaleRequestToken: string;
  scaleTicketId: string;
  expectedTicketVersion: string;
  expectedOrderSnapshotVersion?: string;
  stage: AcceptedScaleStageInput;
}

Behavior:

  1. verify entry stage exists and matches flow;
  2. verify submitted stage equals exit stage;
  3. verify ticket/link/record scope;
  4. claim request token;
  5. conditional stage update;
  6. exact totals and readback;
  7. commit;
  8. return child handoff requirements.

Result does not claim Purchase receipt or Outbound close.

10.5 FinalizePurchaseReceiptFromScale — referenced owner command

Owned by Inbound Purchase.

Input references completed Scale ticket and exact Purchase/Transload/item versions. It may update item/transload/lot state in its own accepted transaction.

Scale UI can invoke an explicit handoff, but the result remains separately labeled.

10.6 CloseOutboundFromScale — referenced owner command

Owned by Outbound Sales.

It updates accepted Outbound completion fields under Outbound policy and returns its own readback. A failure after Scale Out leaves Scale completed and Outbound close incomplete.

10.7 VoidOrReverseScaleTicket

Input:

{
  scaleRequestToken: string;
  scaleTicketId: string;
  expectedVersion: string;
  action: 'VOID' | 'REVERSE';
  reason: string;
}

Behavior:

  • authorize recovery capability;
  • classify ticket as incomplete/completed;
  • verify downstream blockers across all accepted link owners;
  • conditional soft delete;
  • event append;
  • link/projection cleanup;
  • exact residual readback;
  • commit once.

Target does not call this command DELETE in operator UI.

10.8 ReconcileScaleUnknownResult

Input: request token and any known ticket/order/link identifiers.

Result:

FOUND_COMMITTED
CONFIRMED_ABSENT_RETRY_ALLOWED
CONFLICT_MANUAL_REVIEW
UNKNOWN_MANUAL_REVIEW

It does not repeat the business command automatically.


11. Target HTTP Adapter Shape

Routes are illustrative adapters, not domain authority.

GET    /api/scale/schedule
GET    /api/scale/tickets?state=open
GET    /api/scale/tickets/{ticketId}
GET    /api/scale/tickets/{ticketId}/events
GET    /api/scale/requests/{requestToken}

POST   /api/scale/check-ins
POST   /api/scale/tickets/{ticketId}/entry-corrections
POST   /api/scale/tickets/{ticketId}/check-outs
POST   /api/scale/tickets/{ticketId}/reversals
POST   /api/scale/requests/{requestToken}/reconcile

Referenced owner adapters:

POST /api/inbound-purchases/{orderId}/finalize-from-scale
POST /api/outbound-sales/{orderId}/close-from-scale

Next.js Route Handlers own authentication/context/validation/error mapping only. They do not own Scale policy or SQL.


12. Stable Result DTOs

12.1 Check-in result

interface ScaleCheckInResult {
  requestToken: string;
  ticket: {
    id: string;
    uuid?: string;
    ticketNumber: string;
    flow: ScaleFlow;
    state: 'ENTRY_RECORDED';
    entryStage: 'GROSS' | 'TARE';
    entryAt: string;
    grossLb: string;
    tareLb: string;
    netLb: string;
  };
  order: { id: string; type: 'PURCHASE' | 'SALES'; version: string };
  link: { transloadId?: string; equipmentLoadId?: string };
}

12.2 Check-out result

interface ScaleCheckOutResult {
  requestToken: string;
  ticket: {
    id: string;
    ticketNumber: string;
    state: 'COMPLETED';
    completedAt: string;
    grossLb: string;
    tareLb: string;
    netLb: string;
  };
  downstream: {
    purchaseFinalize: 'NOT_APPLICABLE' | 'REQUIRED' | 'COMPLETED' | 'FAILED' | 'UNKNOWN';
    outboundClose: 'NOT_APPLICABLE' | 'REQUIRED' | 'COMPLETED' | 'FAILED' | 'UNKNOWN';
  };
}

12.3 Reversal result

interface ScaleReversalResult {
  requestToken: string;
  ticketId: string;
  action: 'VOIDED' | 'REVERSED';
  eventId: string;
  detachedLinks: Array<{ type: string; id: string }>;
  residualConflicts: Array<{ code: string; owner: string }>;
}

13. Stable Error Catalog

Code Meaning Safe user action
SCALE_UNAUTHENTICATED no authenticated actor sign in through normal entry
SCALE_FORBIDDEN capability denied stop; do not use copied URL/ID
SCALE_PROFILE_NOT_APPLICABLE flow/profile unavailable return to assigned profile
SCALE_FLOW_INVALID unsupported/unresolved flow confirm Purchase/Doortrade/Sales/Export
SCALE_STAGE_DIRECTION_CONFLICT submitted stage contradicts flow stop; do not write opposite stage
SCALE_ORDER_NOT_FOUND owner order absent reopen/search exact order
SCALE_ORDER_STALE owner snapshot changed refresh order/items
SCALE_ITEM_INVALID commodity/quantity/weight invalid correct item lines
SCALE_TICKET_NOT_FOUND ticket absent/inactive reread schedule/ticket
SCALE_TICKET_STALE ticket changed after open refresh detail/timeline
SCALE_ENTRY_REQUIRED Check-out lacks valid entry reconcile flow and first stage
SCALE_ENTRY_ALREADY_EXISTS duplicate/different entry reread; use correction command if allowed
SCALE_EXIT_ALREADY_EXISTS ticket already complete reread; do not reweigh through Check-out
SCALE_REWEIGH_REASON_REQUIRED correction reason missing provide bounded reason
SCALE_REWEIGH_AFTER_EXIT_FORBIDDEN completed ticket immutable use approved reversal/recovery
SCALE_WEIGHT_NEGATIVE negative axle/total correct input
SCALE_WEIGHT_ZERO_FORBIDDEN zero rejected by policy capture valid reading or approved exception
SCALE_TARE_EXCEEDS_GROSS invalid completed totals stop and verify physical values
SCALE_UOM_MISMATCH unsupported unit/context resolve canonical unit
SCALE_REQUEST_DUPLICATE same token already handled display existing result
SCALE_REQUEST_PAYLOAD_CONFLICT same token/different payload stop and reconcile
SCALE_RESULT_UNKNOWN timeout/connection loss read request/ticket/order/link before retry
SCALE_TICKET_NUMBER_CONFLICT number reservation collision server retries or returns stable conflict
SCALE_DOWNSTREAM_LOCKED reversal blocked by later work escalate to owning process
SCALE_LINK_CONFLICT ticket/order/transload/equipment disagree stop; support reconciliation
SCALE_BMS_OWNER_CONFLICT competing BMS mutation detected stop; reconcile current writer
SCALE_DEVICE_UNAVAILABLE approved device path unavailable explicit manual fallback or stop
SCALE_DEVICE_READING_UNSTABLE reading not stable wait/reacquire; do not accept silently
SCALE_SCHEMA_NOT_READY required event/idempotency schema absent no write activation
SCALE_DATA_CONFLICT persisted evidence disagrees support/manual review
SCALE_UNEXPECTED_ERROR unclassified error preserve correlation/request IDs

Raw SQL, credentials, stack traces and unrestricted device payloads are not user errors.


14. Transaction, Concurrency And Idempotency

14.1 Check-in

Target transaction:

request-token claim
+ order/create-or-save through owner contract
+ ticket insert/update
+ typed business link
+ exact readback
= one local transaction

14.2 Entry correction

expected ticket version
+ exit-stage-absent predicate
+ conditional stage update
+ correction event
+ readback
= one local transaction

14.3 Check-out

Preferred target structure:

Owner Prepare command
-> exact owner snapshot
-> Scale Check-out transaction
-> explicit owner finalize/close command

The UI may present this as one guided flow but must display independent child outcomes.

14.4 Reversal

expected ticket version
+ downstream blocker checks
+ conditional ticket soft delete
+ event append
+ link/projection cleanup
+ exact residual readback
= one local transaction

14.5 Locks and conditional writes

Current DB rules forbid FOR UPDATE. Use:

  • tenant-scoped conditional UPDATE predicates;
  • version/freshness columns or full snapshot CAS;
  • unique request token;
  • unique ticket identity/number constraints;
  • transaction boundaries;
  • bounded advisory lock only if accepted and not nested across helper owners.

14.6 Idempotency

Key:

tenant + command kind + scaleRequestToken

Same token/same payload returns the committed result. Same token/different payload returns conflict.

Ticket-stage local same-value repeat is useful but is not enough when a lost response could also include order/link/finalize effects.


15. Exception And Recovery Matrix

ID Situation Required reread Safe recovery Must not repeat
SCALE-EXC-010 Check-in response lost request token, ticket by order/link, order/items, link return existing result or retry only if confirmed absent complete Check-in payload blindly
SCALE-EXC-020 Check-in local transaction rejected order/items/ticket/link correct input and submit new/approved request assume partial commit without evidence
SCALE-EXC-030 Sales/Export Gross/Tare direction mismatch flow, ticket stages, board, detail stop; characterize and fix flow contract Check-out using guessed opposite stage
SCALE-EXC-040 Reweigh response lost ticket stage, event timeline, request token return existing correction or retry confirmed absent second correction with new reason automatically
SCALE-EXC-050 Header saved, later Check-out item save failed header and every item correct/resume owner Save only Scale Out
SCALE-EXC-060 Owner Save complete, Scale Out absent order/items, ticket stages submit Scale Out if confirmed absent and still intended owner Save batch
SCALE-EXC-070 Scale Out committed, Outbound close failed ticket detail, Outbound order Outbound owner resumes close Scale Out
SCALE-EXC-080 Scale Out committed, Purchase finalize failed ticket detail, Purchase/Transload/Lot Inbound owner resumes finalize Check-out
SCALE-EXC-090 30-second timeout request token, ticket/detail, links, owner rows classify committed/absent/conflict timed-out command before reread
SCALE-EXC-100 Ticket-number collision request result and existing ticket by token server reservation retry or manual review client-generated alternate number
SCALE-EXC-110 BMS PATCH changed YMS ticket ticket, event timeline, BMS audit, links freeze writes; reconcile owner YMS correction until classified
SCALE-EXC-120 BMS delete detached only part of links ticket lifecycle, Transload, Equipment Load, Order controlled reconciliation generic recreate/delete
SCALE-EXC-130 Device disconnect before acceptance device session/readings reconnect or explicit manual input assume displayed stale value
SCALE-EXC-140 Device disconnect after accepted command request/ticket readback use committed business evidence repeat device/business submission
SCALE-EXC-150 Completed ticket omitted from board known ID, exact detail/events show completed readback infer deletion/failure from absence
SCALE-EXC-160 Reversal blocked by downstream work all blocker records escalate to owner-specific correction plan direct soft delete/link clear
SCALE-EXC-170 Demo card mistaken for operational record ticket/order IDs and demo flag close demo UI; no business action submit Production-like recovery
SCALE-EXC-180 Print wrong/missing ticket detail and print URL reprint same verified ticket mutate ticket/order to fix print

16. UI / UX Contract

16.1 React Scale Workspace areas

Schedule / Search
Active Tickets
Check-in Workspace
Check-out Workspace
Completed Ticket Readback
Timeline / Recovery
Device Status (only when approved)

16.2 Required visible states

Loading
Empty — no operational rows
Denied
Profile unavailable
Device unavailable
Device unstable
Record stale
Flow/stage conflict
Check-in submitting
Check-in result unknown
Entry recorded
Reweigh reason required
Check-out preparation partial
Check-out submitting
Scale completed / downstream pending
Scale completed / Outbound close failed
Scale completed / Purchase finalize failed
Reversal blocked
Void/Reversal completed
Completed detail

16.3 Demo behavior

Demo content must be an explicit test/demo mode, not silently injected into an empty operational board.

Operational empty state
!= interactive demo ticket

16.4 Readback panel

After each write, show:

  • ticket ID/number;
  • flow;
  • stage and time;
  • Gross/Tare/Net;
  • order ID/number;
  • Transload or Equipment Load link;
  • event ID for correction/reversal;
  • downstream disposition;
  • request/correlation reference;
  • next safe action.

16.5 Accessibility and mobile

  • stage/flow not color-only;
  • input labels and validation are field-local;
  • keyboard submission does not double-submit;
  • readback is screen-reader announced;
  • unknown result is not displayed as generic failure;
  • no required hover-only controls;
  • completed/reversal history is readable on narrow screens.

17. Current Caller And Consumer Map

17.1 Current writers

YMS Scale Portal
-> /api/yms/scale/check-in/execute
-> /api/yms/scale/check-in
-> /api/yms/scale/check-out
-> /api/yms/scale/purchase-inbound/finalize
-> /api/yms/scale/tickets/{id} DELETE

BMS Scale Ticket
-> generic create
-> PATCH
-> DELETE
-> Closing
-> Outbound Weight Apply

17.2 Current readers/consumers

  • YMS Schedule and active board;
  • YMS exact detail and event timeline;
  • Inbound Purchase and Transload link;
  • Outbound Equipment Load and order ticket projection;
  • Inventory receipt/finalize;
  • BMS billing/transaction surfaces;
  • physical-ticket print;
  • Sales Weight Ticket output;
  • reports/history and operational support.

17.3 Caller-zero requirement

Before PHP retirement:

  • all YMS read/write callers route through accepted application contracts;
  • BMS generic create/PATCH/delete no longer mutates YMS-owned MK tickets or has an explicit separate scope proven by caller/record rules;
  • direct physical print uses target read adapter or accepted stable compatibility route;
  • no direct T_SCALE_TICKET business mutation remains outside owner repositories;
  • no current UI relies on demo injection or hidden string actions;
  • Process/Runbook/Wiki point to target routes.

18. Target Component Map

React Scale Workspace
  ├─ ScheduleView
  ├─ ActiveTicketBoard
  ├─ CheckInForm
  ├─ CheckOutForm
  ├─ CompletedTicketReadback
  ├─ TicketTimeline
  └─ DeviceStatusPanel (optional)
          ↓
Next.js Server Components / Route Handlers
          ↓
ScaleQueryApplication
ScaleCheckInApplication
ScaleCheckOutApplication
ScaleCorrectionApplication
ScaleReversalApplication
          ↓
ScaleFlowPolicy
ScaleWeightPolicy
ScaleRecoveryPolicy
          ↓
ScaleTicketRepository
ScaleTicketEventRepository
ScaleRequestRepository
OrderLinkAdapters
          ↓
MySQL

Optional device path:

Device Adapter
-> Device Session/Reading Store or bounded in-memory channel
-> accepted reading DTO
-> Scale Application

React owns presentation and interaction. It does not own stage direction, weight policy, idempotency or SQL.


19. Migration And Cutover

19.1 Waves

SCALE-W0  Source/schema/role/device/caller characterization
SCALE-W1  Flow-stage policy acceptance and regression repair
SCALE-W2  TypeScript read models and completed timeline
SCALE-W3  React + Next.js read-only Workspace
SCALE-W4  Request identity and integrated Check-in one-writer
SCALE-W5  Checkout preparation and Scale Out one-writer
SCALE-W6  Explicit Purchase finalize / Outbound close dispositions
SCALE-W7  Reweigh and reversal one-writer
SCALE-W8  Device adapter, only if approved
SCALE-W9  BMS competing-writer retirement
SCALE-W10 Target-role stabilization, Wiki and observation
SCALE-W11 PHP caller-zero
SCALE-W12 PostgreSQL later

19.2 One-writer rule

For one ticket/request/cohort:

one authoritative Scale writer

No PHP/TypeScript dual write. No YMS/BMS concurrent owner ambiguity.

19.3 Read shadow

Before write cutover compare:

  • Schedule rows;
  • flow classification;
  • open ticket classification;
  • completed detail;
  • Gross/Tare/Net;
  • order/transload/equipment links;
  • event timeline;
  • allowed actions and blockers.

19.4 Rollback

Rollback may:

  • route new writes back to the prior accepted writer;
  • stop new target writes;
  • preserve committed tickets/events/links;
  • reconcile in-flight request tokens;
  • keep target read-only diagnostics.

Rollback must not:

  • delete or recreate committed tickets;
  • replay unknown stages;
  • erase correction/reversal events;
  • manually swap Gross/Tare values;
  • restore BMS generic writer without reconciling ownership;
  • dual-write.

20. PostgreSQL Preservation

Later PostgreSQL design preserves:

  • tenant-first identity and uniqueness;
  • ticket UUID and display number distinction;
  • exact numeric/weight precision;
  • explicit canonical UOM;
  • stage snapshots and physical event times;
  • immutable correction/reversal events;
  • request-token idempotency;
  • conditional/versioned writes;
  • typed Purchase/Transload and Sales/Equipment links;
  • soft delete and retention;
  • no generic table mutation authority.

Do not infer PostgreSQL types from current PHP casts alone.


21. Policy Decision Register

ID Decision required Current source Recommended direction Blocks
SCALE-POL-010 Gross/Tare direction per flow UI and Check-in endpoint conflict accept explicit profile policy and fix all callers/tests every write wave
SCALE-POL-020 Other/Walk-In flow fallback only remove from MK normal path or define explicit policy UI/API/Wiki
SCALE-POL-030 zero-weight policy currently false forbid by default; explicit exceptional command only if business requires validation
SCALE-POL-040 manual versus device reading manual current preserve manual; add device only with provenance/session device wave
SCALE-POL-050 physical event time DB NOW current server accepted time + optional device captured time data model
SCALE-POL-060 Check-out owner pre-save sequential current atomic owner preparation command checkout migration
SCALE-POL-070 Outbound close after Scale separate current explicit child result/recovery UI/Runbook
SCALE-POL-080 Purchase finalize after Scale separate current explicit owner handoff/result UI/Runbook
SCALE-POL-090 reweigh authority same menu currently separate semantic capability and reason access
SCALE-POL-100 void/reversal authority YMS guarded, BMS unguarded YMS owner command only; BMS disposition required recovery
SCALE-POL-110 BMS generic writer competing owner retire for MK YMS tickets or strictly separate record scope caller-zero
SCALE-POL-120 ticket number reservation latest+1 request-bound atomic reservation concurrency
SCALE-POL-130 completed ticket UX leaves board durable completed detail/timeline UI/Wiki
SCALE-POL-140 demo rows auto-injected explicit demo mode only operator safety
SCALE-POL-150 signatures/bad-bale fields legacy shared table separate owner/retention decision schema/UI
SCALE-POL-160 per-action role matrix module/menu current semantic capabilities plus current compatibility mapping activation

No recommendation is Product approval.


22. Stable Verification Scenarios

22.1 Flow direction

SCALE-SCN-010  Purchase Gross Check-in -> Tare Check-out
SCALE-SCN-020  Doortrade Gross Check-in -> Tare Check-out
SCALE-SCN-030  Sales Tare Check-in -> Gross Check-out
SCALE-SCN-040  Export Tare Check-in -> Gross Check-out
SCALE-SCN-050  Opposite-stage Check-in rejected
SCALE-SCN-060  Opposite-stage Check-out rejected

22.2 Check-in

SCALE-SCN-110  Existing order integrated Check-in
SCALE-SCN-120  Walk-in order + Check-in atomic success
SCALE-SCN-130  Middle item validation failure rolls back all
SCALE-SCN-140  Ticket insert failure rolls back order/items
SCALE-SCN-150  Duplicate request token returns same result
SCALE-SCN-160  Response lost after commit
SCALE-SCN-170  Concurrent ticket-number reservation
SCALE-SCN-180  Foreign tenant / denied role / direct URL

22.3 Reweigh

SCALE-SCN-210  Same entry repeat returns existing result
SCALE-SCN-220  Changed entry requires reason
SCALE-SCN-230  Correction records event and before/after snapshot
SCALE-SCN-240  Concurrent stale correction rejected
SCALE-SCN-250  Reweigh after exit rejected
SCALE-SCN-260  Correction response loss reconciled

22.4 Check-out and downstream

SCALE-SCN-310  Normal completed ticket
SCALE-SCN-320  Missing entry rejected
SCALE-SCN-330  Negative/zero/Tare>Gross rejected
SCALE-SCN-340  Sequential owner Save middle failure; no Scale Out
SCALE-SCN-350  Scale Out success / Outbound close failure
SCALE-SCN-360  Scale Out success / Purchase finalize failure
SCALE-SCN-370  Check-out response loss
SCALE-SCN-380  Completed ticket exact detail/timeline

22.5 Reversal and competing writers

SCALE-SCN-410  Void uncompleted ticket
SCALE-SCN-420  Reverse completed ticket without downstream work
SCALE-SCN-430  Reversal blocked by Transload/Inventory/Delivery
SCALE-SCN-440  Reversal response loss
SCALE-SCN-450  BMS PATCH conflict detected
SCALE-SCN-460  BMS delete residual-link detection

22.6 Device and print

SCALE-SCN-510  Manual entry normal
SCALE-SCN-520  Device stable reading accepted
SCALE-SCN-530  Device unstable reading blocked
SCALE-SCN-540  Device disconnect before acceptance
SCALE-SCN-550  Device disconnect after commit
SCALE-SCN-560  Physical ticket tenant/active scope
SCALE-SCN-570  Print failure does not mutate ticket
SCALE-SCN-580  Empty operational board has no interactive demo rows

Device scenarios remain NOT APPLICABLE / NOT RUN until a device contract is approved.

22.7 Migration

SCALE-MIG-SCN-010  Schedule read parity
SCALE-MIG-SCN-020  Flow classification parity
SCALE-MIG-SCN-030  Ticket/detail/event parity
SCALE-MIG-SCN-040  Integrated Check-in one-writer
SCALE-MIG-SCN-050  Check-out one-writer
SCALE-MIG-SCN-060  Downstream child result parity
SCALE-MIG-SCN-070  Reweigh/reversal parity
SCALE-MIG-SCN-080  Unknown-result rollback/reconcile
SCALE-MIG-SCN-090  BMS competing-writer caller-zero
SCALE-MIG-SCN-100  PHP caller-zero
SCALE-MIG-SCN-110  PostgreSQL parity

23. Evidence Template

For each scenario record:

scenario ID
source/release SHA
environment and DB identity
tenant/profile
actor/role/capability
normal menu entry
flow and expected stage direction
order/item/transload/equipment/ticket IDs
request token and request/correlation ID
device/manual source
before ticket/order/link/event state
submitted stage values and UOM
API status/result
exact ticket/detail/event readback
exact owner/link/downstream readback
UI visible result
console/network evidence
cleanup and zero residue
result: PASS / FAIL / BLOCKED / NOT RUN

Do not use Production for destructive, cross-tenant or device-fault injection.


24. Definition Of Ready

A Scale implementation wave is not ready until:

  • SCALE-POL-010 flow direction is accepted;
  • current Sales/Export contradiction is characterized and resolved in plan;
  • target roles/capabilities/record scope are accepted;
  • exact schema and indexes are verified;
  • request identity/version strategy is accepted;
  • ticket number reservation is defined;
  • BMS competing-writer disposition is accepted;
  • Check-out owner-preparation boundary is defined;
  • Purchase finalize and Outbound close child contracts are accepted;
  • reversal/downstream-lock policy is accepted;
  • device work is explicitly in or out;
  • rollback and evidence fixtures exist;
  • CTC regression scope is defined.

25. Definition Of Complete

The capability is not complete until:

  • all four accepted flows pass normal and negative scenarios;
  • exact Check-in/Check-out readback is visible;
  • timeout/duplicate does not duplicate business state;
  • reweigh/reversal lineage is immutable and visible;
  • no competing BMS writer remains for the same MK ticket scope;
  • Purchase/Outbound child failures are recoverable without Scale replay;
  • target roles pass menu/page/API/record tests;
  • current Wiki is updated and field-reviewed;
  • one writer and rollback are proven;
  • PHP caller-zero is proven;
  • Production observation is separately authorized and completed;
  • PostgreSQL remains a later separately accepted wave.

---

Source: docs/reconstruction/MK_PHYSICAL_SCALE_CAPABILITY_REBUILD_PACKET.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.