Skip to content

API v2 Cutover Validation Runbook

  • Status: KEEP_RESEARCH / HISTORICAL RUNBOOK
  • Does not own: current Task, branch, GitHub Issue, promotion or endpoint deletion authority
  • Current contract: .agents/rules/API_CONTRACTS.md

Purpose

This runbook preserves the former feature #436 cutover procedure. Reuse any step only from a newly activated Task after reconciling it with current source and Project Operations.

The runbook is designed for local first, then staging if staging is available. It must not write production data and must not run DDL.

Preconditions

  • Worktree is on the user-approved branch. Do not create or switch branches unless the user explicitly requests it.
  • Use .agents/rules/DEV_ENV.md for local server command, base URL, local DB target confirmation, test accounts, and browser verification setup.
  • Telegram-origin UI work exception follows .agents/rules/UI_STRUCTURE.md; never treat it as production write approval.
  • Production DB remains read-only for this runbook unless the user separately approves a production write.

Artifact Directory

Create one timestamped directory:

output/playwright/cutover-validation/<YYYYMMDD-HHMMSS>/

Required artifacts:

  • api-matrix.json
  • scan-results.txt
  • browser-results.json
  • login and API error screenshots when browser validation is run
  • for Telegram-origin UI work, screenshots of the affected UI included directly in the Telegram message body/attachment
  • final Task evidence with artifact paths and residual risk

Static Validation

Run these commands from the repository root.

git status --short --branch
git diff --check
test ! -e app/controllers/query.php
test ! -e app/controllers/post.php
rg "/app/controllers/(post|query)\.php|KJ\.api\.(post|query|queryPost)|KJ\.config\.url\.(post|query)" frontend public app
rg "KJ\.api\.(post|query|queryPost)|KJ\.config\.url\.(post|query)" frontend public app

Expected:

  • git diff --check exits 0.
  • Both deleted-controller test commands exit 0.
  • Both rg commands exit 1 with no matches.

Also run syntax checks for changed PHP and JS files. At minimum include every changed api_routes.php, changed page PHP file, and changed shared JS file.

For master.php / autocomplete.php retirement, also run the lookup compatibility scan before deletion:

git grep -n -E 'app/controllers/(master|autocomplete)\.php|/app/controllers/(master|autocomplete)\.php|master\.php\?key|autocomplete\.php\?TYPE|KJ\.config\.url\.(master|autocomplete)|serviceUrl|legacyParams' HEAD -- app frontend public config scripts .agents ':!app/utils/google-api-php-client/vendor' ':!reference'

Expected before deletion:

  • Matches are limited to current documentation, migration notes, and the controller files themselves.
  • No active browser or server-rendered application caller builds a request to either legacy lookup controller.

Expected after deletion:

  • The same scan has no active application caller matches and no controller-file matches.
  • Current documentation describes both paths as deleted, not temporary compatibility endpoints.

For deleted lookup controllers, source and runtime validation are the release gate: source scan must show no active callers, both direct legacy URLs must return 404 after deletion, and representative lookup consumers must continue to use owner API v2 routes without failed legacy requests. If a source or runtime test still reaches either legacy URL, block deletion and migrate that caller first.

API Matrix

Validate unauthenticated behavior first. Every protected API route must return 401 with an API v2 error envelope.

Area Method Path Expected unauthenticated status
platform GET /api/platform/ping 401
platform GET /api/platform/companies 401
platform GET /api/platform/companies/1 401
platform POST /api/platform/companies/form 401
add-on POST /api/addons/telegram/messages 401
YMS GET /api/yms/yard-map/state 401
YMS GET /api/yms/yard-moves/dispatch-queue 401
YMS POST /api/yms/yard-moves/preview 401
TMS GET /api/tms/transloads/planning-board 401
TMS GET /api/tms/equipment-loads/1/transloads 401
TMS GET /api/tms/deliveries/driver-list 401
OMS GET /api/oms/inbound-orders/options 401
OMS POST /api/oms/customer-pos 401
WMS GET /api/wms/inventory/report 401
BMS GET /api/bms/rates/commodities 401
shared files GET /api/files?TABLE_NAME=T_TRANSACTION&TABLE_ID=1 401
reports GET /api/reports/fbol?ID=1 401
deleted legacy GET /app/controllers/query.php 404
deleted legacy GET /app/controllers/post.php 404
deleted legacy lookup GET /app/controllers/master.php?key=COMMODITY 404 after lookup-controller deletion
deleted legacy lookup GET /app/controllers/autocomplete.php?TYPE=COMPANY&query=test 404 after lookup-controller deletion
route guard GET /api/not-a-route 404
method guard DELETE /api/platform/ping 405

When authenticated browser validation is approved, repeat the matrix for read-only GET routes with the local accounts documented in .agents/rules/DEV_ENV.md and record 200, 403, or domain-specific 400 as applicable.

Browser Matrix

Run with Playwright first. If Playwright cannot launch Chromium, use the Codex in-app browser and record the fallback.

Area URL Action Expected
auth/session /login.php Load page Login form renders; no console errors.
deleted endpoint /app/controllers/query.php Navigate directly Browser shows 404.
deleted endpoint /app/controllers/post.php Navigate directly Browser shows 404.
deleted lookup endpoint /app/controllers/master.php?key=COMMODITY Navigate directly after lookup-controller deletion Browser shows 404.
deleted lookup endpoint /app/controllers/autocomplete.php?TYPE=COMPANY&query=test Navigate directly after lookup-controller deletion Browser shows 404.
API v2 unauth /api/platform/ping Navigate directly JSON error with HTTP 401.
API v2 method DELETE /api/platform/ping Fetch from Playwright HTTP 405 and Allow header.

Authenticated page smoke, after local DB write confirmation if login will update T_USER.LAST_LOGIN:

  • /?page=yard-map
  • /?page=yard-dispatch
  • /?page=inbound-planning
  • /?page=inbound-loader
  • /?page=mk-inbound-orders
  • /?page=mk-outbound-orders
  • /?page=inventory-report
  • /?page=mk-freight-rate
  • /admin-console

For each page record URL, session user, visible primary UI, console errors, failed network requests, and screenshot path.

For Telegram-origin UI work, screenshot paths alone are not enough. Attach or embed the screenshot directly in the Telegram response, and record in the issue comment that the Telegram message included the screenshot.

Tenant And Module Guard Matrix

Use authenticated sessions only after the DB target confirmation step.

  • Primary local test account: verify normal tenant menu/pages and API v2 reads include effective CLIENT_ID.
  • Secondary local test account: verify MK tenant pages do not expose another tenant's rows.
  • Super-admin impersonation: verify target tenant from getClientId() controls module behavior.
  • Disabled module: disable only in local/staging after explicit write approval; verify page/API returns 403; restore the setting immediately.

Do not perform production tenant/module writes in this runbook.

Mutation Smoke Matrix

Only run on local/staging after explicit DB write approval and after printing the DB target query.

  • API 400: send malformed JSON to /api/platform/ping.
  • API 401: call any protected API without session.
  • API 403: access a disabled module route in local/staging.
  • API 404: call an unknown /api/... route and deleted legacy controllers.
  • API 405: call a valid route with an unsupported method.
  • UUIDv7 / audit: perform one reversible create/update in a low-risk table and confirm UUID, CREATED_AT, UPDATED_AT, and soft-delete behavior are preserved.
  • File/media: create or use a test T_FILE row and validate load URL, upload metadata registration, zip/download, Gmail attachment, AP invoice, and AP payment document flows.
  • Binary-safe JSON: include or locate a row with invalid or non-ASCII text and confirm API v2 JSON output remains parseable.

React API Client Error Handling

Until the React scaffold exists, validate the contract by review:

  • Domain methods call /api/..., not shared query.php/post.php.
  • Request bodies do not contain TYPE, ACTION, or USERNAME.
  • Error handling surfaces error.message and preserves requestId.
  • HTTP 400/401/403/404/405 responses throw a typed API error.

Once the React scaffold exists, add automated tests for the base apiRequest helper before USER_REVIEW.

Rollback Criteria

Rollback or block release if any of these occur:

  • Any active runtime caller still references shared query.php/post.php, KJ.api.post/query/queryPost, or KJ.config.url.post/query.
  • Deleted shared controllers return anything other than 404.
  • Protected API v2 routes fail open instead of returning 401/403.
  • Module-disabled routes bypass module guard.
  • Tenant-scoped read/write omits CLIENT_ID.
  • API v2 error envelopes omit visible message or requestId.
  • File/media flows lose hybrid EFS/S3 T_FILE behavior.
  • Local/staging mutation smoke shows UUID/audit/soft-delete regression.

Rollback plan:

  1. Stop release promotion.
  2. Revert only the cutover changes in the release branch or redeploy the last known-good artifact.
  3. Re-enable the affected caller through its module-owned API v2 route, not by restoring shared query.php/post.php.
  4. Re-run this runbook and attach new artifacts before requesting review again.

Final Report Checklist

The issue comment must include:

  • artifact directory path
  • static scan result summary
  • API matrix pass/fail counts
  • browser matrix pass/fail counts
  • unavailable checks and why
  • residual risk
  • rollback plan summary

---

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

In this section

Document Contents
API_V2_CUTOVER_VALIDATION_RUNBOOK API v2 Cutover Validation Runbook
CTC_ASSIGN_WORK_AND_CLOCK_OUT_FUTURE_OPERATOR_RUNBOOK Legacy Procedure Path
CTC_BILLING_QBO_FILES_EMAIL_OPERATOR_RUNBOOK Billing, QBO, Files And Email Operator Runbook
CTC_FIELD_USER_PROCESS_SYSTEM_TEST_RUNBOOK Field User Process System Test Runbook
CTC_FINAL_LOADING_REVIEW_OPERATOR_RUNBOOK Final Loading Review Operator Runbook
CTC_INBOUND_ASSIGNMENT_LOADER_WORKFORCE_RUNBOOK Inbound Assignment, Loader And Workforce Runbook
CTC_STREET_TURN_AND_REVERT_OPERATOR_RUNBOOK STREET TURN · Operator Runbook
CTC_YARD_DRIVER_PARTIAL_RESULT_RUNBOOK Yard Dispatch, Pull Out Closing And Driver Partial-Result Runbook
DATA_ARCHIVE_RUNBOOK Data Archive Runbook
HUB_QA_OPERATIONS_RUNBOOK Hub QA Operations Runbook
INCIDENT_HOTFIX_RUNBOOK Incident Hotfix Runbook
MK_ADMIN2_FUNCTIONAL_TEST_RUNBOOK Admin2 Full Functional Test Checklist
MK_COMMERCIAL_INBOUND_OUTBOUND_BOOKING_OPERATOR_RUNBOOK COMMERCIAL INBOUND · Operator Runbook
MK_INVENTORY_ALLOCATION_OPERATOR_RUNBOOK INVENTORY ALLOCATION · Operator Runbook
MK_PHYSICAL_SCALE_OPERATOR_RUNBOOK PHYSICAL SCALE · Operator Runbook
MK_TRADE_COST_RATE_DOCUMENT_OUTPUTS_OPERATOR_RUNBOOK TRADE COST · Operator Runbook
PLATFORM_ACCESS_DIAGNOSTICS_ADMIN_SUPPORT_RUNBOOK PLATFORM ACCESS DIAGNOSTICS · Administrator And Support Runbook
PLATFORM_AUDIT_AND_SUPPORT_TIMELINE_RUNBOOK Platform Audit And Support Timeline Runbook
PLATFORM_DEPLOYMENT_HEALTH_ROLLBACK_AND_RESTORE_RUNBOOK Platform Deployment Health, Rollback And Restore Runbook
PLATFORM_IDENTITY_IMPERSONATION_ADMIN_SUPPORT_RUNBOOK PLATFORM IDENTITY IMPERSONATION · Administrator And Support Runbook
PLATFORM_INTEGRATION_PROVIDER_RECOVERY_RUNBOOK Platform Integration And Provider Recovery Runbook
PLATFORM_TENANT_CONFIGURATION_ADMIN_SUPPORT_RUNBOOK PLATFORM TENANT CONFIGURATION · Administrator And Support Runbook
POPUP_DUAL_RUN_ROLLBACK_RUNBOOK Popup Dual-Run and Rollback Runbook
PRODUCTION_ENVIRONMENT_RUNBOOK Production Environment
QUICKBOOKS_TIME_PRODUCTION_SETUP_RUNBOOK QuickBooks Time Production Setup
RELEASE_GATE_RUNBOOK Release Gate Runbook
SYSTEM_REBUILD_READINESS_REVIEW_RUNBOOK System Rebuild-Readiness Review Runbook