# Corporate Phase 5.5 Route & Security Audit

## Scope

Reviewed Corporate module routes after Phases 1-5:

- `/corporate`
- `/b2b`
- `/admin/b2b/leads`
- `/admin/corporate-proposals`
- `/admin/corporate-agreements`
- `/admin/corporate-cohorts`
- `/admin/corporate-reports`
- `/org/programs`
- `/org/reports`

Commands used:

- `php artisan route:list --path=corporate -v`
- `php artisan route:list --path=b2b`
- `php artisan route:list --path=org`

## Route Security Matrix

| Area | Status | Evidence | Notes |
| --- | --- | --- | --- |
| `/corporate` | PASS | Public redirect to `public.b2b` | Public marketing alias only. |
| `/b2b` | PASS | Public Livewire landing page | Lead submission protections are handled in the component/service layer. |
| `/admin/b2b/leads` | PASS | `auth` + `can:b2b.leads.view` / `can:view,lead` | Uses `B2bLeadPolicy`. |
| `/admin/corporate-proposals` | PASS | `auth` + proposal permissions/policies | Private PDF download requires `downloadPdf`. |
| `/admin/corporate-agreements` | PASS | `auth` + agreement permissions/policies | Generated/signed file download requires `downloadFiles`. |
| `/admin/corporate-cohorts` | PASS | `auth` + `corporate_cohorts.*` / `viewCorporate` | Uses `SessionPolicy` for corporate cohort scoping. |
| `/admin/corporate-reports` | PASS | `auth` + `corporate_reports.*` / `CorporateReportPolicy` | Download requires `download`. |
| `/org/programs` | PASS | `auth` + `org_portal` + `tenancy` | Queries are organization-scoped. |
| `/org/reports` | PASS | `auth` + `org_portal` + `tenancy` | Lists only selected organization reports. |
| `/org/reports/{report}/download` | PASS | `auth` + `org_portal` + `tenancy` + `can:download,report` | Rejects report downloads for other organizations. |

## Company Model / Legacy Conflict

No Corporate Phase 1-5 route requires `App\Models\Company`. The canonical tenant model remains `Organization`.

Legacy `companies`, `users.company_id`, and `agreement_path` remain outside the new Corporate workflow and must not be used in Phase 6.

## Private File Access

Corporate files are stored on the private disk:

- Proposal PDFs: `corporate/proposals/*`
- Agreement generated PDFs: `corporate/agreements/*`
- Agreement signed PDFs: `corporate/agreements/signed/*`
- Trainee import files: private import storage from Phase 4
- Report PDFs: `corporate/reports/*`

Downloads are routed through controllers with policies:

- `CorporateProposalPdfController`
- `CorporateAgreementFileController`
- `CorporateReportDownloadController`

Regression tests confirm support users cannot download agreement/report files without the explicit download permissions, and report PDFs are not written to the public disk.

## Findings

### Finding 1: Finance details should require explicit finance permission

Status: Fixed.

Risk: Medium.

Observation: Phase 5 originally allowed any admin-style user to view financial report values. Phase 5.5 tightened this so `corporate_finance.view` is required unless the user is `super_admin`.

Exact fix:

- `app/Policies/CorporateReportPolicy.php`
- `viewFinancial()` now checks `hasPermissionTo('corporate_finance.view')`.

## Test Coverage Added / Confirmed

Added:

- `tests/Feature/Corporate/CorporateModuleRegressionTest.php`

Covered:

- Lead to organization to proposal to agreement to cohort to trainee to attendance to private final report.
- Org member cannot download another organization's report.
- Support cannot download private agreement/report files without permission.
- Admin without `corporate_finance.view` sees reports without financial values.
- Report PDFs are not written to the public disk.
- Corporate report/admin/org report pages do not render raw `corporate.*` or `org.*` translation keys.

Existing coverage confirmed:

- Org member cannot see another organization's corporate cohort.
- Teacher cannot access unassigned corporate cohorts.
- Proposal and agreement private file downloads are permission-protected.

## Phase 6 Readiness

Safe to proceed to Phase 6 Invoicing after this checkpoint, with one constraint:

Phase 6 must reuse `Organization`, `CorporateAgreement`, `Session` corporate cohort links, and private file delivery patterns. It must not use `companies`, `users.company_id`, or public files.
