# FieldOps Cloud Current System Dossier

## 1. Repository Classification

FieldOps Cloud is a Yii3-style PHP/XAMPP application, not a full Yii application scaffold.

The active runtime is a custom lightweight HTTP stack:

- `public/index.php` registers services, repositories, controllers, and routes.
- `src/Application/App.php` routes requests by exact `METHOD /path`.
- `src/Infrastructure/Http/Request.php` normalises XAMPP base paths.
- `src/Infrastructure/Http/Response.php` emits status, headers, and body.
- `src/Infrastructure/View/PhpRenderer.php` renders templates.

Required architecture from project instructions:

- Controller: HTTP handling and request/response flow.
- Service: validation and business rules.
- Repository: persistence and tenant/user data access.
- Database: MySQL schema and seed data under `database/`.
- Template: Bootstrap 5 presentation only.

## 2. Product Scope

FieldOps Cloud targets trades and service companies. The platform has two primary operating surfaces:

1. Tenant/company users:
   - Dashboard
   - Jobs
   - Recurring jobs
   - Dispatch
   - Schedule
   - Quotes
   - Invoices
   - Clients
   - AI Assistant
   - Import/Export
   - Team
   - Reports
   - Accounting, calendar, and LLM settings
   - Workspace and subscription
   - Mobile/offline technician mode

2. Platform admin:
   - Platform admin dashboard
   - Tenants
   - Tenant detail
   - Platform billing and manual overrides
   - Global pricing
   - Audit logs
   - Demo management
   - Import/export visibility
   - System health
   - Support access / login as tenant
   - Security admin
   - Mobile/offline status
   - Platform accounting connection

## 3. Request Lifecycle

1. Apache serves `public/`.
2. Request enters `public/index.php`.
3. Environment and demo mode are established.
4. Dependencies are instantiated manually.
5. Routes are registered as an array of exact keys such as `GET /jobs`.
6. `App::handle()` computes request method and path.
7. Missing route returns 404.
8. Non-API POST requests require `_csrf`.
9. Controllers enforce RBAC with `SessionAuth::requirePermission()`.
10. Controllers call services and repositories.
11. Responses render templates or JSON.
12. `ForbiddenException` becomes a 403 page.

Testing implication: every route needs status, CSRF, RBAC, template rendering, and XAMPP base-path coverage.

## 4. Active Route Table

The active route table is in `public/index.php`.

Current route inventory from `docs/QA_ROUTE_ACTION_INVENTORY.md`:

- Routes: 98
- Links: 201
- Form/action targets: 46
- Buttons: 58
- Findings: 0

Important route groups:

- Public: `/`, `/pricing`, `/privacy`, `/terms`, `/support`, `/account/delete-request`
- Auth/demo: `/auth`, `/login`, `/signup`, `/logout`, `/demo`, `/demo/company-admin`, `/demo/platform-admin`, `/demo/role`
- Tenant operations: `/dashboard`, `/jobs`, `/schedule`, `/quotes`, `/invoices`, `/clients`, `/team`, `/reports`
- Operations detail/edit/create: `/jobs/view`, `/jobs/edit`, `/quotes/view`, `/quotes/edit`, `/invoices/view`, `/invoices/edit`, `/clients/view`, `/clients/edit`, `/team/view`, `/team/edit`
- Workflow posts: `/jobs`, `/jobs/update`, `/quotes`, `/quotes/update`, `/quotes/convert-to-invoice`, `/invoices`, `/invoices/update`, `/invoices/payment`, `/clients`, `/clients/update`, `/team`, `/team/update`
- Dispatch and recurring: `/dispatch`, `/dispatch/crews`, `/dispatch/assign`, `/recurring-jobs`, `/recurring-jobs/generate`, `/recurring-jobs/status`
- Schedule: `/schedule`, `/schedule/appointments`
- AI: `/ai-assistant`, `/ai-assistant/generate`
- Import/export: `/import-data`, `/import-data/sample`, `/import-data/preview`, `/import-data/commit`, `/import-data/undo`, `/export-data`, `/export-data/download`
- Integrations: `/settings/accounting`, `/settings/calendar`, `/settings/llm`
- SaaS: `/workspace`, `/subscription`, `/settings/pricing`
- Platform admin: `/platform-admin`, `/platform-admin/tenants`, `/platform-admin/tenants/view`, `/platform-admin/tenants/action`, `/platform-admin/tenants/login`, `/platform-admin/tenants/return`, `/platform-admin/billing/override`, `/platform-admin/accounting/connect`, `/platform-admin/demo/reset`, `/platform-admin/health`, `/platform-admin/security`, `/platform-admin/mobile-offline`
- API-like current routes: `/api/portal/quote`, `/api/offline-sync`

## 5. Current Roles

Roles are static in `src/Infrastructure/Security/RbacService.php`:

- `owner`
- `manager`
- `supervisor`
- `team_member`
- `trainee`
- `demo_user`
- `platform_admin`

High-level role behavior:

- Owner and manager can manage most tenant operations, billing, imports, exports, integrations, and team.
- Supervisor can create/update jobs, create clients, create quotes, use dispatch, view invoices, use AI, export, and view reports, but cannot manage billing/tenant/platform.
- Team member has limited operational visibility and can update assigned jobs.
- Trainee is highly restricted: dashboard, clients, jobs.
- Demo user is read-oriented for demo/showcase and cannot access platform admin.
- Platform admin can access platform admin, global pricing, platform billing, support access, integrations settings, and LLM settings, but is intentionally denied normal tenant operational pages unless using support impersonation.

## 6. Demo Mode and Production Boundaries

Demo mode is important and must be tested carefully.

Current behavior:

- Local/dev/test environments enable demo behavior by default.
- `DEMO_ENABLED=0` or production environment disables demo auto-login behavior.
- Platform admin demo access is explicit via `/demo/platform-admin` or `/demo/role?role=platform_admin`.
- The previous silent promotion of demo users to platform admin was fixed and covered by tests.

Testing implication:

- Test local demo.
- Test production-like config with demo disabled.
- Verify unauthenticated users cannot access tenant or platform pages in production-like mode.
- Verify platform admin demo entry is unavailable when demo mode is disabled.

## 7. Current Persistence Model

The product currently uses a hybrid persistence model:

- Database repositories exist for core entities.
- Demo/session repositories are used heavily in local/demo workflows.
- Some production database schema exists but not every feature is fully wired to database-backed production behavior.

Important database artifacts:

- `database/schema.sql`
- `database/seed.sql`
- `migrations/m250613_000001_initial_schema.sql`
- `migrations/20260615_000001_add_user_profile_fields.sql`
- `migrations/20260615_000002_add_invoice_payment_fields.sql`
- `migrations/20260615_000003_add_maintenance_agreements.sql`
- `migrations/20260615_000004_add_crews_and_job_crew_assignment.sql`

Testing implication:

- Distinguish demo/session persistence tests from database repository tests.
- Run tenant isolation tests against actual repositories.
- Do not assume every schema table is actively used by controllers.

## 8. Current QA Evidence

Current evidence from the workspace:

- PHP service and integration regression tests are centralised in `tests/run.php`.
- Static route/action inventory is generated by `tools/qa-inventory.php`.
- PHP lint is run by `tools/lint-php.php`.
- Browser route smoke is in `tools/browser-smoke.cjs`.
- Role/RBAC/browser walkthrough is in `tools/role-walkthrough.cjs`.

The latest known checks passed in both workspace and XAMPP served copy.

## 9. Key Current Limitations

Important limitations Claude must not miss:

- Full public REST API is not implemented. Only current `/api/portal/quote` and `/api/offline-sync` are active API-style routes.
- Accounting integrations are sandbox/foundation settings, not live OAuth sync.
- Calendar integrations are settings/strategy foundation, not live Google or Outlook OAuth sync.
- LLM provider settings validate provider metadata, but API keys are not stored and live model calls are not performed.
- AI Assistant is currently a deterministic local assistant and does not call external LLMs.
- Payment provider integration is not wired.
- Production deployment, HTTPS, secrets management, background workers, queue infrastructure, and observability need owner confirmation before public launch.
- Mobile native wrappers are configured/foundation-ready, but app-store submission readiness is not approved.

