# Phase 2 delivery

## Result and scope

The user approved Phase 2 after Phase 1. Employees, the encrypted document vault, compliance renewals and notification management are implemented and enabled for the existing Zentrik tenant. Existing users, MFA state and organizational records were retained. No fabricated employee or document data was added to the working installation. This document records the Phase 2 delivery. Phase 3 was subsequently approved and is documented in PHASE_3_DELIVERY.md.

All six migrations are applied. All 38 working database tables use InnoDB, and the existing connection/session/Docker enforcement remains in place. The working database remains `zentrikhrms` with the requested local root account and empty password.

## Delivered functionality

- Company-scoped employee master, unique employee IDs, linked self-service accounts, personal information, dependants, employment contracts and effective position assignments.
- Employee 360, directory search, transactional CSV import, filtered/formula-safe export, employment and activity history. Actual assignments feed position occupancy and enforce approved capacity, including future boundaries and capacity reductions.
- Configurable employee/company/branch document types, requirements, expiry rules and retention periods; document records, independent versions and private authenticated preview/download.
- Signature/MIME/extension/size validation, restricted PDF content, private encrypted quarantine, real ClamAV INSTREAM integration and fail-closed scanner retries. No application configuration selects a fake clean scanner.
- AES-256-GCM per-version data keys and nonces, tenant/document/version/purpose context binding, ciphertext integrity checks, wrapped key/version metadata, Windows DPAPI and TLS Vault Transit adapters. APP_KEY is not used as a document master key.
- Optional isolated OCR worker with bounded inputs/pages/text/subprocesses, container restrictions and temporary plaintext cleanup; retained OCR suggestions use independent encryption and require human verification.
- Replacement invalidation of metadata verification, legal holds, archived-only retention purge, file/OCR key metadata deletion, and append-only document access records.
- Renewal ownership, due dates, costs, new scanned evidence, human verification and expiry updates; stale or foreign evidence is rejected.
- Compliance dashboard with expired/due/unverified/missing employee/company/branch records and renewal register.
- Bell/email notification center, editable plain-text templates, configurable reminders and role recipients, overdue escalation, timezone-local digests, unique delivery keys, transport retries/backoff, delivery logs and own-account test-send controls.
- New permissions and backend policies; global search includes employees/documents only for entitled roles. Employee self-access requires an explicit account link and cannot read coworkers.

## Changed source areas

| Area | Files and purpose |
| --- | --- |
| Schema | `database/migrations/2026_10_16_000003_create_people_and_compliance.php` adds 12 InnoDB tables with tenant indexes/references |
| Seed/catalog | `PhaseTwoSeeder`, existing provisioning and FoundationSeeder add available modules, built-in role permissions, types, rules, templates and the People & Compliance plan |
| Employees | `app/Domain/Employees`, Employee models/policy/controller, `resources/views/employees` |
| Vault | `app/Domain/Documents`, document models/policy/controller, `config/documents.php`, private filesystem disk and `scripts/dpapi.ps1` |
| Compliance | `ComplianceService`, `ReminderScheduler`, `ComplianceController`, renewals/rules and dashboard |
| Notifications | `NotificationService`, delivery/template models/controller, scheduler jobs and UI |
| Integration | `routes/phase2.php`, event registry, position occupancy/capacity validation, navigation/search/dashboard and queue settings |
| Infrastructure | ClamAV/optional OCR Compose services, private OCR worker source/Dockerfile, environment examples and timeout/reservation settings |
| Verification | `PhaseTwoTest`, DPAPI integration, Vault adapter, ClamAV protocol fixtures/tests, browser Phase 2 workflow and storage-engine regression |
| Documentation | Phase 2 plan, walkthrough, security/operations, architecture and threat-model extensions |

## Verified outcomes

| Check | Result |
| --- | --- |
| Full MySQL suite | 69 passed, 303 assertions |
| Full SQLite suite on Windows | 68 passed, 263 assertions; one MySQL-specific storage-engine test skipped |
| Full Chrome browser suite | 3 passed, including MFA and Phase 2 create/quarantine/hold/compliance/notification/mobile flows |
| Real Windows DPAPI | Encryption, recovery and wrong-context rejection passed |
| ClamAV adapter | INSTREAM framing/clean/rejected results tested against a protocol fixture; real unavailable-daemon behavior tested |
| Vault adapter | TLS requirement, context and key-version handling tested against controlled HTTP responses |
| Phase 2 rollback/re-migration | Passed on disposable MySQL database; working data untouched |
| Encrypted pre-upgrade SQL recovery | Real DPAPI backup decrypted through memory and restored to separate recovery database; 26 InnoDB tables, one tenant and two accounts verified |
| Working installation | 38 InnoDB tables, all six migrations applied, five enabled modules, login endpoint HTTP 200 |
| UI/build | Production frontend build and Blade compilation passed; desktop Employee 360 and mobile compliance screenshots inspected |
| PHP formatting gate | Laravel Pint passed |
| Compose/Python | Compose with OCR profile validates without an engine; OCR worker syntax validated |

Tests cover tenant/record/account/evidence isolation; scoped self-access; unauthorized upload rejection before file processing; unique employee IDs; atomic CSV rollback; effective capacity and history; GCM nonce/key uniqueness, roundtrip, wrong-context and tamper rejection; ciphertext-only storage; authenticated access logging; malware and scanner outages; invalid/active file rejection; key outages; verification invalidation; renewal lifecycle; legal hold/retention/purge; encrypted OCR; key rotation; timezone date boundaries; delivery deduplication, retries/backoff and recipient isolation; role/module gates and rendered screens.

Test wrapping keys and clean/rejected scanner implementations are confined to tests. The real application uses DPAPI/Vault and ClamAV. A test protocol server is not proof that a live malware engine's signatures are current.

## Commands and migrations

```text
php artisan migrate --force
php artisan zentrik:phase2 zentrik
php artisan test --compact
php artisan test --filter=PhaseTwoTest
php artisan test --filter=ClamAvProtocolTest
php artisan test --filter=VaultAdapterTest
npx playwright test
npm run build
php artisan view:cache
php vendor/bin/pint
php vendor/bin/pint --test
php artisan migrate:status
docker compose --env-file .env.production --profile ocr config --quiet
```

The initial MySQL run rejected an overlong generated index name. The name was shortened; only verified-empty tables left by that failed new migration were removed before retrying. The existing 26-table Phase 1 schema/data was retained. The corrected migration and its down/up path passed on MySQL. Tests also found and fixed a stale-model verification invalidation bug. Browser tests use separate SQLite and private object directories and do not write synthetic records into the working database.

## Open integration gates and risks

Docker Desktop was present but did not provide a running engine after an attempted background startup. Consequently, live ClamAV signature scanning, OCR containers, Vault service operations, S3/MinIO integration and the production Compose stack could not be exercised here. Document publication remains blocked unless real ClamAV returns clean; local encrypted upload can remain quarantined until the daemon is connected. Real Windows DPAPI and the encrypted SQL recovery drill were exercised. External service tests, production key recovery, encrypted object-store restore and operational hardening remain deployment acceptance gates.

The optional OCR worker and Vault endpoints require operator secrets and network configuration. SMTP remains a configured transport; local development uses log mail. Automatic approval review rejected an attempted invocation of pending notification processing because it could send emails without approval for those messages/recipients. Pending real notification deliveries were left queued; tests used controlled mail transports. The local web server can run without dispatching them.

SQL and encrypted objects must be backed up together with independently retained key-service recovery material. DPAPI files cannot be recovered by changing Windows users or using a new profile; Vault keys must retain recoverable versions. Purge cannot promise erasure from older object-store versions or backups. Email is at-least-once. Employee imports are bounded to 500 rows, exports to 10,000 matching records, PDFs for OCR to 10 pages, and document uploads to 10 MB. Production scale/load and penetration tests remain later gates.

Phase 2 is ready for local feature review with the integration limits above; it is not signed off as a fully deployed production vault. See PHASE_2_WALKTHROUGH.md and PHASE_2_SECURITY_AND_OPERATIONS.md for the concrete review and service setup steps.
