API v2 Contract Inventory¶
- Status:
DATED CURRENT-FACT / EVIDENCE INPUT - Captured/refreshed:
2026-04-30 / 2026-06-30 KST - Does not own: current migration status, Task order, React adoption or activation
- Current contract:
.agents/rules/API_CONTRACTS.md
Purpose¶
This file preserves the captured migration inventory for the former feature
436/task #456. It maps legacy TYPE / ACTION contracts to the API v2 route¶
surface observed at the recorded dates.
The shared app/controllers/query.php and app/controllers/post.php
entrypoints were deleted in #454 after the recorded caller scans passed.
The counts below are dated evidence and require a fresh source scan before use.
Baseline¶
Captured on 2026-04-30 KST from the current workspace.
| Signal | Count / State |
|---|---|
Module-owned query.php / post.php shells under app/systems |
23 |
KJ.api.query runtime callers |
107 |
KJ.api.post runtime callers |
81 |
/app/controllers/query.php direct string callers |
34 |
/app/controllers/post.php direct string callers |
17 |
KJ.config.url.query callers |
21 |
KJ.config.url.post callers |
12 |
Current #454 state:
| Signal | State |
|---|---|
KJ.api.query/post/queryPost active runtime callers |
0 |
KJ.config.url.query/post active runtime callers |
0 |
/app/controllers/query.php and /app/controllers/post.php active runtime callers |
0 |
app/controllers/query.php and app/controllers/post.php files |
deleted |
Current 2026-06-30 state:
| Signal | Count / State |
|---|---|
API v2 route definitions loaded from api_routes.php files |
437 |
| API v2 route files | 29 |
Module-owned legacy query.php / post.php shells under app/systems |
22 |
Inventory rows marked migrated |
115 |
Inventory rows marked done |
2 |
Inventory rows marked defer |
9 |
Inventory rows marked migrate |
0 |
Active KJ.api.query/post/queryPost callers |
0 |
Active KJ.config.url.query/post callers |
0 |
Active /app/controllers/query.php / /app/controllers/post.php string callers |
0 |
Remaining non-API-v2 controller callers/surfaces are specialized controllers, not shared TYPE/ACTION blockers: excel.php active export callers are classified in #1081; gmail.php and chatgpt.php remain specialized/compatibility surfaces. media.php and sync.php remain only as temporary compatibility surfaces; active app callers use /api/files/media/* and /api/platform/sync/checksums. master.php and autocomplete.php were removed in #1088 after active callers were confirmed on owner API v2 lookup routes.
Primary hotspots:
| File / Area | Legacy call count | Migration owner |
|---|---|---|
public/assets/js/modules/shared/popup.core.js |
75 | #453 |
frontend/pages/system/TMS/transload/appointment.php |
16 | #443 |
public/assets/js/modules/shared/kjtable.core.js |
14 | #450, #452, #453 |
frontend/pages/system/TMS/delivery/driver-operation.php |
13 | #445 |
frontend/pages/platform/admin-console/tenants.php |
10 | #451 |
public/assets/js/modules/shared/mk-outbound-order-editor.js |
10 | #447 |
frontend/pages/system/YMS/yard-map/yard-map.php |
8 | #439, #440 |
public/assets/js/photo.js |
7 | #452 |
API v2 Rules¶
- New API v2 request bodies must not use
TYPE,ACTION, orUSERNAME. - New API v2 routes enter through
/api/...andapi/index.php. - New API v2 route definitions belong in
app/platform/api_routes.php,app/shared/*/api_routes.php,app/addons/*/api_routes.php, orapp/systems/*/*/api_routes.phpand are loaded by the API entrypoint. - New API v2 responses use
{ "data": ..., "requestId": "..." }on success. - New API v2 errors use
{ "error": { "code": "...", "message": "..." }, "requestId": "..." }. - Route definitions carry the module key directly; API v2 must not depend on
moduleGuardEndpointModuleKey(). - API v2 response helpers must preserve binary-safe JSON behavior equivalent to
JSON_INVALID_UTF8_SUBSTITUTE. - API v2 writes must preserve
KJDatabasemutation audit behavior, transaction boundaries, and sync task behavior where existing writes have it. - API v2 read paths must not bypass active/soft-delete filters introduced by the UUIDv7 / soft-delete foundation.
- File APIs must preserve #460 hybrid EFS/S3 behavior through
app/shared/storage/file_storage.php. - React callers must use the domain client pattern in
.agents/rules/REACT_API_CLIENT.md; no new generic post/query client is allowed.
Status values:
| Status | Meaning |
|---|---|
migrate |
Create explicit API v2 route and migrate active callers. |
migrated |
Explicit API v2 route is active, listed callers are migrated, and the matching shared-controller branch has been removed. |
delete |
Remove or replace the flow; do not create a v2 route. |
defer |
Keep outside #436 cutover until a separate owner/task is approved. Must have a reason. |
React Client Foundation¶
Task #438 defines the future client layout because no React scaffold exists in the current repository.
| Contract area | Decision |
|---|---|
| Future root | frontend/react/src/api/ |
| Base helper | http.ts owns JSON fetch, credentials, envelope parsing, and request id extraction |
| Error model | ApiError carries status, code, message, requestId, and details |
| Domain clients | yms/yardMap, yms/yardMoves, tms/transloads, wms/inventory, oms/outboundOrders |
| Forbidden | Any helper shaped like post(type, action, data) or query(type, action, data) |
Source of truth: .agents/rules/REACT_API_CLIENT.md.
Runtime Contract¶
Task #437 established the initial runtime shell:
| Contract area | Implementation |
|---|---|
| HTTP entry | /api/... via api/index.php |
| Shared helpers | app/shared/api/request.php, response.php, runtime.php, router.php |
| Route ownership | app/platform/api_routes.php, app/shared/*/api_routes.php, app/addons/*/api_routes.php, and app/systems/*/*/api_routes.php files |
| Auth | existing PHP session, requiring login_username |
| Tenant/module gate | explicit route moduleKey and getClientId() |
| Success envelope | { "data": ..., "requestId": "..." } |
| Error envelope | { "error": { "code": "...", "message": "..." }, "requestId": "..." } |
| Method handling | unsupported method returns HTTP 405 with Allow |
| JSON body parsing | invalid JSON returns HTTP 400 INVALID_JSON |
| Transactions | apiWithTransaction(KJDatabase $db, callable $callback) |
Active API v2 routes:
| Route | Method | Module key |
|---|---|---|
/api/platform/ping |
GET, POST | none |
/api/platform/account/password |
PATCH | none |
/api/platform/sync/checksums |
GET | none |
/api/platform/menu/* |
GET, POST, PATCH, DELETE | platform.menu |
/api/platform/module-pages |
GET | none |
/api/platform/users* |
GET, POST, PATCH | none |
/api/platform/companies |
GET, POST | none |
/api/platform/companies/form |
POST, PATCH | none |
/api/platform/companies/{id} |
GET | none |
/api/platform/master-data/form |
POST, PATCH | none |
/api/platform/master-data/row |
GET | none |
/api/platform/operation-events |
GET, POST | none |
/api/platform/operation-events/count |
GET | none |
/api/platform/operation-events/{uuid}/ack |
PATCH | none |
/api/addons/telegram/messages |
POST | addon.telegram |
/api/addons/ai-verifications/ingate-ticket/ai-extract |
POST | addon.reports |
/api/platform/telegram/send |
POST | none |
/api/platform/admin/* |
GET, POST, PATCH | none |
/api/platform/admin/logs/codex |
GET | none |
/api/quickbooks-time/connect |
GET | none |
/api/quickbooks-time/callback |
GET | none |
/api/quickbooks-time/disconnect |
POST | none |
/api/yms/yard-map/ping |
GET | yms.yard-map |
/api/yms/yard-map/sections |
GET | yms.yard-map |
/api/yms/yard-map/state |
GET | yms.yard-map |
/api/yms/yard-moves/dispatch-queue |
GET | yms.yard-move |
/api/yms/yard-moves/returning-empty |
GET | yms.yard-move |
/api/yms/yard-moves/assignable-users |
GET | yms.yard-move |
/api/yms/yard-moves/unmapped-entities |
GET | yms.yard-move |
/api/yms/yard-locations/occupied-items |
GET | yms.yard-move |
/api/yms/yard-locations/available |
GET | yms.yard-move |
/api/yms/yard-locations/stack-groups |
GET | yms.yard-move |
/api/yms/yard-locations/available-by-stack-group |
GET | yms.yard-move |
/api/yms/yard-moves/preview |
POST | yms.yard-move |
/api/yms/yard-locations/reset |
POST | yms.yard-move |
/api/yms/yard-locations/move |
POST | yms.yard-move |
/api/yms/yard-locations/vacate |
POST | yms.yard-move |
/api/yms/yard-moves/queue |
POST, PATCH | yms.yard-move |
/api/yms/yard-moves/queue/relocate-before-pull-out |
POST | yms.yard-move |
/api/yms/yard-moves/queue-after-clear |
POST | yms.yard-move |
/api/yms/yard-moves/queue/reorder |
POST | yms.yard-move |
/api/yms/yard-moves/queue/cancel |
POST | yms.yard-move |
/api/yms/yard-moves/queue/claim |
POST | yms.yard-move |
/api/yms/yard-moves/queue/unclaim |
POST | yms.yard-move |
/api/yms/yard-moves/queue/confirm |
POST | yms.yard-move |
/api/yms/yard-moves/dispatch/complete |
POST | yms.yard-move |
/api/yms/containers/mobile |
GET | yms.container-tracking |
/api/yms/containers/empty |
GET | yms.container-tracking |
/api/yms/yard-containers |
GET | yms.container-tracking |
/api/yms/equipment-loads/search |
GET | yms.container-tracking |
/api/yms/equipment-loads/{id}/container-detail |
GET | yms.container-tracking |
/api/yms/equipment-loads/container-details |
GET | yms.container-tracking |
/api/yms/containers/by-delivery |
GET | yms.container-tracking |
/api/yms/containers/by-equipment-load |
GET | yms.container-tracking |
/api/yms/containers/by-deliveries |
GET | yms.container-tracking |
/api/yms/equipment/by-delivery |
GET | yms.container-tracking |
/api/yms/equipment-information/{id} |
GET | yms.container-tracking |
/api/yms/equipment-information/form |
POST, PATCH | yms.container-tracking |
/api/yms/equipment/{id}/repair-logs |
GET | yms.container-tracking |
/api/yms/containers/validate-numbers |
POST | yms.container-tracking |
/api/yms/containers/validate-full-ready |
POST | yms.container-tracking |
/api/yms/containers/form |
POST, PATCH | yms.container-tracking |
/api/yms/containers/seal-photo/ai-extract |
POST | yms.container-tracking |
/api/yms/containers/street-turn |
POST | yms.container-tracking |
/api/yms/containers/return-bookings |
PATCH | yms.container-tracking |
/api/yms/containers/mobile/{id}/empty-weight |
PATCH | yms.container-tracking |
/api/yms/equipment-repair-logs/{id} |
GET | yms.container-tracking |
/api/yms/dock-scheduling/available-docks |
GET | yms.dock-scheduling |
/api/yms/dock-scheduling/available-yard-locations |
GET | yms.dock-scheduling |
/api/yms/dock-scheduling/planning-yard-locations |
GET | yms.dock-scheduling |
/api/yms/dock-scheduling/appointments |
GET | yms.dock-scheduling |
/api/yms/scale/schedule |
GET | yms.scale |
/api/yms/scale/tickets |
GET | yms.scale |
/api/yms/scale/tickets/{id} |
GET, DELETE | yms.scale |
/api/yms/scale/check-in |
POST, PATCH | yms.scale |
/api/yms/scale/check-out |
POST | yms.scale |
/api/yms/scale/purchase-inbound/walk-in |
POST | yms.scale |
/api/yms/scale/purchase-inbound/finalize |
POST | yms.scale |
/api/tms/transloads/planning-board |
GET | tms.transload |
/api/tms/transloads |
GET | tms.transload |
/api/tms/transloads/form |
POST, PATCH | tms.transload |
/api/tms/transloads/load-to-load-reconcile |
POST | tms.transload |
/api/tms/transloads/{id} |
GET | tms.transload |
/api/tms/transloads/{id}/scale-ticket |
PATCH | tms.transload |
/api/tms/transloads/load-schedule/ai-extract |
POST | tms.transload |
/api/tms/transloads/export-schedule/ai-extract |
POST | tms.transload |
/api/tms/transloads/load-schedule/ai-prompt |
GET, PATCH | tms.transload |
/api/tms/loading-planner/{id} |
GET, PATCH, DELETE | tms.transload |
/api/tms/equipment-loads/{id}/transloads |
GET | tms.transload |
/api/tms/transloads/plan-preview |
POST | tms.transload |
/api/tms/transloads/plan-apply |
POST | tms.transload |
/api/tms/transloads/assign-submit |
POST | tms.transload |
/api/tms/transloads/loader-assignment |
POST, PATCH | tms.transload |
/api/tms/transloads/loader-telegram |
POST | tms.transload |
/api/tms/transloads/confirm-plan |
POST | tms.transload |
/api/tms/transloads/plan |
PATCH | tms.transload |
/api/tms/transloads/check-in |
POST | tms.transload |
/api/tms/transloads/mobile-check-in |
POST | tms.transload |
/api/tms/transloads/dock-in |
POST | tms.transload |
/api/tms/transloads/dock-in-after-clear |
POST | tms.transload |
/api/tms/transloads/stage |
PATCH | tms.transload |
/api/tms/transloads/start-transloading |
POST | tms.transload |
/api/tms/transloads/start-unloading |
POST | tms.transload |
/api/tms/transloads/complete-transloading |
POST | tms.transload |
/api/tms/transloads/complete-unloading |
POST | tms.transload |
/api/tms/transloads/complete-unloading-spare |
POST | tms.transload |
/api/tms/transloads/complete-spare |
POST | tms.transload |
/api/tms/transloads/undo |
POST | tms.transload |
/api/tms/transloads/doc-submitted |
PATCH | tms.transload |
/api/tms/transloads/driver-contacted |
PATCH | tms.transload |
/api/tms/transloads/dispatch |
POST | tms.transload |
/api/tms/transloads/cancel |
POST | tms.transload |
/api/tms/transloads/no-show |
POST | tms.transload |
/api/tms/transloads/domestic-dock-plan |
PATCH | tms.transload |
/api/tms/transload-emails/reschedule-decision |
GET | tms.transload |
/api/tms/transload-emails/approval-queue |
GET | tms.transload |
/api/tms/transload-emails/outbound-queue |
GET | tms.transload |
/api/tms/transload-emails/reschedule-apply |
POST | tms.transload |
/api/tms/transload-emails/approval-submit |
POST | tms.transload |
/api/tms/transload-emails/create-confirmation-reply |
POST | tms.transload |
/api/tms/transload-emails/item-process |
POST | tms.transload |
/api/tms/transloads/{id}/load-label |
GET | tms.transload |
/api/tms/transloads/{id}/load-label/warehouse-location |
PATCH | tms.transload |
/api/tms/transload-planner/events |
GET | tms.transload |
/api/tms/transload-planner/events/{id} |
PATCH | tms.transload |
/api/tms/loading-planner |
POST | tms.transload |
/api/tms/loading-planner/form |
POST, PATCH | tms.transload |
/api/tms/loading-planner/{id} |
GET, PATCH, DELETE | tms.transload |
/api/tms/transload-appointment-blocks |
GET, POST, DELETE | tms.transload |
/api/tms/transload-timeblocks/status |
GET | tms.transload |
/api/tms/deliveries |
GET | tms.delivery |
/api/tms/deliveries/form |
POST, PATCH | tms.delivery |
/api/tms/deliveries/{id} |
GET | tms.delivery |
/api/tms/deliveries/{id}/arrival-signal |
POST | tms.delivery |
/api/tms/deliveries/{id}/arrival-action |
PATCH | tms.delivery |
/api/tms/deliveries/{id}/location-ping |
POST | tms.delivery |
/api/tms/bookings |
GET, POST | tms.booking |
/api/tms/bookings/booking-instruction/ai-extract |
POST | tms.booking |
/api/tms/bookings/booking-instruction/ai-prompt |
GET, PATCH | tms.booking |
/api/tms/bookings/form |
POST, PATCH | tms.booking |
/api/tms/bookings/{id} |
GET, PATCH | tms.booking |
/api/tms/carriers/{id} |
GET | tms.carrier |
/api/tms/carriers/form |
POST, PATCH | tms.carrier |
/api/oms/commercial-orders/options |
GET | oms.commercial-order |
/api/oms/commercial-orders |
GET, POST | oms.commercial-order |
/api/oms/commercial-orders/{id} |
GET, PATCH, DELETE | oms.commercial-order |
/api/oms/inbound-orders/options |
GET | oms.inbound-order |
/api/oms/inbound-orders/doortrade-packing-list/ai-extract |
POST | oms.inbound-order |
/api/oms/inbound-orders |
GET, POST | oms.inbound-order |
/api/oms/inbound-orders/schedule |
GET | oms.inbound-order |
/api/oms/inbound-orders/calendar-events |
GET | oms.inbound-order |
/api/oms/inbound-orders/{id} |
GET, PATCH, DELETE | oms.inbound-order |
/api/oms/inbound-orders/{id}/atomic-save |
POST | oms.inbound-order |
/api/oms/inbound-orders/{id}/complete-without-scale |
POST | oms.inbound-order |
/api/oms/inbound-orders/{id}/items |
POST | oms.inbound-order |
/api/oms/inbound-orders/{id}/items/{itemId} |
PATCH, DELETE | oms.inbound-order |
/api/oms/customer-pos/by-load-numbers |
POST | oms.inbound-order |
/api/oms/customer-pos |
POST | oms.inbound-order |
/api/oms/customer-pos/form |
POST, PATCH | oms.inbound-order |
/api/oms/customer-pos/{id} |
GET | oms.inbound-order |
/api/oms/customer-pos/{id}/items |
GET | oms.inbound-order |
/api/bms/fuel/{id} |
GET | bms.transaction |
/api/bms/fuel/form |
POST, PATCH | bms.transaction |
/api/oms/outbound-orders/options |
GET | oms.outbound-order |
/api/oms/outbound-orders |
GET, POST | oms.outbound-order |
/api/oms/outbound-orders/schedule |
GET | oms.outbound-order |
/api/oms/outbound-orders/{id} |
GET, PATCH | oms.outbound-order |
/api/oms/outbound-orders/{id}/items |
POST | oms.outbound-order |
/api/oms/outbound-orders/{id}/items/{itemId} |
PATCH, DELETE | oms.outbound-order |
/api/oms/outbound-orders/{id}/costs |
GET, POST | oms.outbound-order |
/api/oms/outbound-orders/{id}/costs/{transactionId} |
DELETE | oms.outbound-order |
/api/oms/export-brokerage/documents/ai-extract |
POST | oms.outbound-order + oms.inbound-order |
/api/oms/allocations/workbench |
GET | oms.allocation |
/api/oms/allocations/target-shipments |
GET | oms.allocation |
/api/oms/allocations/apply |
POST | oms.allocation |
/api/oms/trade-summary |
GET | oms.trade-summary |
/api/oms/trade-summary/{equipmentId} |
GET | oms.trade-summary |
/api/oms/deal-ledger |
GET | oms.trade-summary |
/api/oms/deal-ledger/{equipmentId} |
GET | oms.trade-summary |
/api/wms/inbound/transloads/check-in-list |
GET | wms.inbound |
/api/wms/inbound/transloads/completed |
GET | wms.inbound |
/api/wms/inbound/imports/transload |
POST | wms.inbound |
/api/wms/inbound/imports/delivery-orders |
POST | wms.inbound |
/api/wms/inbound/import-delivery-orders/ai-extract |
POST | wms.inbound |
/api/wms/inbound/import-delivery-orders/ai-prompt |
GET, PATCH | wms.inbound |
/api/wms/inventory/lots |
GET | wms.inventory |
/api/wms/inventory/lots/{id} |
GET, PATCH | wms.inventory |
/api/wms/inventory/lots/{id}/adjust |
POST | wms.inventory |
/api/wms/inventory/report |
GET | wms.inventory |
/api/wms/storage/by-company |
GET | wms.inventory |
Exact Legacy Type Coverage¶
The route tables below intentionally group some legacy types by module family. This table makes the exact active type coverage explicit for scan/review purposes.
| Covered by route table row | Exact legacy types / prefixes |
|---|---|
| Platform/admin | ACCOUNT, CHECK_USERNAME, COMPANY_LIST, MENU, SUPER_ADMIN, TEMP_COMPANY_LIST, USER_ROLE_LIST, MASTER_LIST, CHASSIS_LIST, COMMODITY_LIST, DRIVER_LIST |
| Shared file/media/report/add-ons | AI_VERIFICATION, INGATE_TICKET, FILE, REPORT, MONTHLY_INVENTORY_REPORT, ACCUMULATIVE_INVENTORY_REPORT, INVENTORY_REPORT, STORAGE_BY_COMPANY, MK_DAILY_, MK_DAILY_COMMODITY_REPORT, MK_DAILY_DASHBOARD, TRUCKING_SUMMARY_REPORT, TELEGRAM |
| YMS yard map/move | YARD_MAP, YARD_LOCATION, YARD_DISPATCH_PREVIEW, YARD_DISPATCH_ASSIGNABLE_USER_LIST, YARD_UNMAPPED_ENTITY_LIST, RESET_YARD |
| YMS container/dock/scale | MOBILE_CONTAINER, MOBILE_CONTAINER_LIST, MOBILE_EMPTY_CONTAINER_LIST, CONTAINER_BY_DELIVERY_ID, CONTAINER_BY_DELIVERY_IDS, CONTAINER_BY_EQUIPMENT_LOAD_ID, EDIT_CONTAINER_DATA, EDIT_MULTI_CONTAINER_DATA, EQUIPMENT_BY_DELIVERY_ID, EQUIPMENT_REPAIR_LOG_LIST, VALIDATE_CONTAINER_NUMBERS, VALIDATE_FULL_READY_BY_EQUIPMENT_LOAD_IDS, YARD_CONTAINER_LIST, CONTAINER_SEAL_PHOTO, MOBILE_APPOINTMENT_LIST, MOBILE_AVAILABLE_DOCK_LIST, MOBILE_AVAILABLE_YARD_LIST, MOBILE_PLANNING_YARD_LIST, YMS_SCALE, YMS_SCALE_DETAIL, YMS_SCALE_LIST, YMS_SCALE_SCHEDULE_LIST |
| TMS transload/planning/email | TRANSLOAD, MOBILE_TRANSLOAD, TRANSLOAD_PLANNER, TRANSLOAD_APPOINTMENT_BLOCK, TRANSLOAD_TIMEBLOCK_STATUS, TRANSLOAD_EMAIL_RESCHEDULE_DECISION, TRANSLOAD_EMAIL_APPROVAL_QUEUE, TRANSLOAD_EMAIL_OUTBOUND_QUEUE, OCCUPIED_TRANSLOAD_TIME, TRANSLOAD_LIST_BY_EQUIPMENT_LOAD_ID, LOADING_PLANNER_LIST, TRANSLOAD_COMPLETED_LIST, LOAD_SCHEDULE |
| TMS delivery/booking/carrier | MOBILE_DRIVER, DELIVERY_LIST_BY_USERNAME, DELIVERY_LIST_BY_DRIVER_LOG_ID, DELIVERY_LIST_BY_EQUIPMENT_LOAD_ID, DELIVERY_ORDER_BY_BOL_ID, DELIVERY_DISPATCH, EXPORT_PICKUP_DISPATCH, IMPORT_RETURN_DISPATCH, REVERT_EXPORT_CONTAINER, EMPTY_PLAN_SUMMARY, EMPTY_PLAN_CREATE, CLONE_BOOKING, IS_TERMINAL, GET_DRIVER_ID_BY_WORDPRESS_USERNAME, GET_DRIVER_LOG, GET_LOADING_BOOKING_NUMBER, GET_LOADING_EQUIPMENT, GET_CARRIER_MASTER_BY_PHONE_NUMBER, EXPORT_CARRIER_MASTER_LIST, CONTAINER_LIST_BY_BOOKING_ID, WEIGHT_REQUIREMENT_BY_BOOKING_NUMBER, PACKING_LIST, LOAD_LABEL, BOOKING_INSTRUCTION, MK_BOOKING, MK_BOOKING_, MK_BOOKING_DETAIL, MK_BOOKING_EDITOR_OPTIONS, MK_BOOKING_LIST, IS_DUPLICATE_REFERENCE_NUMBER |
| OMS order/allocation/reporting | COMMERCIAL_ORDER, CUSTOMER_PO_LIST, CUSTOMER_PO_ITEM_BY_PO_ID, GET_CUSTOMER_PO_BY_LOAD_NUMBERS, MK_PURCHASE_ORDER, DOORTRADE_PACKING_LIST, MK_PURCHASE_, MK_INBOUND_, MK_INBOUND_ORDER_DETAIL, MK_INBOUND_ORDER_SCHEDULE, MK_INBOUND_CALENDAR_EVENTS, MK_SALES_ORDER, EXPORT_BROKERAGE_DOCUMENT, MK_SALES_, MK_OUTBOUND_, MK_OUTBOUND_ORDER_DETAIL, MK_OUTBOUND_ORDER_SCHEDULE, MK_OUTBOUND_COST, MK_OUTBOUND_COST_LIST, MK_ALLOCATION_, MK_ALLOCATION_WORKBENCH_READ_MODEL, MK_ALLOCATION_TARGET_SHIPMENT_AUTOCOMPLETE, TRADE_SUMMARY, DEAL_LEDGER |
| WMS inbound/inventory | IMPORT_DELIVERY_ORDER, TRANSLOAD_FROM_IMPORT, MK_INVENTORY, MK_INVENTORY_, MK_INVENTORY_LOT_LIST, MK_INVENTORY_LOT_DETAIL |
| BMS rate/scale/invoice/transaction | MK_COMMODITY_RATE, MK_COMMODITY_RATE_OPTIONS, MK_COMMODITY_RATE_LIST, MK_TRUCKING_RATE, MK_TRUCKING_RATE_OPTIONS, MK_TRUCKING_RATE_LIST, MK_FREIGHT_RATE, MK_FREIGHT_RATE_OPTIONS, MK_FREIGHT_RATE_LIST, TRUCKING_RATE, CHASSIS_RATE_BY_COMPANY_ID, CHASSIS_RATE_BY_EQUIPMENT_LOAD_ID, SCALE_TICKET, CLOSING_SCALE_TICKET, OUTBOUND_WEIGHT_APPLY, BMS_LOCAL_PURCHASE_INVOICE, BMS_LOCAL_TRANSACTION_DOCUMENT, MK_BILLING_, MK_BILLING_PURCHASE_LIST, MK_BILLING_SALES_LIST, MK_BILLING_REPORT, EDIT_TRANSACTION_DATA, BILLING_ADDRESS_BY_COMPANY_ID, JTABLE, APPLY_FINAL_TRANSLOAD_TO_EQUIPMENT, apply_final_transload_to_equipment, FUEL_LIST |
| Generic/decompose-only | GENERIC, GENERIC_MULTI |
Platform And Admin¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
ACCOUNT write password/account actions |
platform.auth |
PATCH /api/platform/account/password |
migrated | #451 | Active password caller uses session identity; shared post.php ACCOUNT branch removed. |
MENU MENU_TREE |
platform.menu |
GET/PATCH /api/platform/menu/tree |
migrated | #451 | Menu management uses API v2; permission-only route rows are excluded; writes clear KJ_MENU_CACHE. |
MENU ROLE_LIST |
platform.menu |
GET /api/platform/menu/roles |
migrated | #451 | Preserve role/menu permission behavior. |
MENU PAGE_LIST |
platform.module |
GET /api/platform/module-pages |
migrated | #451 | Keep page/module registry source of truth. |
MENU writes |
platform.menu |
POST/PATCH/DELETE /api/platform/menu/... |
migrated | #451 | Shared post.php MENU branch removed. |
SUPER_ADMIN query/write actions |
platform.audit |
GET/POST/PATCH /api/platform/admin/... |
migrated | #451, #490 | Admin routes enforce explicit super-admin checks and use API v2 envelopes; tenant onboarding is available through tenant create payloads and /api/platform/admin/tenants/{clientId}/onboarding. |
USER_ROLE_LIST |
platform.auth |
GET /api/platform/users/roles |
migrated | #451 | Popup/admin flows use API v2; shared query.php branch removed. |
CHECK_USERNAME |
platform.auth |
GET /api/platform/users/check-username?USERNAME=... |
migrated | #451 | Visible validation error preserved through API v2 response handling. |
USER_MASTER_LIST popup user detail/create/update |
platform.auth |
GET/POST/PATCH /api/platform/users* |
migrated | #453 | Popup user read/write no longer uses generic T_USER; create/update validate tenant roles and hash passwords server-side. |
COMPANY_LIST read/create/update |
platform / master data |
GET/POST /api/platform/companies..., POST/PATCH /api/platform/companies/form |
migrated | #454 | Company popup callers use platform-owned API v2 routes. |
TEMP_COMPANY_LIST |
platform company list | GET /api/platform/companies |
migrated | #454 | Driver-operation pages use the platform company list route. |
Admin console direct /app/controllers/query.php/post.php calls |
platform.audit |
domain-specific admin API routes | migrated | #451 | Admin-console tabs and api-debug use /api/platform/... routes only. |
Shared File, Media, Reports, Add-ons¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
FILE LOAD_URL |
shared file helper + reports | GET /api/files?TABLE_NAME=...&TABLE_ID=... |
migrated | #452 | photo.js and transaction file views use API v2; shared query.php FILE branch removed. |
FILE PACKING_LIST_URL |
tms.booking / reports file bridge |
GET /api/tms/bookings/{id}/packing-list/files |
migrated | #446 | Packing-list file lookup caller uses API v2; Excel export remains specialized report controller work, not shared query/post. |
FILE UPLOAD metadata registration |
shared file helper | POST /api/files |
migrated | #452 | Physical upload uses /api/files/media/upload; metadata route uses FILE_TYPE and preserves S3/EFS metadata columns. |
FILE UPLOAD_MANY AP documents |
BMS transaction + file helper | POST /api/files/transaction-documents |
migrated | #452 | kjtable.core.js registers AP invoice/payment documents through the shared file metadata route. |
FILE DELETE |
shared file helper | DELETE /api/files/{id} |
migrated | #452 | Deletes are scoped by CLIENT_ID and preserve S3 object cleanup. |
FILE CHANGE_TYPE / BULK_CHANGE |
shared file helper | PATCH /api/files/{id} / PATCH /api/files |
migrated | #452 | Preserves sequence/type behavior with explicit CLIENT_ID ownership checks. |
media.php ACTION=UPLOAD |
shared file/media helper | POST /api/files/media/upload |
migrated | #1052 | Active callers use API v2 for binary upload while preserving hybrid EFS/S3 behavior; media.php remains compatibility-only. |
media.php ACTION=DOWNLOAD |
shared file/media helper | POST /api/files/media/download |
migrated | #1052 | Active zip/download callers use API v2 and preserve the binary zip response contract. |
media.php ACTION=DATESTAMP |
shared file/media helper | POST /api/files/media/datestamp |
migrated | #1052 | Active date-stamp callers use API v2 and preserve equipment-load T_FILE registration. |
REPORT ACCOUNT_TRUCKING |
reports / BMS | GET /api/bms/reports/account-trucking |
migrated | #452 | kjtable.core.js uses API v2; shared query.php REPORT ACCOUNT_TRUCKING branch removed. |
REPORT FBOL |
reports / TMS booking | GET /api/reports/fbol |
migrated | #452 | Report route is explicitly owned by addon.reports; shared query.php REPORT FBOL branch removed. |
MONTHLY_INVENTORY_REPORT |
reports | GET /api/reports/inventory/monthly |
migrated | #452 | Administration report page uses API v2; shared query.php branch removed. |
ACCUMULATIVE_INVENTORY_REPORT |
reports | GET /api/reports/inventory/accumulative |
migrated | #452 | Administration report page uses API v2; shared query.php branch removed. |
INVENTORY_REPORT |
reports / WMS | GET /api/wms/inventory/report |
migrated | #449 | Inventory report page uses API v2; shared query.php branch removed. |
STORAGE_BY_COMPANY |
reports | GET /api/wms/storage/by-company |
migrated | #449 | Storage report page uses API v2; shared query.php branch removed. |
MK_DAILY_COMMODITY_REPORT / MK_DAILY_DASHBOARD |
reports | GET /api/reports/mk/daily-commodity |
migrated | #452 | MK daily commodity report uses API v2; shared report branches removed. |
TRUCKING_SUMMARY_REPORT |
reports / BMS | GET /api/bms/reports/trucking-summary |
migrated | #450, #452 | BMS report screen uses API v2; shared query.php branch removed. |
AI_VERIFICATION |
add-on reports | GET /api/addons/ai-verifications/{id} |
migrated | #452 | Popup apply flow uses API v2; kept separate from Gemini extraction endpoint. |
INGATE_TICKET AI extraction |
add-on reports | POST /api/addons/ai-verifications/ingate-ticket/ai-extract |
migrated | #436 | KJ.api.ai() routes ingate ticket extraction to the add-on report-owned API v2 route while preserving the legacy Result/Value payload inside the API response data. |
TELEGRAM write |
add-on telegram | POST /api/addons/telegram/messages |
migrated | #727 | KJ.api.sendTelegram calls the add-on-owned API v2 route; /api/platform/telegram/send remains a compatibility route. |
excel.php, gmail.php, chatgpt.php |
specialized controllers | excel.php is classified as a retained binary export boundary; keep the remaining specialized surfaces until separate route replacement is planned |
defer | #455, #1081 | Not blockers for deleting query.php/post.php unless active callers use them as shared controller substitutes. master.php and autocomplete.php were removed in #1088. |
YMS¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
YARD_MAP SECTIONS |
yms.yard-map |
GET /api/yms/yard-map/sections |
migrated | #439 | Implemented for yard-map page/API v2 callers; shared query.php branch removed. |
YARD_MAP STATE |
yms.yard-map |
GET /api/yms/yard-map/state |
migrated | #439 | Implemented for yard-map page/API v2 callers; shared query.php branch removed. |
YARD_MAP DISPATCH_QUEUE |
yms.yard-move |
GET /api/yms/yard-moves/dispatch-queue |
migrated | #440 | Used by yard map, yard dispatch, yard instruction, and shared dispatch UI; shared query.php branch removed. |
YARD_MAP RETURNING_EMPTY |
yms.yard-move |
GET /api/yms/yard-moves/returning-empty |
migrated | #440 | Yard-map caller uses API v2; shared query.php branch removed. |
YARD_DISPATCH_PREVIEW |
yms.yard-move |
POST /api/yms/yard-moves/preview |
migrated | #440 | Uses POST for complex request bodies; shared query.php branch removed. |
YARD_DISPATCH_ASSIGNABLE_USER_LIST |
yms.yard-move |
GET /api/yms/yard-moves/assignable-users |
migrated | #440 | Used by yard dispatch UI and shared dispatch UI; shared query.php branch removed. |
YARD_UNMAPPED_ENTITY_LIST |
yms.yard-move |
GET /api/yms/yard-moves/unmapped-entities |
migrated | #440 | Preserves tenant scope through existing handler; shared query.php branch removed. |
YARD_LOCATION AVAILABLE_BY_AREA |
yms.yard-move |
GET /api/yms/yard-locations/available?areaType=... |
migrated | #440 | Uses query params instead of DATA; shared query.php branch removed. CY L2/L3 mobile-lane targets blocked by AUTO:CY_L1_TRL:<lane> remain selectable when the L1 trailer has an active clearing queue. |
YARD_LOCATION AVAILABLE_STACK_GROUPS |
yms.yard-move |
GET /api/yms/yard-locations/stack-groups |
migrated | #440 | Stack-group callers use API v2; shared query.php branch removed. |
YARD_LOCATION AVAILABLE_BY_STACK_GROUP |
yms.yard-move |
GET /api/yms/yard-locations/available-by-stack-group?stackGroup=... |
migrated | #440 | Keeps existing area/stack semantics; shared query.php branch removed. CY L2/L3 mobile-lane targets blocked by a clearing L1 trailer remain selectable. |
YARD_LOCATION writes |
yms.yard-move |
POST/PATCH /api/yms/yard-locations... and /api/yms/yard-moves... |
migrated | #440 | T_YARD_LOCATION remains source of truth; write routes use explicit transactions and sync task flushing. |
RESET_YARD |
yms.yard-move |
POST /api/yms/yard-locations/reset |
migrated | #440 | Uses explicit transaction and visible errors; shared post.php branch removed. |
MOBILE_CONTAINER, MOBILE_CONTAINER_LIST, MOBILE_EMPTY_CONTAINER_LIST |
yms.container-tracking |
GET/PATCH /api/yms/containers... |
migrated | #441 | Container tracking, appointment, and closing callers use API v2; shared query.php/post.php branches removed. |
CONTAINER_*, EDIT_CONTAINER_DATA, EDIT_MULTI_CONTAINER_DATA |
yms.container-tracking |
GET /api/yms/containers... and /api/yms/equipment-loads... |
migrated | #441 | Popup/editor flows use API v2; shared query.php branches removed. |
EQUIPMENT_BY_DELIVERY_ID, EQUIPMENT_REPAIR_LOG_LIST, YARD_CONTAINER_LIST |
yms.container-tracking |
GET /api/yms/equipment... and /api/yms/yard-containers |
migrated | #441 | Equipment/repair and yard-closing callers use API v2; shared query.php branches removed. |
VALIDATE_CONTAINER_NUMBERS, VALIDATE_FULL_READY_BY_EQUIPMENT_LOAD_IDS |
yms.container-tracking |
POST /api/yms/containers/validate-* |
migrated | #441 | Validation routes use request bodies without TYPE/ACTION; shared query.php branches removed. |
CONTAINER_SEAL_PHOTO AI extraction |
yms.container-tracking |
POST /api/yms/containers/seal-photo/ai-extract |
migrated | #436 | Seal photo OCR callers in popup/table flows use API v2 and normalize the owner response before reading the legacy Result/Value payload. |
GENERIC T_EQUIPMENT.RETURN_BOOKING_ID updates |
yms.container-tracking |
PATCH /api/yms/containers/return-bookings |
migrated | #453 | Empty-container swap booking action uses explicit return-booking update route with tenant validation. |
MOBILE_APPOINTMENT_LIST, MOBILE_AVAILABLE_DOCK_LIST, MOBILE_AVAILABLE_YARD_LIST, MOBILE_PLANNING_YARD_LIST |
yms.dock-scheduling |
GET /api/yms/dock-scheduling/... |
migrated | #441 | Appointment, driver, yard map, dispatch, popup, and table callers use API v2; shared query.php branches removed. Yard-location lists include CY L2/L3 mobile-lane targets when the only block is a clearing L1 trailer. |
YMS_SCALE_*, YMS_SCALE writes |
yms.scale |
GET/POST/PATCH/DELETE /api/yms/scale/... |
migrated | #441 | Scale portal callers use API v2; write routes preserve explicit transactions and visible errors; shared query.php/post.php branches removed. |
TMS¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
TRANSLOAD CHECKIN_LIST |
wms.inbound |
GET /api/wms/inbound/transloads/check-in-list |
migrated | #449 | WMS inbound route added; shared query.php branch removed. |
TRANSLOAD PLANNING_BOARD read |
tms.transload |
GET /api/tms/transloads/planning-board |
migrated | #442 | Inbound planning and loader planning-board callers use API v2; shared query.php branch removed. |
TRANSLOAD COMPLETED_LIST |
wms.inbound |
GET /api/wms/inbound/transloads/completed |
migrated | #449 | Inbound completed page uses API v2 adapter instead of jTable legacy endpoint for this read model. |
TRANSLOAD CHECKIN, PLAN_PREVIEW, PLAN_APPLY |
tms.transload execution/planning boundary |
POST /api/tms/transloads/{command} |
migrated | #442, #443 | PLAN_PREVIEW and PLAN_APPLY migrated in #442; CHECKIN migrated in #443. |
TRANSLOAD AUTO_PLAN |
wms.inbound / tms.transload boundary |
POST /api/tms/transloads/auto-plan |
defer | future | Helper remains reachable through the WMS inbound direct endpoint shell; no shared-controller caller was found in the 2026-06-08 static scan. |
TRANSLOAD CONFIRM_PLAN, EDIT_PLAN, ASSIGN_SUBMIT, DISPATCH, CANCEL, NOSHOW |
tms.transload planning/execution boundary |
POST/PATCH /api/tms/transloads/{command} |
migrated | #442, #443 | Planning commands migrated in #442; dispatch/cancel/no-show migrated in #443. |
TRANSLOAD CREATE_RESERVE_MOVE |
tms.transload |
POST /api/tms/transloads/{id}/reserve-move |
defer | future | No active shared-controller caller was found in the 2026-06-08 static scan; any future route must coordinate yard side effects with YMS. |
MOBILE_TRANSLOAD runtime actions |
tms.transload execution boundary, WMS/YMS side effects through helpers |
POST/PATCH /api/tms/transloads/{command} |
migrated | #443 | Appointment, inbound-loader, and planning-board callers use named API v2 commands; shared post.php mobile branch removed. |
| Staff time clock and loader timeline events | tms.transload staff-time boundary |
GET /api/tms/staff-time/current, POST /api/tms/staff-time/event, GET /api/tms/staff-time/timeline |
migrated | #537 | Inbound-loader staff clock controls and /loader-timeline use T_STAFF_TIME_EVENT; transload Start/Complete dual-write job events while preserving T_LOADING_PLANNER timing fields. |
TRANSLOAD_PLANNER |
tms.transload |
GET/PATCH /api/tms/transload-planner/events... |
migrated | #442 | KJPlanner accepts API v2 callbacks for planner page; shared query.php/post.php branches removed. |
TRANSLOAD_APPOINTMENT_BLOCK LIST/CREATE/REMOVE |
tms.transload |
GET/POST/DELETE /api/tms/transload-appointment-blocks |
migrated | #442 | Existing block manager uses API v2; shared query.php/post.php branches removed. |
TRANSLOAD_TIMEBLOCK_STATUS |
tms.transload |
GET /api/tms/transload-timeblocks/status |
migrated | #442 | Planner and popup dependencies use API v2; shared query.php branch removed. |
TRANSLOAD_EMAIL_RESCHEDULE_DECISION |
tms.transload |
GET /api/tms/transload-emails/reschedule-decision |
migrated | #444 | Preserves SCHEDULED / PRE_PLANNED source status rules through existing validator. |
TRANSLOAD_EMAIL_APPROVAL_QUEUE |
tms.transload |
GET /api/tms/transload-emails/approval-queue |
migrated | #444 | Email approval page uses API v2; shared query.php branch removed. |
TRANSLOAD_EMAIL_OUTBOUND_QUEUE |
tms.transload |
GET /api/tms/transload-emails/outbound-queue |
migrated | #444 | Follow-up page uses API v2; shared query.php branch removed. |
TRANSLOAD EMAIL_RESCHEDULE_APPLY, EMAIL_APPROVAL_SUBMIT, EMAIL_ITEM_PROCESS |
tms.transload |
POST /api/tms/transload-emails/{command} |
migrated | #444 | Email actions use API v2; shared post.php email actions removed. |
LOAD_LABEL read/write |
tms.transload / reports boundary |
GET/PATCH /api/tms/transloads/{id}/load-label... |
migrated | #444 | Print page uses API v2 and no longer calls shared query/post controllers. |
OCCUPIED_TRANSLOAD_TIME, TRANSLOAD_LIST_BY_EQUIPMENT_LOAD_ID, GET_LOADING_EQUIPMENT |
tms.transload |
GET /api/tms/transloads/... |
defer | #454 / future | TRANSLOAD_LIST_BY_EQUIPMENT_LOAD_ID active callers use GET /api/tms/equipment-loads/{id}/transloads; OCCUPIED_TRANSLOAD_TIME remains in the module-owned TMS/transload/query.php direct shell. |
GET_LOADING_BOOKING_NUMBER, CONTAINER_LIST_BY_BOOKING_ID, WEIGHT_REQUIREMENT_BY_BOOKING_NUMBER, PACKING_LIST, MK_BOOKING_*, MK_BOOKING, IS_DUPLICATE_REFERENCE_NUMBER |
tms.booking |
GET/POST/PATCH /api/tms/bookings... |
migrated | #446 | MK_BOOKING ownership resolved to tms.booking; booking list/editor, packing list, popup, and table callers use API v2. |
LOAD_SCHEDULE AI extraction/prompt |
tms.transload |
POST /api/tms/transloads/load-schedule/ai-extract, GET/PATCH /api/tms/transloads/load-schedule/ai-prompt |
migrated | #436 | KJ.api.ai() / KJ.api.aiPrompt() route load schedule calls to the transload-owned API v2 route while preserving the legacy Result/Value payload inside the API response data. |
EXPORT_TRANSLOAD_SCHEDULE AI extraction |
tms.transload |
POST /api/tms/transloads/export-schedule/ai-extract |
migrated | current | Returns requested date/order/target metadata only; client timeblock logic determines the usable appointment preview. |
BOOKING_INSTRUCTION AI extraction/prompt |
tms.booking |
POST /api/tms/bookings/booking-instruction/ai-extract, GET/PATCH /api/tms/bookings/booking-instruction/ai-prompt |
migrated | #436 | KJ.api.ai() / KJ.api.aiPrompt() route booking instruction calls to the booking-owned API v2 route while preserving tenant prompt editing. |
GET_CARRIER_MASTER_BY_PHONE_NUMBER, EXPORT_CARRIER_MASTER_LIST |
tms.carrier |
GET/POST /api/tms/carriers... |
migrated | #446 | Inbound planning, appointment, and table export callers use API v2; export is POST because it marks carrier rows exported. |
GET_DRIVER_ID_BY_WORDPRESS_USERNAME, GET_DRIVER_LOG, MOBILE_DRIVER, DELIVERY_LIST_BY_*, DELIVERY_ORDER_BY_BOL_ID, IS_TERMINAL |
tms.delivery |
GET/POST/PATCH /api/tms/deliveries..., /api/tms/drivers..., /api/tms/driver-logs... |
migrated | #445 | Driver-operation, inbound-loader identity, and delivery popup reads use API v2. Field edits use allowlisted delivery/equipment endpoints instead of generic table input. |
DELIVERY_DISPATCH, EXPORT_PICKUP_DISPATCH, IMPORT_RETURN_DISPATCH |
tms.delivery |
POST /api/tms/dispatch/* |
migrated | #445 | Dispatch creation is migrated in #445. |
REVERT_EXPORT_CONTAINER, EMPTY_PLAN_SUMMARY, EMPTY_PLAN_CREATE, CLONE_BOOKING |
tms.booking |
POST /api/tms/export-containers/revert, GET/POST /api/tms/empty-plan/*, POST /api/tms/bookings/{id}/clone |
migrated | #446 | Booking clone, empty-plan, and export-container revert callers use booking API v2 routes. |
OMS¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
COMMERCIAL_ORDER reads/writes |
oms.commercial-order |
GET/POST/PATCH/DELETE /api/oms/commercial-orders... |
migrated | #447 | Commercial order page uses API v2 list/detail/options/create/update/delete routes; company templates and ORDER_NUMBER_PATTERN are preserved. |
MK_INBOUND_ORDER_LIST, DETAIL, SCHEDULE, CALENDAR_EVENTS, MK_PURCHASE_ORDER_OPTIONS, MK_PURCHASE_ORDER writes |
oms.inbound-order |
GET/POST/PATCH/DELETE /api/oms/inbound-orders...; editor Save POST /api/oms/inbound-orders/{id}/atomic-save |
migrated | #447 | Inbound order list, schedule, shared editor options/detail and individual compatibility writes use API v2; existing-order editor Save is one atomic header/item/delete request. |
DOORTRADE_PACKING_LIST AI extraction |
oms.inbound-order |
POST /api/oms/inbound-orders/doortrade-packing-list/ai-extract |
migrated | #436 | KJ.api.ai() routes doortrade packing-list extraction to the inbound-order-owned API v2 route. |
GET_CUSTOMER_PO_BY_LOAD_NUMBERS |
oms.inbound-order |
POST /api/oms/customer-pos/by-load-numbers |
migrated | #446 | Popup load-PO callers use API v2. |
CUSTOMER_PO_ITEM_BY_PO_ID, CUSTOMER_PO_LIST reads |
oms.inbound-order |
GET /api/oms/customer-pos/{id}, GET /api/oms/customer-pos/{id}/items |
migrated | #453 | Shared popup customer PO edit reads use API v2. |
CUSTOMER_PO_LIST writes |
oms.inbound-order |
POST /api/oms/customer-pos, POST/PATCH /api/oms/customer-pos/form |
migrated | #453, #454 | Customer PO popup writes use module-owned create/form routes instead of generic table dispatch. |
MK_OUTBOUND_ORDER_LIST, DETAIL, SCHEDULE, MK_SALES_ORDER_OPTIONS, MK_SALES_ORDER writes |
oms.outbound-order |
GET/POST/PATCH/DELETE /api/oms/outbound-orders... |
migrated | #447 | Outbound order list, schedule, shared editor options/detail, header writes, and item writes use API v2. |
EXPORT_BROKERAGE_DOCUMENT AI extraction |
oms.outbound-order + oms.inbound-order |
POST /api/oms/export-brokerage/documents/ai-extract |
migrated | #436 | KJ.api.ai() routes export brokerage document extraction to the export-brokerage API v2 route with outbound, inbound, and workflow-config gates. |
MK_OUTBOUND_COST, MK_OUTBOUND_COST_LIST |
oms.outbound-order |
GET/POST/DELETE /api/oms/outbound-orders/{id}/costs... |
migrated | #447, #450 | Cost read/upsert/delete uses API v2. File metadata and physical upload flows coordinate with #452. |
MK_ALLOCATION_WORKBENCH_READ_MODEL, MK_ALLOCATION_TARGET_SHIPMENT_AUTOCOMPLETE, MK_SALES_ORDER APPLY_WORKBENCH |
oms.allocation |
GET /api/oms/allocations/workbench, GET /api/oms/allocations/target-shipments, POST /api/oms/allocations/apply |
migrated | #448 | Allocation workbench uses API v2; shared query branches and shared MK_SALES_ORDER APPLY_WORKBENCH dispatch removed. |
TRADE_SUMMARY, DEAL_LEDGER |
oms.trade-summary / reports |
GET /api/oms/trade-summary, GET /api/oms/deal-ledger |
migrated | #448 | Trade summary page uses API v2; shared query branches removed. |
WMS¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
IMPORT_DELIVERY_ORDER, TRANSLOAD_FROM_IMPORT |
wms.inbound |
POST /api/wms/inbound/imports/delivery-orders, POST /api/wms/inbound/imports/transload |
migrated | #449 | Import popup callers use API v2; shared post.php dispatch removed. |
IMPORT_DELIVERY_ORDER AI extraction/prompt |
wms.inbound |
POST /api/wms/inbound/import-delivery-orders/ai-extract, GET/PATCH /api/wms/inbound/import-delivery-orders/ai-prompt |
migrated | #436 | KJ.api.ai() / KJ.api.aiPrompt() route import delivery order extraction and prompt editing to the WMS inbound-owned API v2 route. |
TRANSLOAD CHECKIN_LIST, COMPLETED_LIST, import-linked writes |
wms.inbound / TMS boundary |
Explicit WMS inbound or TMS transload command routes | migrated | #449 | #443 moved active TMS runtime commands to tms.transload; remaining WMS read/import bridge work is migrated. |
MK_INVENTORY_LOT_LIST, MK_INVENTORY_LOT_DETAIL |
wms.inventory |
GET /api/wms/inventory/lots, GET /api/wms/inventory/lots/{id} |
migrated | #449 | Route preserves source/status visibility and tenant scope. |
MK_INVENTORY writes |
wms.inventory |
PATCH /api/wms/inventory/lots/{id}, POST /api/wms/inventory/lots/{id}/adjust |
migrated | #449 | Routes preserve existing transaction behavior; shared post.php dispatch removed. |
| Canonical Warehouse Map grid state and shared location options | wms.inventory |
GET /api/wms/inventory/warehouse-map/{state,locations,location-options} |
migrated | #773, #1182, #1194, #1339, #1348 | state reads the Excel-coordinate grid, each grid-owned cellType, and current T_INVENTORY_LOT.WAREHOUSE_LOCATION occupancy for STORAGE cells only. locations and location-options preserve shared Loader/Inbound callers; options include active, unblocked Firelane exceptions but continue to exclude manual/system blocks. Task #1339 retired the V1 marker, unmapped-review, inventory-lot move, and footprint-confirm operator/API surface; the canonical map is read-only until a separately approved grid-write workflow exists. Internal unload handoff and location mirror helpers remain workflow dependencies rather than map endpoints. |
INVENTORY_REPORT, STORAGE_BY_COMPANY |
WMS/report boundary | GET /api/wms/inventory/report, GET /api/wms/storage/by-company |
migrated | #449 | Pages use API v2; helper ownership remains WMS/report boundary internally. |
BMS¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
MK_COMMODITY_RATE_*, MK_COMMODITY_RATE |
bms.rate |
GET/POST/PATCH/DELETE /api/bms/rates/commodities... |
migrated | #450 | Rate pages and order editors use API v2; shared query.php/post.php branches removed. |
MK_TRUCKING_RATE_*, MK_TRUCKING_RATE, TRUCKING_RATE |
bms.rate |
GET/POST/PATCH/DELETE /api/bms/rates/trucking... and GET /api/bms/rates/trucking/lookup |
migrated | #450 | Rate page and popup trucking-rate lookups use API v2; shared branches removed. |
MK_FREIGHT_RATE_*, MK_FREIGHT_RATE |
bms.rate |
GET/POST/PATCH/DELETE /api/bms/rates/freight... |
migrated | #450 | Route aliases the trucking-rate table through the BMS rate owner; shared branches removed. |
SCALE_TICKET, CLOSING_SCALE_TICKET, OUTBOUND_WEIGHT_APPLY |
bms.scale-ticket |
GET/POST/PATCH/DELETE /api/bms/scale-tickets... |
migrated | #450 | Popup, container tracking, yard closing, and scale-portal dependencies use API v2; shared branches removed. |
BMS_LOCAL_PURCHASE_INVOICE, BMS_LOCAL_TRANSACTION_DOCUMENT |
bms.invoice |
GET /api/bms/invoices..., GET /api/bms/transaction-documents... |
migrated | #450 | API v2 read routes exist; server-rendered print helpers remain available without legacy client contracts. |
JTABLE transaction actions |
bms.transaction |
POST/DELETE /api/bms/transactions/{source}, DELETE /api/bms/transactions, PATCH /api/bms/transactions/close, POST /api/bms/transactions/chassis/bulk-input |
migrated | #453 | Shared post.php JTABLE branch removed; no /api/jtable compatibility route was added. |
apply_final_transload_to_equipment |
bms.transaction |
POST /api/bms/transactions/apply-final-transload |
migrated | #453 | Popup caller uses normalized API v2 route; shared post.php branch removed. |
EDIT_TRANSACTION_DATA, BILLING_ADDRESS_BY_COMPANY_ID, CHASSIS_RATE_* |
bms.transaction / bms.rate |
GET /api/bms/transactions/{id}, GET /api/bms/companies/{id}/billing-address, GET /api/bms/rates/... |
migrated | #450, #453 | Transaction detail, billing address, and chassis-rate popup dependencies use API v2; shared query.php branches removed for transaction detail/address. |
| AR Billing presets / preview / confirm / QBO sync | bms.transaction |
GET/POST/PATCH/DELETE /api/bms/ar-billing... |
migrated | #755 | New AR Billing workbench uses UUID-first API routes; preview is read-only until confirm creates container-scoped AR T_TRANSACTION rows. |
MK_BILLING_PURCHASE_LIST, MK_BILLING_SALES_LIST, MK_BILLING_REPORT |
bms.transaction / reports |
/api/bms/ar-billing/* active replacement; no /api/bms/billing/* compatibility route |
migrated | #450, #755 | 2026-06-27 active scan found no exact legacy caller or handler outside the module guard prefix. AR Billing workbench/reporting uses API v2 routes; no active P&L compatibility action was found to preserve. |
Generic, jTable, Shared Popup¶
| Legacy contract | Current owner | Proposed API v2 route | Status | Task | Notes |
|---|---|---|---|---|---|
GENERIC read/write |
shared controller | Domain popup/form routes under YMS/TMS/OMS/BMS ownership | migrated | #453 | Runtime callers no longer send GENERIC; route bodies use explicit URL/method and module allowlists. |
GENERIC_MULTI read/write |
shared controller | Domain popup/form routes with mode=bulk where needed |
migrated | #453 | No arbitrary shared table route was added; allowed tables are scoped by module route. |
GENERIC/GENERIC_MULTI T_DELIVERY reads |
tms.delivery |
GET /api/tms/deliveries, GET /api/tms/deliveries/{id} |
migrated | #453 | Shared popup DELIVERY_LIST and delivery-linked container edit reads use explicit TMS delivery routes. |
GENERIC T_TRANSLOAD reads and linked T_SCALE_TICKET read |
tms.transload / bms.scale-ticket |
GET /api/tms/transloads..., GET /api/bms/scale-tickets/{id} |
migrated | #453 | Shared popup transload edit reads use explicit TMS routes and scale-ticket linked read uses BMS scale-ticket route. |
GENERIC T_SCALE_TICKET create and T_TRANSLOAD.SCALE_TICKET_ID link |
bms.scale-ticket / tms.transload |
POST /api/bms/scale-tickets, PATCH /api/tms/transloads/{id}/scale-ticket |
migrated | #453 | Popup and inbound-planning scale-ticket create/link flows no longer use generic table writes; DB-write smoke still requires explicit confirmation. |
GENERIC T_LOADING_PLANNER read/write |
tms.transload |
GET/POST/PATCH /api/tms/loading-planner..., POST/PATCH /api/tms/loading-planner/form |
migrated | #453, #496, #161 | Inbound-planning and loading-planner popup callers use explicit TMS API v2 routes and the popup form route preserves loading-planner insert side effects. Loader Timeline moved to T_STAFF_TIME_EVENT through /api/tms/staff-time/timeline. |
| Popup form table updates/deletes | module-owned popup flows | /api/yms/containers/form, /api/yms/equipment-information/form, /api/tms/transloads/form, /api/tms/deliveries/form, /api/tms/bookings/form, /api/tms/carriers/form, /api/oms/customer-pos/form, /api/bms/transactions/form, /api/bms/rates/form, /api/bms/rates/form-row, /api/bms/fuel/form, /api/platform/master-data/form |
migrated | #453, #496 | Replaces final popup generic create/edit/delete fallbacks with module-owned allowlisted form routes. |
| Company popup read/write | platform |
GET/POST /api/platform/companies..., POST/PATCH /api/platform/companies/form |
migrated | #454 | Replaces COMPANY_LIST shared read/write callers and keeps company-email rows under platform-owned routes. |
| Telegram send | addon.telegram |
POST /api/addons/telegram/messages |
migrated | #727 | Replaces KJ.api.sendTelegram use of shared post.php with the add-on-owned route while preserving existing Telegram helper behavior. |
| Equipment-load transload history | tms.transload |
GET /api/tms/equipment-loads/{id}/transloads |
migrated | #454 | Replaces remaining TRANSLOAD_LIST_BY_EQUIPMENT_LOAD_ID shared query callers. |
GENERIC import container street-turn |
yms.container-tracking |
POST /api/yms/containers/street-turn |
migrated | #453 | Street-turn command validates equipment load, equipment, and pickup booking by CLIENT_ID. |
JTABLE write actions |
bms.transaction and shared table runtime |
Domain transaction/table routes. | migrated | #453 | Runtime callers use BMS transaction API v2 routes; jtable_core.php can remain table runtime during transition but not a React API pattern. |
dataSource: { endpoint: "/app/controllers/query.php" } |
shared table config | Domain-specific endpoint/client config | migrated | #454 | Active runtime scan no longer reports direct shared query endpoint callers. |
KJ.api.post/query/queryPost |
global JS helper | removed | done | #454 | React API client must not reproduce this shape. |
KJ.config.url.post/query |
global JS config | removed | done | #454 | Existing specialized URLs can remain if still valid. |
Specialized Controllers¶
These are not query.php / post.php blockers by themselves, but they must be classified before API v2 is considered complete.
| Controller | Current purpose | API v2 decision | Status | Notes |
|---|---|---|---|---|
app/controllers/media.php |
upload, zip/download, datestamp compatibility | API v2 routes active under /api/files/media/*; keep controller temporarily for external/legacy compatibility |
migrated | #1052; preserves S3/EFS behavior. |
app/controllers/excel.php |
authenticated packing-list XLSX and QuickBooks CSV export | Retain as a specialized binary export boundary until owner APIs define download/command semantics | defer | #1081; active callers inventoried on 2026-06-30. PACKING_LIST is a TMS booking XLSX export; QUICKBOOK is a BMS transaction CSV export that marks T_TRANSACTION.CHECK_NUMBER after streaming. Not a shared post/query blocker. |
app/controllers/master.php |
master data lookup | Deleted after active callers were confirmed on explicit API v2 lookup routes | done | Removed in #1088. Caller inventory completed on 2026-06-27 against committed HEAD, client fallback removed in #1083, and deletion validation confirmed no active application callers for the legacy path. |
app/controllers/autocomplete.php |
autocomplete lookup | Deleted after committed KJAutocomplete callers were confirmed on owner-specific bounded search/options routes |
done | Removed in #1088. Caller inventory completed on 2026-06-27 against committed HEAD, the browser serviceUrl / legacy TYPE fallback was removed in #1083, and deletion validation confirmed no active application callers for the legacy path. |
app/controllers/gmail.php |
booking inquiry, packing list, and BOL compatibility branches | Keep temporarily for server-token/external compatibility; delete only after the controller-specific source inventory and runtime tests show active flows use owner API v2 routes | migrated | BOOKING_INQUIRY active caller moved to /api/tms/empty-plan/booking-inquiry-email; PACKING_LIST active caller moved to /api/tms/bookings/{id}/packing-list/email; BOL active caller moved to /api/tms/transloads/{id}/bol-email with GmailSender, Dompdf, and hybrid T_FILE/FileStorage attachment behavior preserved. The controller still accepts a configured server token through GMAIL_CONTROLLER_TOKEN / GMAIL_OPERATION_TOKEN; deleting it intentionally ends any direct token-based legacy integration and must be validated against the actual deletion scope. |
app/controllers/chatgpt.php |
Gemini-backed document/OCR extraction and prompt management | Browser fallback removed; keep controller as legacy/external compatibility until the controller-specific source inventory and runtime tests show active flows use owner API v2 routes | defer | #1087 removed KJ.config.url.chatgpt, KJ.api.chatgpt, KJ.api.ai() / KJ.api.aiPrompt() fallback to chatgpt.php, and direct seal-photo OCR legacy fallback. Current browser extraction tasks route through owner API v2 endpoints via KJ.api.ai(); IMPORT_DELIVERY_ORDER, LOAD_SCHEDULE, and BOOKING_INSTRUCTION also use owner prompt read/save routes through KJ.api.aiPrompt(). Unsupported browser AI task/prompt names fail visibly. Appointment email intake already uses TransloadAppointmentActionAgent directly. |
app/controllers/sync.php |
checksum polling compatibility | API v2 route active under /api/platform/sync/checksums; keep controller temporarily for external/legacy compatibility |
migrated | #1079; the active KJ.api.sync() caller uses API v2 and still accepts the legacy raw checksum map shape in the client normalizer. |
Master And Autocomplete Inventory¶
Captured on 2026-06-27 KST from committed HEAD after the GitHub workflow document merge. Uncommitted dirty files from other sessions were intentionally excluded from the search basis.
Deleted master.php contract:
- Former
GET /app/controllers/master.php?key=ALLreturned grouped master data plus forklift drivers, inspector companies, company list, andT_MASTERcategories. - Former
GET /app/controllers/master.php?key=<category>returned one list. Special keys wereFORKLIFT_DRIVER_LIST,INSPECTOR_LIST,COMPANY_LIST,SHIPPER_COMPANY_ID_LIST, andCOMMODITY; other keys readT_MASTER.CATEGORY. - Active callers are mostly popup
data-group=MASTERfields, transload planning/loader boards, transload planner/calendar screens, and commodity datalists, all routed through API v2-supportedKJ.api.getMasterkeys.KJ.api.loadMaster()no longer callsmaster.php?key=ALL, andKJ.api.getMasterno longer falls back tomaster.php; unsupported keys return an empty list.
| Key / caller group | Active callers | Owner decision | Replacement direction |
|---|---|---|---|
ALL global cache |
frontend/partials/_app_shell.php calls KJ.api.loadMaster() through public/assets/vendor/kj/kj.js |
no API v2 replacement | loadMaster() is retained as an app-shell compatibility marker but no longer calls master.php?key=ALL; do not recreate a generic API v2 bulk dispatcher. |
T_MASTER.CATEGORY values such as statuses, timeblocks, labels, booking/load/delivery types |
KJ.api.getMaster, popup data-group=MASTER, TRANSLOAD_TIMEBLOCK in transload planner/order schedule |
platform-owned master data, with TMS ownership for timeblock consumers | Add bounded GET /api/platform/master-data/options?category=... for generic master-data categories, then move TMS timeblock callers to a named TMS route if behavior becomes domain-specific. |
COMPANY_LIST and SHIPPER_COMPANY_ID_LIST |
transload planner, booking popup/form multiselects, popup master groups | platform-owned company lookup | Use platform company options/search routes instead of master.php list shape. |
FORKLIFT_DRIVER_LIST |
frontend/pages/system/TMS/transload/inbound-planning.php, frontend/pages/system/TMS/transload/loader-assignment-board.php |
tms.transload |
Add a bounded loader roster/options route for assignment boards; preserve ID/name shape and blank handling where existing UI expects it. |
INSPECTOR_LIST |
booking and loading-planner popup master groups | platform company type lookup | Replace with company search/options filtered by company type INSPECTOR; preserve the blank -1 option where current forms expect it. |
COMMODITY |
inbound planning datalist, popup commodity fields, scale-ticket modal | platform commodity master, consumed by BMS/TMS/WMS/OMS | Add a bounded commodity options/search route over T_COMMODITY; preserve name-only datalist compatibility for legacy fields. |
Deleted autocomplete.php contract:
- Former legacy response shape was
{ suggestions: [{ key, value, data }] }. - Former active callers set
TYPEthroughKJAutocompleteorkj_ui_view_autocomplete(). SupportedKJAutocompletetypes now route to owner-specific API v2 endpoints withoutTYPE; the browserserviceUrlfallback that generated legacyTYPEautocomplete requests was removed in #1083. CONTAINER,YARD_LOCATION, andYARD_LOCATION_ALLcontroller branches had no committed active caller in the 2026-06-27 scan and were removed with the controller in #1088.
TYPE |
Active caller evidence | Owner decision | Replacement direction |
|---|---|---|---|
COMPANY |
report filters, WMS bale inventory, TMS leftover/check-in forms, transload email approval, import dispatch popup, user/company cells, BMS rate KJView configs, shared popup company fields, scale portal | platform-owned company search | Use a bounded platform company search/options route with optional terminal/type metadata. |
COMMODITY |
BMS rate KJView configs, booking editor commercial field, WMS bale inventory, scale portal item rows | platform commodity master, shared across BMS/TMS/WMS/OMS | Use a bounded commodity search/options route over T_COMMODITY; keep both ID-based and value-as-name modes for legacy form compatibility. |
DRIVER |
shared popup delivery/driver-log fields, driver filtered by carrier company in popup.core.js |
tms.delivery |
Use GET /api/tms/drivers/search with optional companyId; preserve Truck Operator and Forklift Operator role filtering. |
BOOKING |
delivery-order/equipment popup fields, scale portal booking fields, outbound order booking autocomplete helper | tms.booking |
Use GET /api/tms/bookings/search; existing /api/tms/bookings list should not become a generic autocomplete adapter. |
EQUIPMENT_LOAD |
transload popup initial/final equipment fields | yms.container-tracking for equipment-load lookup, with tms.transload consumers |
Use GET /api/yms/equipment-loads/search for bounded active equipment-load search/detail semantics. |
UNLOADING_EQUIPMENT |
loading planner popup UNLOADING_EQUIPMENT_LOAD_ID and related transload planning flows |
tms.transload |
Use GET /api/tms/transloads/unloading-equipment/options with the existing transload eligibility query semantics. |
ALLOCATABLE_INVENTORY_LOT |
public/assets/js/modules/shared/mk-outbound-order-editor.js allocation source selector |
oms.allocation with WMS inventory data |
Use GET /api/oms/allocations/allocatable-lots/search with the existing context fields commodityId, loadNumber, sourceOrderId, and sourceMode; do not expose the legacy TYPE name. |
YARD_LOCATION |
no committed active direct caller found | yms.yard-move if revived |
Existing /api/yms/yard-locations/available* routes cover active yard-location selection patterns; keep controller branch temporary only. |
YARD_LOCATION_ALL |
no committed active direct caller found | temporary specialized or delete candidate | Do not add a replacement until an active caller is found. |
CONTAINER |
no committed active direct caller found | yms.container-tracking if revived |
Existing container/equipment routes should be used for active flows; no compatibility API route needed without a caller. |
Legacy Lookup Controller Retirement Gate¶
Completed in #1088. Source scan against committed HEAD found no active application callers for /app/controllers/master.php, /app/controllers/autocomplete.php, master.php?key, autocomplete.php?TYPE, KJ.config.url.master, KJ.config.url.autocomplete, serviceUrl, or legacy autocomplete TYPE request construction outside current documentation, historical reference/, and migration notes. The controllers were deleted and direct browser/API validation returns 404 for both legacy paths. Representative owner API v2 lookup routes are the active runtime surface for popup master fields, company autocomplete, commodity autocomplete, TMS loader/timeblock/driver/booking lookups, YMS equipment-load lookup, and OMS allocatable inventory lot lookup.
Excel Export Boundary Inventory¶
Captured on 2026-06-30 KST from committed qa plus targeted current files; unrelated dirty files from other sessions were excluded from the classification basis.
app/controllers/excel.php active caller contract:
- The controller is protected by
controllerRequireAuthenticatedDownload()and returns file downloads directly, not API v2 JSON envelopes. TYPE=PACKING_LISTis called byfrontend/pages/system/TMS/booking/packingList.phpfrom the Excel button. Owner istms.booking. It returns an XLSX workbook generated frompacking_list(...)plus page-supplied printable overrides such as print date, shipper/consignee names, purchase order, commodity, and weight unit.TYPE=QUICKBOOKis called bypublic/assets/js/modules/shared/kjtable.core.jsfor selected transaction exports. Owner isbms.transactionwith AR/AP billing semantics. It returns a CSV forAP_TRUCKING_TRANSACTION,AP_CHASSIS_TRANSACTION,AR_TRUCKING_TRANSACTION,AR_CHASSIS_TRANSACTION,AR_TRANSLOAD_TRANSACTION, andAR_SCALE_TICKET_TRANSACTION, then marks selected unmarked transactions withCHECK_NUMBER='QBYYYYMMDD'.- Do not migrate
TYPE=QUICKBOOKas a read-only GET download. Its replacement needs an owner command/download contract that explicitly preserves the check-number side effect, selected-id allowlisting, tenant scoping, and failure semantics around streaming and the DB update.
| Export type | Active caller | Owner | Response | Replacement direction |
|---|---|---|---|---|
PACKING_LIST |
frontend/pages/system/TMS/booking/packingList.php Excel button |
tms.booking |
XLSX workbook download | Future explicit booking export route, for example GET /api/tms/bookings/{id}/packing-list/export, after the owner route contract defines auth/module guard behavior, request validation, direct-download headers, printable override handling, and pre-stream error behavior. |
QUICKBOOK |
public/assets/js/modules/shared/kjtable.core.js transaction selection button |
bms.transaction / AR/AP billing |
CSV download plus T_TRANSACTION.CHECK_NUMBER update |
Future BMS transaction export command/download flow; do not hide the DB write behind a read-only download route. |
Gmail And AI Extraction Boundary Inventory¶
Captured on 2026-06-29 KST from committed qa plus the current working tree, excluding unrelated dirty files in app/platform/api_routes.php, app/platform/audit/page_usage_logger.php, and scripts/kj-view-audit.php. Rechecked on 2026-06-30 KST against committed HEAD for direct browser/server-rendered callers to gmail.php and chatgpt.php, ignoring unrelated dirty files.
app/controllers/gmail.php active caller contract:
TYPE=PACKING_LISTwas called byfrontend/pages/system/TMS/booking/packingList.php. Owner istms.booking. The active caller now usesPOST /api/tms/bookings/{id}/packing-list/email, preserving recipient lookup fromT_COMPANY_EMAIL/T_MASTER, packing-list HTML content, ZIP splitting, and hybridT_FILE.STORAGE/FileStorage::readToTempFile()attachment handling.TYPE=BOLwas called bypublic/assets/js/modules/shared/popup.core.jsfor a singleTRANSLOAD_LISTrow. Owner istms.transload. The active caller now usesPOST /api/tms/transloads/{id}/bol-email, preserving scale-ticket PDF generation,T_TRANSLOAD/T_FILEattachment reads, admin test recipient override behavior, and visible Gmail send failures.TYPE=BOOKING_INQUIRYwas called byfrontend/pages/system/TMS/booking/empty-schedule.php. Owner istms.bookingbecause the payload is an empty-plan booking-needed summary grouped by billing company, not selected scheduled transload rows. The active caller now usesPOST /api/tms/empty-plan/booking-inquiry-email, preservingBOOKING_INQUIRYrecipient lookup and the current summary response shape.POST /api/tms/transloads/scheduled-inquiry-emailis a separatetms.transloadroute used bypublic/assets/js/modules/shared/kj-table-options-export.jsfor selectedSCHEDULEDtransload rows and must not be treated as theBOOKING_INQUIRYreplacement.- Committed application code no longer contains active browser calls to
/app/controllers/gmail.php. The remaining controller contract is compatibility-only, including session-authenticated direct POSTs and server-token POSTs throughGMAIL_CONTROLLER_TOKEN/GMAIL_OPERATION_TOKENheaders. - Deletion gate: prove no direct
POST /app/controllers/gmail.phprequests during the chosen compatibility window, remove or retire the server-token integration contract, and confirm active browser email flows still use/api/tms/empty-plan/booking-inquiry-email,/api/tms/bookings/{id}/packing-list/email, and/api/tms/transloads/{id}/bol-email.
Gmail Workspace Add-on boundary:
public/gmail/addon.phpis a public token-protected Apps Script gateway, not a session API v2 route.- Actual supported actions are
status,analyze,apply, andreply-draft;reply_draftanddraftaliasreply-draft. process-safeis documented as a desired add-on behavior in older notes, but it is not currently routed bypublic/gmail/addon.php. Apps Script must callapplywith selected safe item ids or an explicitprocess-safealias must be implemented before that action is considered supported.- The implementation lives in
app/utils/GmailAppointmentAddonGateway.php; there is no currentapp/addons/gmail/directory. - Intake and approval storage side effects are in
T_MAIL_MESSAGEandT_MAIL_REQUEST_ITEM; watch state is inT_MAILBOX_WATCH_STATE.
app/controllers/chatgpt.php active caller contract:
- Active browser callers use
KJ.api.ai()/KJ.api.aiPrompt()throughpublic/assets/vendor/kj/kj.jsand must resolve to owner API v2 routes. - Browser extraction tasks found in current callers route to owner API v2 endpoints:
IMPORT_DELIVERY_ORDER,LOAD_SCHEDULE,BOOKING_INSTRUCTION,DOORTRADE_PACKING_LIST,EXPORT_BROKERAGE_DOCUMENT,INGATE_TICKET, andCONTAINER_SEAL_PHOTO. IMPORT_DELIVERY_ORDER,LOAD_SCHEDULE, andBOOKING_INSTRUCTIONalso route prompt read/save to owner API v2 endpoints.GET_PROMPTandSAVE_PROMPTare used by popup and booking editor prompt-editing flows and must not be folded into a generic API v2TYPE/ACTIONdispatcher; migrated tasks use owner GET/PATCH prompt routes. Browser prompt tasks without owner prompt routes fail visibly and do not callchatgpt.php.-
1087 removed the shared JS legacy fallback surface:
KJ.config.url.chatgpt,KJ.api.chatgpt,KJ.api.ai()fallback whenaiTaskRoute(task)is empty,KJ.api.aiPrompt()fallback whenaiPromptRoute(task)is empty, and direct seal-photo OCR fallback to the legacy controller.¶ APPOINTMENT_ACTION_PLANis registered inAiTaskRegistry, but transload appointment email intake usesTransloadAppointmentActionAgentdirectly. Migratingchatgpt.phpshould not disturb Gmail appointment intake.- Replacement routes remain owner-specific by task family.
chatgpt.phpremains a compatibility surface for direct legacy/external AI callers and tenant prompt actions not yet exposed through owner prompt routes. - Deletion gate: prove no direct
POST /app/controllers/chatgpt.phprequests during the chosen compatibility window, then validate owner AI extraction and prompt routes for each active task and confirm the direct legacy path returns 404 after deletion.
Next Step Plan¶
Local Assignment Work Candidate¶
POST /api/tms/transloads/assignment-workcreates one bounded Work or Clock Out row per eligible Loader; manager list, edit/cancel, and Telegram retry stay on the same owner path.GET /api/tms/transloads/assignment-work/currentis Loader-authenticated and conceals Assigned detail;POST .../{id}/startreveals it only after Start.- Loader workflow commands are
POST .../{id}/complete,cleaning-complete,final-break, andclock-out. Final Break is available only for a linked Started Clock Out withfinalBreakRequired=true; its server timer controls the terminal Clock Out transition. - This is a local uncommitted candidate. Production API/schema, provider observation, and target-role field acceptance are not asserted here.
The shared controller cutover is complete. Media upload/download/datestamp active callers were migrated on 2026-06-27 through #1052. The BMS billing legacy contract scan was completed on 2026-06-27, the master.php / autocomplete.php caller inventory was completed on 2026-06-27, the legacy lookup controllers were deleted in #1088, Gmail dispatch plus current browser AI extraction callers are owner-routed as of 2026-06-30, the browser/client fallback to chatgpt.php was removed in #1087, sync checksum polling active callers use /api/platform/sync/checksums as of #1079, and excel.php export callers were classified as a retained binary export boundary in #1081. There are no inventory rows left in migrate. The next API migration phase should finish specialized controller work without recreating generic dispatch.
| Priority | Scope | Target | Exit condition |
|---|---|---|---|
| Done | Media controller replacement | app/controllers/media.php upload, download/zip, and datestamp actions |
/api/files/media/upload, /api/files/media/download, and /api/files/media/datestamp preserve hybrid EFS/S3 behavior, binary responses, metadata registration, and active UI callers. |
| Done | BMS billing read/report contract | MK_BILLING_PURCHASE_LIST, MK_BILLING_SALES_LIST, MK_BILLING_REPORT |
Active scan found no exact legacy caller/handler; AR Billing uses /api/bms/ar-billing/*, and no /api/bms/billing/* compatibility dispatcher is needed. |
| Done | Master/autocomplete caller inventory | master.php and autocomplete.php active callers |
Caller inventory assigns each lookup to platform, module, or temporary specialized ownership. |
| Done | Platform lookup routes | platform master-data/company/commodity options and search | /api/platform/master-data/options, /api/platform/companies/options, /api/platform/companies/search, /api/platform/commodities/options, and /api/platform/commodities/search are available; KJ.api.getMaster uses API v2 for platform-owned keys and no longer falls back to master.php; KJ.api.loadMaster() no longer calls the legacy global ALL endpoint. |
| Done | TMS lookup routes | transload loader/timeblock/unloading options; delivery driver search; booking search | /api/tms/transload-loaders/options, /api/tms/transload-timeblocks/options, /api/tms/transloads/unloading-equipment/options, /api/tms/drivers/search, and /api/tms/bookings/search are available; KJ.api.getMaster, transload planning/assignment loader fetches, and KJAutocomplete routes use these API v2 endpoints for their supported lookup keys. |
| Done | YMS equipment-load lookup route | equipment-load autocomplete | /api/yms/equipment-loads/search is available and KJAutocomplete routes EQUIPMENT_LOAD suggestions through API v2 without legacy TYPE. |
| Done | OMS allocation lookup route | outbound allocation lot autocomplete | /api/oms/allocations/allocatable-lots/search is available and the outbound order editor allocation selector uses it without legacy TYPE. |
| Done | Master/autocomplete compatibility retirement gate | app/controllers/master.php and app/controllers/autocomplete.php |
#1088 deleted both controllers. Static source scan found no active app callers, direct legacy paths return 404, and representative lookup consumers use owner API v2 routes. |
| Done | Gmail dispatch and browser AI extraction cutover | gmail.php and chatgpt.php active browser task paths |
Gmail dispatch browser callers are on API v2; all current browser AI extraction task names are owner-routed. gmail.php is compatibility-only, and chatgpt.php has no browser fallback path after #1087. |
| Done | AI fallback retirement | KJ.config.url.chatgpt, KJ.api.chatgpt, and KJ.api.ai() / KJ.api.aiPrompt() fallback to chatgpt.php |
#1087 removed the shared browser fallback surface. Active browser AI tasks and prompt tasks either resolve to owner API v2 routes or fail visibly without calling chatgpt.php; no generic AI TYPE/ACTION dispatcher is recreated. |
| 1 | AI controller compatibility retirement gate | app/controllers/chatgpt.php |
Runtime evidence proves no direct legacy/external POST callers remain; direct path returns 404 after deletion while owner AI extraction and prompt routes keep working. |
| 2 | Gmail controller compatibility retirement gate | app/controllers/gmail.php |
Runtime evidence proves no direct session or server-token POST callers remain; server-token contract is retired or explicitly documented elsewhere; direct path returns 404 after deletion while owner email routes keep working. |
| Done | Sync checksum route | sync.php active polling caller |
/api/platform/sync/checksums preserves checksum polling behavior and sync.php is compatibility-only. |
| Done | Export controller classification | excel.php |
#1081 documents caller inventory, binary response types, replacement owners, and the QuickBooks check-number side effect; keep the controller specialized until explicit owner download/command replacements are planned. |
| 3 | Legacy module shell retirement | 22 module-owned query.php / post.php shells |
Each shell is either removed after caller cutover or documented as an intentional server-rendered legacy adapter with owner and exit condition. |
Execution Order¶
-
437 API v2 route/bootstrap contract, including binary-safe JSON, module-key route definitions, and transaction/audit rules.¶
-
438 React API client foundation.¶
-
439-#441 YMS routes, because the module endpoints already exist and yard-map/yard-move give a good read/write pilot.¶
-
442-#444 TMS transload planning/runtime/email, resolving WMS inbound boundaries where needed.¶
-
445-#446 TMS delivery/booking/carrier.¶
-
447-#448 OMS order/allocation/reporting, including #410 changes.¶
-
449 WMS inbound/inventory.¶
-
450 BMS rate/scale/invoice/transaction documents.¶
-
451 Platform/admin. Completed API v2 caller cutover; admin-console no longer calls shared
query.php/post.php.¶ -
452 File/media/reports with #460 S3/EFS behavior.¶
-
453 Generic/jTable/popup decomposition.¶
-
454 Delete legacy callers and shared controllers.¶
-
455 Cutover validation.¶
- Specialized controller replacement and module-shell retirement, following the next step plan above.
Deletion Conditions¶
app/controllers/query.php and app/controllers/post.php were deleted in #454 after:
- The runtime source scan for
/app/controllers/(post|query).php,KJ.api.post/query/queryPost, andKJ.config.url.post/queryreturns zero active callers. - All
GENERIC,GENERIC_MULTI, andJTABLEcallers are replaced by domain APIs or explicitly retired. - File/media flows pass hybrid EFS/S3 validation.
- Admin-console replacement routes pass super-admin and impersonation checks.
- Disabled module, enabled module, and impersonation checks pass for representative API v2 routes.
.agents/rules/ARCHITECTURE.mdand.agents/rules/API_CONTRACTS.mdno longer describequery.php/post.phpas active application API entrypoints.
---¶
Source:
.agents/rules/API_V2_CONTRACT_INVENTORY.md— ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.