# Phase 5 delivery

User approval: “continue to phase 5 and make sure everything stays on InnoDB”. Implementation extends the existing Laravel application and preserves prior data, identities and MFA. Phase 6 remains unstarted.

## Delivered areas

| Area | Implementation |
| --- | --- |
| Assets | Categories, purchase/serial/tag/warranty, printable Code 39 labels, maintenance, physical verification, exact cost records, whole-month straight-line management book values, independent disposal approval |
| Custody | Employee issue/acceptance/return, explicit return-and-reissue transfers, timestamps and condition evidence, append-only equipment events, concurrent issuance serialized on the tenant row |
| Fleet | Asset-linked plate/VIN register; registration, insurance, permit and inspection; verified driver class/licence evidence and expiry checks; mileage, date/km service thresholds, fuel, fines, accidents and costs |
| Secure evidence | Existing encrypted, quarantine-scanned document vault; tenant-bound equipment-document links, verified employee licence ownership, narrow read permission for linked company evidence |
| Lifecycle | Accepted handover completes linked onboarding task; career changes generate current-custody review tasks; live asset/fleet exit clearance and independent final-archive recheck |
| Forms/workflows | Typed custom forms; visual add/remove/reorder builder; sequential and parallel user approvals; typed conditions; immutable submission snapshots; dated delegation, independent decisions, rejection/cancellation, SLA escalation; registered event review triggers |
| Reports | Permission/entitlement-filtered dashboards and asset valuation; HR/compliance/assets/fleet CSV registers; tenant-preserving streaming and formula neutralization |
| Operations | PhaseFiveSeeder, Complete Workforce plan, idempotent phase installer, durable reference-only bells, audit/outbox integration, queued monitoring/escalation and explicit monitor command |

## Schema and storage

Migration `2026_10_16_000006_create_assets_fleet_automation` creates twelve tenant-scoped tables with explicit InnoDB engines: asset_categories, assets, vehicles, driver_licences, custodies, equipment_events, equipment_documents, form_templates, automation_rules, automation_runs, automation_tasks and approval_delegations. Structural references use composite tenant/id foreign keys. Existing table engines are retained; MySQL/MariaDB connections initialize their session default to InnoDB. Host-wide settings are unchanged.

An encrypted, DPAPI-wrapped pre-upgrade SQL backup was created and its decrypt/hash roundtrip checked before this phase's installation. No plaintext dump was saved. Keep the DPAPI identity, original app key and document key recovery materials available according to the operations guide.

## Validation

- Full MySQL regression: **168 tests passed, 640 assertions** on the isolated `zentrikhrms_codex_test` database. This includes all-table/session InnoDB checks and earlier phases' regressions.
- Full SQLite regression, run independently: **167 tests passed, 565 assertions; 1 expected storage-engine skip**. The MySQL run performs that engine check.
- Phase 5 targeted SQLite suite: **29 tests passed, 66 assertions**. It covers custody, return/reissue, immutable event history, disposal separation, verified driver and vehicle evidence, expired licences, odometer/service guards, exact costs, onboarding acceptance, live exit checks, final-archive rechecks, tenant isolation, disabled fleet route guards, parallel/sequential/conditional approvals, snapshots, delegation/self approval, duplicate decisions, idempotent monitoring/escalation, real event triggers, HTTP string inputs, export context/formula escaping and repeatable installation.
- Full browser regression: **6 tests passed**, using an isolated browser SQLite fixture. Phase 5 verifies asset registration, handover, employee acceptance, return, actual visual form/workflow publishing, form submission, independent approval, dashboard rendering and a 390px employee equipment screen without horizontal overflow. Prior phase UI tests also pass.
- Production frontend build, Blade compilation, Pint formatting checks and Composer validation pass. Desktop/mobile screenshots were visually inspected and saved in `docs/screenshots/phase5-*`.
- Applied the migration and `zentrik:phase5 zentrik` to the working database after the encrypted backup and targeted verification. All **9 migrations** are applied; the plan is **Complete Workforce** with assets/fleet and previous modules enabled. The original two accounts remain. New operational tables and employees contain zero sample records.
- [Storage verification](PHASE_5_STORAGE_VERIFICATION.json): **73 tables, zero non-InnoDB tables; application PDO session default InnoDB**. Working login endpoint returns HTTP 200. Host-wide MySQL default was not changed.

Commands: `php artisan test --compact --no-ansi` (SQLite); the same command with `DB_CONNECTION=mysql DB_DATABASE=zentrikhrms_codex_test DB_USERNAME=root DB_PASSWORD=` (MySQL); `npx playwright test --reporter=line`; `npm run build`; `php artisan view:cache`; `php vendor/bin/pint --test --no-ansi`; `composer validate --no-check-publish`.

## Design limits and deployment gates

- Driver classes and life/salvage assumptions are company configuration, requiring a qualified reviewer. No automatic legal eligibility, police/fine integration, accounting posting or statutory depreciation rules are claimed.
- Vehicle evidence and licences use the existing real scan-ready gate. ClamAV, optional OCR and production Vault/S3 services still require configured deployment services; scanner outage quarantines evidence and blocks issuance. Local metadata tests use controlled fixtures, never a production fake scanner.
- Workflow actions create review records, tasks and reference notifications. They do not execute arbitrary code, SQL, external URLs or bypass the typed services' business approvals. Event rules are intentionally restricted to asset changes, fleet changes and lifecycle decisions. A rule without an independent eligible reviewer rejects its triggering transaction; administrators can pause the rule.
- Each published definition is a new record. Existing runs retain snapshots; no visual editing of historical submissions or reassigning completed decisions is offered. Overdue escalations notify workflow administrators; escalation never grants approval automatically.
- Transfers require return inspection and a new handover. Historical custody and events remain visible. Barcode symbols contain the inventory tag, require authenticated inventory search, and use Code 39; hardware/printer calibration should be checked before bulk label printing.
- Reports give current operational states and dated asset book values, not a historical financial ledger. Cost events do not pay fines, submit insurance claims or post payroll deductions. UI reference pickers show the first 200 eligible records, and equipment detail shows the latest 100 events; exports stream complete authorized registers.
- The main scheduler/notification worker remains off. Existing email deliveries were not sent. New phase notifications use the bell delivery channel. No real employee, asset, driver, licence, workflow or financial records are inserted into the working database by installation.

Barcode encoding values are attributed in source to the Apache-2.0 [ZXing Code39Reader](https://github.com/zxing/zxing/blob/master/core/src/main/java/com/google/zxing/oned/Code39Reader.java). This adds no remote barcode service or runtime dependency.
