# Final route matrix

Production HTTP routes from `app/Config/Routes.php`. Global CSRF filter applies to POST. Authenticated group uses `auth`, `sessionVersion`, `passwordGate`, and optional Company/Plant scope. There are **zero** HTTP DELETE routes, **zero** seed/demo/probe/fixture/test routes, **zero** audit edit/delete routes, and **zero** Credit Note cancel/delete/void routes.

Permission is the controller’s primary guard (first `can` / `forbidden` in the action, or `perm()` on product/raw-material). Direct unauthorised POST returns **403**. Object-level GET outside Company/Plant returns **403**. Production ignores `?frame=`.

| Method | Route | Controller | Permission (primary) | Scope | CSRF | Transaction | Status guard | Redirect/response | Tests |
|---|---|---|---|---|---|---|---|---|---|
| GET | `/login` | `LoginController::show` | none (public login) | public | n/a | — | permission; production ignores ?frame= | HTML | Phase7SecurityHttpTest; Phase6CloseoutTest; AuthAndAuthorisationTest |
| POST | `/login` | `LoginController::attempt` | none (public login) | public | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7SecurityHttpTest; Phase6CloseoutTest; AuthAndAuthorisationTest |
| GET | `/health` | `closure` | none (public health JSON) | public | n/a | — | permission; production ignores ?frame= | JSON | Phase7SecurityHttpTest; Phase6CloseoutTest; AuthAndAuthorisationTest |
| POST | `/logout` | `LoginController::logout` | authenticated session | session | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7SecurityHttpTest; Phase6CloseoutTest; AuthAndAuthorisationTest |
| POST | `/session/switch-role` | `LoginController::switchRole` | IAM.SWITCH_ROLE (held role; not a permission union) | session | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/account/password` | `PasswordChangeController::show` | authenticated (password gate; no catalogue code) | session | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/account/password` | `PasswordChangeController::update` | authenticated (password gate; no catalogue code) | session | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/` | `HomeController::index` | DASHBOARD.VIEW | optional Company/Plant context | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/session/context` | `HomeController::context` | authenticated session (active-role permission JSON) | optional Company/Plant context | n/a | — | permission; production ignores ?frame= | JSON | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/inward/vendor` | `InwardController::create` | INWARD.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| POST | `/inward/vendor` | `InwardController::store` | INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/vendor/(:num)` | `InwardController::show/$1` | INWARD.VIEW or INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/production` | `InwardController::productionCreate` | INWARD.VIEW or INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| POST | `/inward/production` | `InwardController::productionStore` | INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/production/(:num)` | `InwardController::productionShow/$1` | INWARD.VIEW or INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/opening-stock` | `InwardController::openingCreate` | INWARD.VIEW or OPENING_STOCK.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| POST | `/inward/opening-stock` | `InwardController::openingStore` | OPENING_STOCK.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/opening-stock/(:num)` | `InwardController::openingShow/$1` | INWARD.VIEW or OPENING_STOCK.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/returns` | `ReturnController::create` | INWARD.VIEW or INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| POST | `/inward/returns` | `ReturnController::store` | INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward/returns/(:num)` | `ReturnController::show/$1` | INWARD.VIEW or INWARD.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/inward` | `InwardController::index` | INWARD.LIST or INWARD.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| POST | `/inward/(:num)/reverse` | `InwardController::reverse/$1` | INWARD.REVERSE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| POST | `/inward/(:num)/correct` | `InwardController::correct/$1` | INWARD.REVERSE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase1/3 inward tests; Phase7FrameAcceptanceHttpTest |
| GET | `/rejections/create` | `RejectionController::create` | DISPATCH.VIEW or DISPATCH.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/rejections/create` | `RejectionController::store` | DISPATCH.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/rejections/(:num)/reassign` | `RejectionController::reassign/$1` | DISPATCH.REASSIGN | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/rejections/(:num)/reassign` | `RejectionController::reassignStore/$1` | DISPATCH.REASSIGN | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/rejections/(:num)/disposition` | `RejectionController::disposition/$1` | DISPATCH.DISPOSE or DISPATCH.REASSIGN or DISPATCH.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/rejections/(:num)/disposition` | `RejectionController::dispositionStore/$1` | DISPATCH.DISPOSE or DISPATCH.REASSIGN | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/rejections/(:num)` | `RejectionController::show/$1` | DISPATCH.VIEW or DISPATCH.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/wastage` | `WastageController::index` | WASTAGE.LIST or WASTAGE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/wastage/create` | `WastageController::create` | WASTAGE.VIEW or WASTAGE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/wastage/create` | `WastageController::store` | WASTAGE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/wastage/(:num)/approve` | `WastageController::approve/$1` | WASTAGE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/wastage/(:num)/return` | `WastageController::returnForCorrection/$1` | WASTAGE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/wastage/(:num)/reverse` | `WastageController::reverseForm/$1` | WASTAGE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted status + row version; no compatibility-only POST | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/wastage/(:num)/reverse` | `WastageController::reverse/$1` | WASTAGE.CANCEL_REVERSE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/wastage/(:num)` | `WastageController::show/$1` | WASTAGE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/challans` | `ChallanController::index` | CHALLAN.LIST | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/challans/create` | `ChallanController::create` | CHALLAN.ADD or CHALLAN.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans` | `ChallanController::store` | CHALLAN.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)/submit` | `ChallanController::submit/$1` | CHALLAN.EDIT | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)/approve` | `ChallanController::approve/$1` | CHALLAN.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)/return` | `ChallanController::returnForCorrection/$1` | CHALLAN.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)/cancel` | `ChallanController::cancel/$1` | CHALLAN.CANCEL | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)/invoice/approve` | `ChallanController::approveInvoice/$1` | INVOICE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)/invoice` | `ChallanController::createInvoice/$1` | INVOICE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/challans/(:num)` | `ChallanController::update/$1` | CHALLAN.EDIT | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/challans/(:num)` | `ChallanController::show/$1` | CHALLAN.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoices/unbilled` | `UnbilledController::index` | INVOICE.LIST or INVOICE.VIEW or INVOICE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/unbilled` | `UnbilledController::toggle` | INVOICE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoices/later` | `LaterInvoiceController::create` | INVOICE.VIEW or INVOICE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/later` | `LaterInvoiceController::store` | INVOICE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoices/later/(:num)` | `LaterInvoiceController::show/$1` | INVOICE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/later/(:num)` | `LaterInvoiceController::update/$1` | INVOICE.EDIT or INVOICE.ADD | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoices` | `InvoiceController::index` | INVOICE.LIST | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/(:num)/submit` | `InvoiceController::submit/$1` | INVOICE.EDIT | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/(:num)/approve` | `InvoiceController::approve/$1` | INVOICE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/(:num)/return` | `InvoiceController::returnForCorrection/$1` | INVOICE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/(:num)/cancel` | `InvoiceController::cancel/$1` | INVOICE.CANCEL | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| POST | `/invoices/(:num)/irn` | `InvoiceController::recordIrn/$1` | INVOICE.RECORD_IRN_DETAILS | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | PENDING_IRN / APPROVED_PRE_IRN / IRN_FAILED; append-only manual recording | redirect on success; 403 permission/scope; validation errors redisplay | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoices/(:num)/irn` | `InvoiceController::irn/$1` | INVOICE.VIEW or INVOICE.RECORD_IRN_DETAILS | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | PENDING_IRN / APPROVED_PRE_IRN / IRN_FAILED; append-only manual recording | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoices/(:num)` | `InvoiceController::show/$1` | INVOICE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Invoice/Challan family; Phase7P28JourneyTest |
| GET | `/invoice-reservations/create` | `InvoiceReservationController::create` | INVOICE.RESERVE_NUMBER or INVOICE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/invoice-reservations` | `InvoiceReservationController::index` | INVOICE.RESERVE_NUMBER or INVOICE.RELEASE_NUMBER | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/invoice-reservations` | `InvoiceReservationController::store` | INVOICE.RESERVE_NUMBER | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/invoice-reservations/(:num)/release` | `InvoiceReservationController::release/$1` | INVOICE.RELEASE_NUMBER | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/credit-notes` | `CreditNoteController::index` | CREDIT_NOTE.LIST or CREDIT_NOTE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | CreditNote*; Phase7ReconciliationTest |
| GET | `/credit-notes/create` | `CreditNoteController::create` | CREDIT_NOTE.VIEW or CREDIT_NOTE.CREATE | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | permission; production ignores ?frame= | HTML | CreditNote*; Phase7ReconciliationTest |
| POST | `/credit-notes/create` | `CreditNoteController::store` | CREDIT_NOTE.CREATE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | CreditNote*; Phase7ReconciliationTest |
| POST | `/credit-notes/(:num)/submit` | `CreditNoteController::submit/$1` | CREDIT_NOTE.CREATE or CREDIT_NOTE.EDIT | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | CreditNote*; Phase7ReconciliationTest |
| POST | `/credit-notes/(:num)/approve` | `CreditNoteController::approve/$1` | CREDIT_NOTE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | CreditNote*; Phase7ReconciliationTest |
| POST | `/credit-notes/(:num)/return` | `CreditNoteController::returnForCorrection/$1` | CREDIT_NOTE.APPROVE | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted status + row version; no compatibility-only POST | redirect on success; 403 permission/scope; validation errors redisplay | CreditNote*; Phase7ReconciliationTest |
| GET | `/credit-notes/(:num)/irn` | `CreditNoteController::irn/$1` | CREDIT_NOTE.VIEW or CREDIT_NOTE.RECORD_IRN_DETAILS | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | PENDING_IRN / APPROVED_PRE_IRN / IRN_FAILED; append-only manual recording | HTML | CreditNote*; Phase7ReconciliationTest |
| POST | `/credit-notes/(:num)/irn` | `CreditNoteController::recordIrn/$1` | CREDIT_NOTE.RECORD_IRN_DETAILS | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | PENDING_IRN / APPROVED_PRE_IRN / IRN_FAILED; append-only manual recording | redirect on success; 403 permission/scope; validation errors redisplay | CreditNote*; Phase7ReconciliationTest |
| POST | `/credit-notes/(:num)` | `CreditNoteController::update/$1` | CREDIT_NOTE.EDIT | Company/Plant object-level; unauthorised GET/POST 403 | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | CreditNote*; Phase7ReconciliationTest |
| GET | `/credit-notes/(:num)` | `CreditNoteController::show/$1` | CREDIT_NOTE.VIEW | Company/Plant object-level; unauthorised GET/POST 403 | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | CreditNote*; Phase7ReconciliationTest |
| GET | `/reports/material-ledger` | `LedgerController::index` | REPORT.VIEW | Company/Plant report filters | n/a | — | permission; production ignores ?frame= | HTML | Phase5 report/export tests; Phase7ReconciliationTest |
| POST | `/reports/material-ledger/export` | `LedgerController::export` | REPORT.EXPORT | Company/Plant report filters | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase5 report/export tests; Phase7ReconciliationTest |
| GET | `/reports` | `ReportController::index` | REPORT.VIEW | Company/Plant report filters | n/a | — | permission; production ignores ?frame= | HTML | Phase5 report/export tests; Phase7ReconciliationTest |
| GET | `/reports/(:segment)` | `ReportController::show/$1` | REPORT.VIEW | Company/Plant report filters | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase5 report/export tests; Phase7ReconciliationTest |
| POST | `/reports/(:segment)/export` | `ReportController::export/$1` | REPORT.EXPORT | Company/Plant report filters | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase5 report/export tests; Phase7ReconciliationTest |
| GET | `/exports/(:segment)/download` | `ExportDownloadController::download/$1` | REPORT.VIEW | opaque download token + REPORT.VIEW; 30-day expiry | n/a | — | persisted row; 404 if missing; 403 if out of scope | file/JSON | Phase5 report/export tests; Phase7ReconciliationTest |
| GET | `/audit` | `AuditController::index` | AUDIT.VIEW | AUDIT company grant; object not plant-scoped | n/a | — | permission; production ignores ?frame= | HTML | Phase6AuditCompletenessTest; Phase7SecurityHttpTest |
| POST | `/audit/export` | `AuditController::export` | AUDIT.EXPORT | AUDIT company grant; object not plant-scoped | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase6AuditCompletenessTest; Phase7SecurityHttpTest |
| GET | `/iam/users` | `IamUserController::index` | IAM.VIEW | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | permission; production ignores ?frame= | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/users/create` | `IamUserController::create` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | permission; production ignores ?frame= | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/users` | `IamUserController::store` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/users/(:num)` | `IamUserController::show/$1` | IAM.VIEW | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/users/(:num)/edit` | `IamUserController::edit/$1` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/users/(:num)/deactivate` | `IamUserController::deactivate/$1` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/users/(:num)/reactivate` | `IamUserController::reactivate/$1` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/users/(:num)/revoke-sessions` | `IamUserController::revokeSessions/$1` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/users/(:num)/temporary-password` | `IamUserController::temporaryPassword/$1` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/users/(:num)` | `IamUserController::update/$1` | IAM.MANAGE_USERS | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/roles` | `IamRoleController::index` | IAM.VIEW | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | permission; production ignores ?frame= | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/roles/create` | `IamRoleController::create` | IAM.MANAGE_ROLES | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | permission; production ignores ?frame= | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/roles` | `IamRoleController::store` | IAM.MANAGE_ROLES | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/roles/(:num)` | `IamRoleController::show/$1` | IAM.VIEW | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/iam/roles/(:num)/edit` | `IamRoleController::edit/$1` | IAM.MANAGE_ROLES | IAM company grant; last Super Admin / Hybrid C guards | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/roles/(:num)/deactivate` | `IamRoleController::deactivate/$1` | IAM.MANAGE_ROLES | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| POST | `/iam/roles/(:num)` | `IamRoleController::update/$1` | IAM.MANAGE_ROLES | IAM company grant; last Super Admin / Hybrid C guards | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase6Iam*; Phase7SecurityHttpTest |
| GET | `/companies` | `CompanyController::index` | COMPANY.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/companies/create` | `CompanyController::create` | COMPANY.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/companies` | `CompanyController::store` | COMPANY.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/companies/(:num)/deactivate` | `CompanyController::deactivate/$1` | COMPANY.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/companies/(:num)` | `CompanyController::update/$1` | COMPANY.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/companies/(:num)` | `CompanyController::show/$1` | COMPANY.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/plants` | `PlantController::index` | PLANT.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/plants/create` | `PlantController::create` | PLANT.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/plants` | `PlantController::store` | PLANT.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/plants/(:num)/mappings/(:num)/deactivate` | `PlantController::deactivateMapping/$1/$2` | PLANT.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/plants/(:num)/deactivate` | `PlantController::deactivate/$1` | PLANT.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/plants/(:num)` | `PlantController::update/$1` | PLANT.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/plants/(:num)` | `PlantController::show/$1` | PLANT.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/clients` | `ClientController::index` | CLIENT.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/clients/create` | `ClientController::create` | CLIENT.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/clients` | `ClientController::store` | CLIENT.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/clients/(:num)/sites` | `ClientSiteController::index/$1` | CLIENT_SITE.LIST | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/clients/(:num)/sites/create` | `ClientSiteController::create/$1` | CLIENT_SITE.ADD | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/clients/(:num)/sites` | `ClientSiteController::store/$1` | CLIENT_SITE.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/clients/(:num)/sites/(:num)/deactivate` | `ClientSiteController::deactivate/$1/$2` | CLIENT_SITE.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/clients/(:num)/sites/(:num)` | `ClientSiteController::update/$1/$2` | CLIENT_SITE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/clients/(:num)/sites/(:num)` | `ClientSiteController::show/$1/$2` | CLIENT_SITE.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/clients/(:num)/deactivate` | `ClientController::deactivate/$1` | CLIENT.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/clients/(:num)` | `ClientController::update/$1` | CLIENT.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/clients/(:num)` | `ClientController::show/$1` | CLIENT.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vendors` | `VendorController::index` | VENDOR.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vendors/create` | `VendorController::create` | VENDOR.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vendors` | `VendorController::store` | VENDOR.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vendors/(:num)/deactivate` | `VendorController::deactivate/$1` | VENDOR.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vendors/(:num)` | `VendorController::update/$1` | VENDOR.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vendors/(:num)` | `VendorController::show/$1` | VENDOR.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/products` | `ProductController::index` | PRODUCT.LIST or PRODUCT.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/products/create` | `ProductController::create` | PRODUCT.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/products` | `ProductController::store` | PRODUCT.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/products/(:num)/deactivate` | `ProductController::deactivate/$1` | PRODUCT.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/products/(:num)` | `ProductController::update/$1` | PRODUCT.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/products/(:num)` | `ProductController::show/$1` | PRODUCT.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/raw-materials` | `RawMaterialController::index` | RAW_MATERIAL.LIST or RAW_MATERIAL.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/raw-materials/create` | `RawMaterialController::create` | RAW_MATERIAL.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/raw-materials` | `RawMaterialController::store` | RAW_MATERIAL.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/raw-materials/(:num)/deactivate` | `RawMaterialController::deactivate/$1` | RAW_MATERIAL.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/raw-materials/(:num)` | `RawMaterialController::update/$1` | RAW_MATERIAL.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/raw-materials/(:num)` | `RawMaterialController::show/$1` | RAW_MATERIAL.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/units` | `UnitController::index` | UNIT.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/units` | `UnitController::store` | UNIT.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/units/(:num)/deactivate` | `UnitController::deactivate/$1` | UNIT.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/units/(:num)` | `UnitController::update/$1` | UNIT.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/recipes` | `RecipeController::index` | RECIPE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/recipes/create` | `RecipeController::create` | RECIPE.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/recipes` | `RecipeController::store` | RECIPE.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/recipes/(:num)/deactivate` | `RecipeController::deactivate/$1` | RECIPE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/recipes/(:num)` | `RecipeController::update/$1` | RECIPE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/recipes/(:num)` | `RecipeController::show/$1` | RECIPE.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vehicle-suppliers` | `VehicleSupplierController::index` | VENDOR.VIEW or VEHICLE.VIEW | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vehicle-manufacturers` | `VehicleManufacturerController::index` | VEHICLE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicle-manufacturers` | `VehicleManufacturerController::store` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicle-manufacturers/(:num)/deactivate` | `VehicleManufacturerController::deactivate/$1` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicle-manufacturers/(:num)` | `VehicleManufacturerController::update/$1` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vehicle-brands` | `VehicleBrandController::index` | VEHICLE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicle-brands` | `VehicleBrandController::store` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicle-brands/(:num)/deactivate` | `VehicleBrandController::deactivate/$1` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicle-brands/(:num)` | `VehicleBrandController::update/$1` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vehicles` | `VehicleController::index` | VEHICLE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vehicles/create` | `VehicleController::create` | VEHICLE.ADD | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicles` | `VehicleController::store` | VEHICLE.ADD | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicles/(:num)/supplier` | `VehicleController::changeSupplier/$1` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicles/(:num)/deactivate` | `VehicleController::deactivate/$1` | VEHICLE.ACTIVATE_DEACTIVATE | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/vehicles/(:num)` | `VehicleController::update/$1` | VEHICLE.EDIT | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/vehicles/(:num)` | `VehicleController::show/$1` | VEHICLE.VIEW | Company (masters); Plant where plant-owned | n/a | — | persisted row; 404 if missing; 403 if out of scope | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/rates/universal` | `RateController::universal` | RATE.VIEW or RATE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/rates/universal` | `RateController::storeUniversal` | RATE.ADD (service assertPermission) | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/rates/company` | `RateController::company` | RATE.VIEW or RATE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/rates/company` | `RateController::storeCompany` | RATE.ADD (service assertPermission) | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/charges` | `ChargeController::index` | CHARGE.VIEW or CHARGE.LIST | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/charges` | `ChargeController::store` | CHARGE.ADD (service; CHARGE.EDIT when id present) | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/charges/(:num)/deactivate` | `ChargeController::deactivate/$1` | CHARGE.ACTIVATE_DEACTIVATE (service) | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| GET | `/statutory-timing` | `StatutoryController::index` | STATUTORY.VIEW or STATUTORY.MANAGE | Company (masters); Plant where plant-owned | n/a | — | permission; production ignores ?frame= | HTML | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/statutory-timing` | `StatutoryController::store` | STATUTORY.MANAGE (service) | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | server validation + permission; CSRF | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |
| POST | `/statutory-timing/(:num)/deactivate` | `StatutoryController::deactivate/$1` | STATUTORY.MANAGE (service) | Company (masters); Plant where plant-owned | yes (global filter) | mutating service transaction | persisted row; 404 if missing; 403 if out of scope | redirect on success; 403 permission/scope; validation errors redisplay | Phase7FrameAcceptanceHttpTest; Phase7SecurityHttpTest; module family |

Route count in this matrix: **182**. Login, logout, switch-role, password-change, dashboard `/`, and `/health` are included. `GET /health` returns JSON `{status:ok, phase:7, engine:innodb}`.

