# Phase 3 delivery

The user approved Phase 3 after the foundation and employee/compliance phases. Recruitment, hiring, employee lifecycle, performance/growth records and exit clearance are implemented for review. This document records the Phase 3 delivery; Phase 4 was subsequently approved and is documented in PHASE_4_DELIVERY.md.

## Architecture and changed files

| Area | Implementation |
| --- | --- |
| Migration | `2026_10_16_000004_create_recruitment_and_lifecycle.php`: seven InnoDB tables, candidate document reference, account disable timestamp |
| Recruitment | `RecruitmentService`, `RecruitmentController`, `CareerPageController`; manpower requests, capacity reservations, publication/closure, consented applications, ATS history, interviews/evaluations, independently approved offers, acceptance and atomic/idempotent hire conversion |
| Lifecycle | `LifecycleService`, `LifecycleController`; validated typed records for career, probation, letters, policies, performance, training, certifications, development, succession and exits |
| Persistence | `Vacancy`, `Candidate`, `CandidateEvent`, `EmploymentOffer`, `LifecycleRecord`, `LifecycleTask`, `LifecycleDecision`; existing tenant scopes and composite references; append-only approval decisions |
| Career and headcount | Dated employee assignments, salary contract revisions and approved employee-specific department/grade/manager overrides; chronological history, capacity and reporting-cycle checks; completed exits release dated occupancy without deleting history |
| Approvals | Separate requester and decision maker; role and entitlement checks at HTTP boundaries; terminal decisions, actor/reason audit and transactional application/rollback |
| Documents | Candidate documents share existing envelope encryption, quarantine, malware scanning, retention and access logging; recruitment permission required even for users who otherwise manage employee documents; candidates remain linked after hiring |
| Offboarding | Seven required clearance tasks with role-specific completion and evidence; effective-date guard; archived employment; linked-account disable, session removal and denied login/workspace/realtime access |
| Permissions/catalog | `PhaseThreeSeeder`, `ProvisionTenant`, `DatabaseSeeder`, artisan `zentrik:phase3`; People Lifecycle plan, recruitment/career availability and role permissions; other plans/custom roles retained |
| UI | Recruitment, candidate, public career, lifecycle request/detail/clearance, growth forms and employee history views; navigation, responsive styles, printable letters and approval forms |
| Existing integrations | Employee profile forms and controller prevent direct status, subsequent salary and position changes from bypassing lifecycle approval; document listing/search exclude restricted candidate records; event registry extended |
| Verification | `PhaseThreeTest`, browser `phase3.spec.js`, isolated fixture extensions; previous foundation, document-security and compliance tests retained |

Recruitment and career are the module boundaries. Performance/growth is included in the career module with separate view/manage permissions. Typed lifecycle payloads are validated by kind and stored as immutable request content through the available endpoints; approvals, tasks and acknowledgements are separate state. `Employee::careerAt(date)` projects approved employee-specific career overrides at a date. Position-wide organization versions remain independent.

## Commands

From the project directory:

```powershell
php artisan migrate --force
php artisan zentrik:phase3 zentrik
npm.cmd run build
php artisan view:cache
php artisan test --compact
php vendor/bin/pint --test
npx.cmd playwright test
```

Use a disposable database for MySQL tests by setting `DB_CONNECTION=mysql`, `DB_DATABASE=zentrikhrms_codex_test`, `DB_USERNAME=root` and the appropriate test password in that process. Never point RefreshDatabase tests at the working database. Browser setup refuses any database other than its isolated SQLite fixture. Fixed browser credentials, recovery codes and synthetic people are confined to that fixture.

## Operational boundaries

- Existing local database/account settings remain `zentrikhrms`, root and an empty password. Existing connection defaults and explicit new-table engines enforce InnoDB.
- An encrypted pre-upgrade SQL snapshot was created outside deliverables in the local scratch directory. Real Windows DPAPI encryption/decryption and content hash comparison succeeded; no plaintext dump was retained. Recover it with the same Windows identity/key material and matching release. The snapshot does not replace independent offsite backups.
- No synthetic vacancy, applicant or employee is installed in the working database. No real notification delivery is invoked by the Phase 3 installation.
- Candidate uploads require an authenticated recruitment user. Public file-upload portals and invitation links are not part of this phase. Live ClamAV, production Vault/S3 and optional OCR still require the service deployment gates documented in Phase 2. Unavailable scanning keeps files quarantined.
- Letters are approved plain-text records with browser print/PDF support; a designer for branded templates remains later work. Competencies use a narrative assessment within each review. Workflow decisions use one independent approval step; the visual workflow designer remains Phase 5.
- Department, grade and manager career changes are employee-specific dated overrides; they do not rewrite the shared position. Approval must follow increasing career effective dates. Correct an approved change with a new dated request, preserving history.
- Asset/vehicle clearances record human evidence until Phase 5 connects the custody registers. Finance handoff does not calculate or pay final settlement. Notice days are supplied by the business; no statutory/legal compliance engine is claimed.
- Exit finalization is an explicit HR action on or after the effective date. No new unattended worker silently archives future departures. Account disable is local to Zentrik; revocation in external systems remains the IT clearance owner's responsibility.
- Scaling/load testing, hardened deployment, external penetration testing and jurisdiction adapters remain later phase gates. Do not roll back this migration on a populated installation: it drops Phase 3 records and account-disable state. Restore a verified backup with the matching release after reviewing data and queue state.

## Verification

| Check | Result |
| --- | --- |
| Final full SQLite regression | 97 passed, 372 assertions; one MySQL-specific engine test skipped |
| Full MySQL regression | 98 passed, 416 assertions |
| Final affected MySQL regression after compliance visibility guard | 57 passed, 229 assertions; all Phase 2 and Phase 3 tests |
| Chrome browser suite | 4 passed: foundation/MFA, mobile login, employee/document/compliance workflow, public application through independent approvals, hiring and KPI review submission |
| Final browser screenshot/workflow verification | Phase 3 scenario passed again; dynamic KPI fields, real submission, closed mobile navigation and no horizontal overflow verified |
| Frontend build | Vite production build passed |
| Blade and PHP formatting | View compilation and Laravel Pint passed |
| Disposable MySQL migration drill | Phase 3 down/up passed; working database was not rolled back |
| Working schema | Seven migrations applied; 45/45 base tables InnoDB |
| Application connection | zentrikhrms; default_storage_engine InnoDB |
| Working tenant | People Lifecycle plan; organization, workflows, employees, documents, compliance, recruitment and career enabled |
| Preserved data | Two existing user accounts; no synthetic employees/candidates installed |
| Running endpoints | /login, /careers/zentrik and /up returned HTTP 200 |
| Pre-upgrade backup | Encrypted SQL snapshot; real DPAPI roundtrip and content-hash comparison passed |

The full regression preceded the last candidate-compliance visibility restriction; the final affected MySQL run verified that restriction and all employee/document/lifecycle behavior. Earlier foundation, cryptography, MFA and engine checks remained passing. Tests use separate MySQL/SQLite databases, mail fakes and controlled scanner/key-service adapters where appropriate. Real Windows DPAPI tests are retained; test-only clean scanner behavior is not selectable by application configuration.

The acceptance suite covers approval separation, vacancy capacity/reservations/closure, publication and company-local closing dates, consent and duplicates, interviews/evaluations, accepted-offer conversion and idempotency, candidate ciphertext and read/renewal/search/compliance permissions, tenant references, chronological salary/currency history, transfer rollback, manager cycles, weighted KPIs, training/development/succession/probation, scanned certification evidence, policy acknowledgement, clearance permissions, future-exit guard, account revocation and preserved historical occupancy.

Candidate documents use a seeded minimum retention of 365 days and per-record legal holds; they are managed from recruitment and excluded from general compliance reminders/type-management screens. This keeps PRO/compliance access separate from candidate-file access.

[Desktop growth form](screenshots/performance-desktop.png) · [Mobile growth form](screenshots/performance-mobile.png) · [Public career page](screenshots/careers-desktop.png). Screenshots contain isolated test-fixture data.
