# TenantPilot Stack Overview and Enterprise Assessment

Status: 2026-05-15
Scope: `apps/platform` Laravel/Filament application in `wt-plattform`
Project phase assumption: pre-production / MVP-to-scale-up, high criticality because Intune configuration, restore, audit, and tenant isolation are in scope.

## Executive Summary

TenantPilot already has a stronger-than-average governance foundation: Spec Kit is active, workspace and tenant isolation are explicit constitutional rules, Graph calls are centralized through `GraphClientInterface`, queued operations are observable via `OperationRun`, and many Filament actions use `UiEnforcement`, confirmation, audit logging, and capability checks.

The main enterprise gaps are not conceptual; they are operational hardening gaps:

1. P0: `composer audit` and `pnpm audit` currently report high/medium advisories affecting Filament Tables, phpseclib, PHPUnit, axios, devalue, esbuild, postcss, and related packages.
2. P1: Several critical historical JSON payload columns still use PostgreSQL `json` where the project data strategy requires `jsonb` for queryable snapshots and backup/restore payloads.
3. P1: Multiple Filament resources/pages exceed 1,000-5,700 lines, increasing change risk around admin workflows.
4. P1: Policy coverage is inconsistent: many resources use resource-level `can*()` plus gates, but not every resource-backed model has a dedicated policy.
5. P1: The local/Docker queue command uses `queue:listen`; production should use supervised `queue:work` or Laravel 12 `reload` semantics.
6. P2: Admin panel registration mixes explicit resources with discovery. This can be valid, but needs a documented rule to avoid accidental double mental models.
7. P2: Production configuration rules need to be encoded as deployment gates: `APP_DEBUG=false`, encrypted/secure sessions where needed, health checks, audit-safe logging, queue restart/reload, and backup restore testing.

## Stack and Version Analysis

| Bereich | Erkannte Version | Quelle/Datei | Status | Risiko | Empfehlung |
|---|---:|---|---|---|---|
| PHP runtime | 8.4.15 | Laravel Boost `application_info` | supported | low | Keep 8.4; track active support until 2026-12-31 and security support until 2028-12-31. |
| PHP constraint | `^8.2` | `apps/platform/composer.json` | broad | low | Keep if needed, but CI should test the actual runtime 8.4. |
| Laravel | 12.52.0 | Boost / `composer.lock` | current LTS-family app version | medium | Stay on 12.x for now; treat Laravel 13 as a planned major upgrade, not incidental. |
| Filament | 5.2.1 | Boost / `composer.lock` | vulnerable range | high | Upgrade to at least 5.3.5; preferably current 5.x after regression tests. |
| Livewire | 4.1.4 | Boost / `composer.lock` | compliant | low | Filament v5 + Livewire v4 compliance is satisfied. |
| Tailwind CSS | 4.2.2 | Boost / `pnpm-lock.yaml` | current minor behind | low | Tailwind v4 Vite integration is correct; update during frontend dependency patch window. |
| Alpine.js | unclear direct version | bundled transitively by Filament assets | unclear | low | Do not pin separately unless a project asset needs it. |
| PostgreSQL | 16 | `docker-compose.yml` | aligned | low | Use PostgreSQL-specific CI for JSONB, partial index, FK, and isolation assertions. |
| Redis | 7-alpine | `docker-compose.yml` | available | medium | Use for cache/queue when scale requires it; database queue is acceptable for MVP but not the long-term default. |
| Queue | database | `.env.example`, `config/queue.php` | MVP-grade | medium | Production should use supervised `queue:work`; split high/low/default queues for Graph/restore workloads. |
| Cache | database | `.env.example`, `config/cache.php` | MVP-grade | medium | Use Redis for production if queue restart signals, locks, and scheduler overlap become load-sensitive. |
| Session | database, encrypted false | `.env.example` | local default | medium | Production must set secure cookie/domain/same-site policy and consider `SESSION_ENCRYPT=true`. |
| Mail | log | `.env.example` | local default | low | Production needs SMTP/SES/Postmark decision and alert delivery tests. |
| Storage | local | `.env.example` | local default | medium | Production backup/report artifacts should use private object storage and tested restore paths. |
| Auth | Socialite + Microsoft Azure provider | `composer.json`, providers | aligned | medium | Review SocialiteProviders Microsoft-Azure 4.x to 5.x upgrade separately. |
| Testing | Pest 4.3.1, PHPUnit 12.5.4 | Boost / `composer.lock` | strong but vulnerable dev dep | high | Upgrade PHPUnit to a patched 12.5.x and keep Pest 4 lanes. |
| Frontend build | pnpm 10.33, Vite 7.3.2 | root/app package files | aligned | medium | Patch axios/postcss/esbuild/devalue advisories before production. |

## Enterprise Maturity Score

| Bereich | Score | Begründung | Zielzustand |
|---|---:|---|---|
| Architektur | 3.0 | Strong service/job/support layers, but some Filament surfaces are very large. | Thin UI classes, explicit services/actions for business workflows, no speculative frameworking. |
| Filament | 3.0 | Correct v5/Livewire 4 basis, panel providers in `bootstrap/providers.php`, central RBAC helper. | Standardized resource patterns, policy per resource, extracted schema/table/action builders where size justifies it. |
| Security | 3.0 | Tenant isolation, encrypted credential payloads, audit logs are strong. Supply-chain and policy coverage need work. | Audit gates in CI, patched dependencies, policy/resource coverage matrix, production security config gate. |
| Testing | 4.0 | Rich Pest/Filament/browser/governance lanes exist. | PostgreSQL lane required for schema/isolation changes; dependency audit gates mandatory. |
| Performance | 3.0 | Eager loading and queues exist; JSONB strategy is partially implemented. | Query budgets, JSONB indexes for queried payloads, worker separation, dashboard metrics. |
| DevOps | 3.0 | Sail-first local and Gitea CI exist. | Dokploy runbook, health checks, supervised workers, staging gate, rollback drills. |
| Observability | 3.0 | `OperationRun` and `AuditLog` create useful internal observability. | External error tracking/APM, queue/scheduler alerts, SLO dashboards. |
| Compliance | 2.5 | Audit/isolation foundations exist; GDPR/retention docs are incomplete. | Data inventory, retention matrix, DPA/vendor review, backup encryption proof. |
| Maintainability | 3.0 | Spec Kit and constitution reduce drift; large UI files raise regression risk. | Enforced file-size/refactor triggers and feature-local extraction patterns. |

## Findings Register

| ID | Kategorie | Finding | Evidenz | Risiko | Priorität | Aufwand | Empfehlung | Akzeptanzkriterium |
|---|---|---|---|---|---|---|---|---|
| F-001 | Supply Chain | Composer audit reports 8 advisories affecting 5 packages, including high severity Filament Tables XSS and phpseclib/PHPUnit advisories. | `composer audit --format=plain`; `filament/filament` 5.2.1, `phpunit/phpunit` 12.5.4 | XSS, crypto/DoS, unsafe dev tooling | P0 | M | Upgrade Filament to >=5.3.5, patch transitive packages, rerun full Filament/Pest lanes. | `composer audit` returns no high/medium advisories accepted by default policy. |
| F-002 | Supply Chain | pnpm audit reports high/moderate advisories for axios, devalue, esbuild, postcss and workspace packages. | `corepack pnpm audit --audit-level moderate --json` | SSRF, header injection, XSS, DoS | P0 | M | Update axios >=1.16.1, postcss >=8.5.10, devalue >=5.8.1, esbuild chain via dependency upgrade. | `pnpm audit --audit-level moderate` is clean or has approved exceptions. |
| F-003 | Datenbank | Core snapshot/backup/restore payload columns still use `json`, not `jsonb`. | `policy_versions.snapshot`, `backup_items.payload`, `restore_runs.preview/results/requested_items`, `audit_logs.metadata` migrations | Slow query paths, weaker indexing, inconsistency with product rule | P1 | M | Convert queryable payloads to JSONB with reversible migrations where feasible; add GIN/expression indexes only for proven queries. | Schema uses JSONB for policy snapshots, backup payloads, restore previews/results, and audit metadata query paths. |
| F-004 | Filament | Large workflow classes create high change risk. | `ManagedEnvironmentOnboardingWizard.php` 5748 LOC, `ManagedEnvironmentResource.php` 3785 LOC, `RestoreRunResource.php` 2779 LOC, `FindingResource.php` 2503 LOC | Regression risk, difficult review, slow onboarding | P1 | L | Extract schema/table/action factories and service actions at natural workflow boundaries; keep extra layers narrow. | Largest admin workflows have test-covered extracted builders/services and no single file exceeds agreed threshold without exception. |
| F-005 | Security | Resource/model policy coverage is inconsistent. | Policies exist for many models, but resources like `Policy`, `PolicyVersion`, `BackupSet`, `RestoreRun`, `ManagedEnvironment`, `BaselineProfile`, `InventoryItem`, `StoredReport` lack obvious dedicated policies. | Authorization drift between UI and server | P1 | M | Add policy classes or documented exceptions; make Filament resources call policies for CRUD and domain actions. | Resource-policy matrix is complete and tested. |
| F-006 | DevOps | Queue container uses `php artisan queue:listen`. | `docker-compose.yml:65` | Inefficient workers, production reload ambiguity | P1 | S | Production/Dokploy should run `php artisan queue:work --sleep=3 --tries=3 --timeout=300` under process supervision and reload/restart on deploy. | Deployment checklist has worker command, process monitor, restart/reload, queue metrics. |
| F-007 | Filament | Admin panel registers explicit resources and also discovers resources. | `AdminPanelProvider.php:198`, `:211` | Accidental resource exposure or inconsistent registration ownership | P2 | S | Choose explicit allowlist for enterprise panels or document discovery boundaries. | Panel registration rule is documented and covered by navigation/surface tests. |
| F-008 | Graph/Integration | Default Graph version is `beta`. | `apps/platform/config/graph.php:12` | API drift and production contract instability | P2 | M | Keep beta only where endpoint requires it; document endpoint version in `config/graph_contracts.php` and specs. | Each Graph contract records v1.0/beta, permission, retry behavior, and production risk. |
| F-009 | Testing/CI | PostgreSQL test lane exists but should be mandatory for schema/isolation changes. | `composer.json` has `test:pgsql`; default PHPUnit uses SQLite in memory. | SQLite misses JSONB, partial index, FK, and lock behavior | P2 | M | Add CI rule: migrations, tenant isolation, JSONB, operation locks require `sail:test:pgsql` or CI PostgreSQL lane. | PR checks show PostgreSQL lane on relevant path changes. |
| F-010 | Compliance | GDPR retention and backup security are not yet consolidated in one operational matrix. | Product docs exist; no single retention/backup/privacy matrix found in requested scope. | Incomplete audit readiness | P2 | M | Create retention matrix for audit logs, backups, reports, credentials, run payloads; include deletion/export procedure. | Retention matrix exists and is referenced from deployment/security docs. |

## Recommended Next 10 Actions

1. Patch Composer and pnpm advisories, starting with Filament >=5.3.5 and axios/postcss/devalue.
2. Add `composer audit` and `pnpm audit --audit-level moderate` to the confidence or release lane.
3. Create a resource-policy matrix and add missing policy classes or documented exceptions.
4. Convert core queryable JSON payloads to JSONB with targeted indexes.
5. Replace production queue guidance from `queue:listen` to supervised `queue:work` plus Laravel 12 `reload`/`queue:restart`.
6. Extract repeated Filament action closures from `BackupScheduleResource`, `RestoreRunResource`, and `ManagedEnvironmentResource` into focused action/service classes.
7. Require PostgreSQL CI for migrations, tenant isolation, operation locks, and JSONB behavior.
8. Document Graph endpoint version and permission truth in `config/graph_contracts.php` for every new integration.
9. Add production security config checklist: debug false, secure cookies, private storage, no secret logging, encrypted credentials.
10. Create retention/backup restore drill checklist before staging promotion.

## Best-Practice Target State

- Architecture: Laravel monolith with clear UI/application/domain/infrastructure boundaries; no speculative platform framework.
- Filament: v5-native resources/pages/widgets/actions with thin UI orchestration, policies, `UiEnforcement`, empty states, table standards, and tested actions.
- Backend: services/actions/jobs own business behavior; controllers and resources stay thin; remote work is queued and idempotent.
- Database: PostgreSQL integrity first: workspace/tenant constraints, partial unique indexes for active operations, JSONB for retained/queryable payloads.
- Security: OWASP ASVS-informed controls, deny-as-not-found isolation, least privilege, encrypted credentials, clean dependency audits.
- Testing: Pest 4 lanes protect business truth, Filament actions, policy semantics, PostgreSQL constraints, and browser-critical workflows.
- Deployment: Dokploy runbook with staging gate, health checks, migrations, asset build, supervised workers, rollback, backup restore proof.
- Observability: audit logs, operation runs, queue/scheduler metrics, Graph throttle metrics, error tracking, and production dashboards.
- Documentation: compact project rules in `docs/*-guidelines.md`, current AGENTS rules, and spec-linked decisions.
- AI coding: agents must follow `docs/ai-coding-rules.md`, Spec Kit, and version-specific official docs.

## Anti-Pattern Catalog

| Anti-Pattern | Warum problematisch | Besseres Pattern | Priorität |
|---|---|---|---|
| Fat Filament Resources/Pages | Hard to review, test, and safely change | Extract focused schema/table/action builders and domain actions | P1 |
| Business logic in closures | Authorization/audit/transaction behavior drifts | Service/action class called from UI action | P1 |
| Missing policies | UI checks become the only guard | Policy per resource-backed model or documented exception | P1 |
| N+1 table/global-search queries | Slow admin surfaces | Eager loading, `withCount`, aggregate subqueries | P2 |
| Unsafe uploads | RCE/path tampering/data leakage risk | Private disk, random filenames, MIME/size validation, tamper prevention | P2 |
| Missing transactions | Partial writes in critical workflows | Transaction around intent/run/audit state changes | P1 |
| JSON where JSONB is queried | Weak indexing and repeated parsing | JSONB plus targeted GIN/expression indexes | P1 |
| Fragile broad tests | Slow suite, unclear signal | Lane-scoped tests that prove business truth | P2 |
| Plugin/package drift | Security and maintenance risk | Package governance and audit gates | P0 |
| Admin actions without audit | No accountability for critical changes | Audit event for every sensitive mutation | P1 |
| Unclear roles/rights | Tenant data exposure risk | Capability matrix, policies, deny-as-not-found | P1 |
| No queue retry strategy | Duplicate/failed operations | Idempotent jobs, locks, run identity, backoff | P1 |

## Roadmap

### Phase 1: Stabilisieren

Goal: remove immediate production blockers.

Tasks:

- Patch Composer and pnpm advisories.
- Add audit gates to CI/release.
- Replace production queue guidance with supervised `queue:work`.
- Add production env/security checklist enforcement.
- Add or confirm tests for destructive restore/backup/provider actions.

Effort: M.
Risk: dependency upgrades can reveal Filament regressions.
Acceptance: audits clean, critical tests pass, staging deploy runbook works.

### Phase 2: Standardisieren

Goal: reduce admin workflow change risk.

Tasks:

- Build resource-policy matrix.
- Extract repeated action closure logic from largest resources.
- Standardize explicit vs discovered Filament resource registration.
- Document Graph contract version and permission rules per endpoint.
- Require PostgreSQL lane for schema/isolation changes.

Effort: L.
Risk: refactors can conflict with active feature work.
Acceptance: resource-policy matrix complete, top three largest surfaces have bounded extraction plan/tests.

### Phase 3: Skalieren

Goal: prepare for higher tenant/data volume.

Tasks:

- Convert queryable JSON payloads to JSONB.
- Add targeted indexes for policy/backup/restore/audit query paths.
- Split queues and consider Redis for production.
- Add dashboard/queue/scheduler/Graph metrics.
- Cache stable aggregates where invalidation is clear.

Effort: L.
Risk: migrations need staging timing proof.
Acceptance: query plans and queue metrics are documented; staging migration time is acceptable.

### Phase 4: Enterprise Readiness

Goal: compliance and operating model.

Tasks:

- Data inventory and retention matrix.
- Backup restore drill and incident response runbook.
- External error tracking/APM integration.
- Vendor/DPA/security review for mail/storage/hosting providers.
- Scheduled package/security review cadence.

Effort: XL.
Risk: organizational dependencies outside code.
Acceptance: production readiness checklist is signed off and rehearseable.

## Open Questions

- Which production mail provider will be used: SMTP, SES, Mailgun, Postmark, or another service?
- Which production storage backend will hold backup/report artifacts: local volume, S3, R2, Spaces, or another private object store?
- Should production queue/cache move to Redis before first customer data, or after volume signals?
- What are the required retention periods for audit logs, backups, restore results, operation runs, reports, and support access logs?
- Is Microsoft Graph `beta` acceptable for each production endpoint, or must some flows be v1.0-only?
- What compliance bar is expected: internal GDPR readiness, enterprise customer security review, regulated procurement, or formal certification?

## Sources

- Official Laravel 12 docs: [deployment](https://laravel.com/docs/12.x/deployment), [authorization](https://laravel.com/docs/12.x/authorization), [queues](https://laravel.com/docs/12.x/queues), [validation](https://laravel.com/docs/12.x/validation).
- Official Filament 5 docs: [global search](https://filamentphp.com/docs/5.x/resources/global-search), [actions](https://filamentphp.com/docs/5.x/actions/overview), [security](https://filamentphp.com/docs/5.x/advanced/security), [testing actions](https://filamentphp.com/docs/5.x/testing/testing-actions).
- Official Pest 4 docs: [browser testing release notes](https://pestphp.com/docs/pest-v4-is-here-now-with-browser-testing).
- Official PostgreSQL 16 docs: [JSON/JSONB and GIN indexing](https://www.postgresql.org/docs/16/datatype-json.html).
- OWASP: [ASVS](https://owasp.org/www-project-application-security-verification-standard/).
- NIST: [SP 800-218 SSDF](https://csrc.nist.gov/pubs/sp/800/218/final).
- Microsoft Learn: [Graph throttling guidance](https://learn.microsoft.com/en-us/graph/throttling).
- PHP: [supported versions](https://www.php.net/supported-versions.php).

## Assumptions and Uncertainties

- Production is assumed to be Dokploy on VPS with container-based deployment, as stated in `AGENTS.md`.
- Exact production mail/storage/cache providers are not set in `.env.example`; recommendations are provider-neutral.
- Alpine.js exact version is not declared directly; it is treated as Filament-managed unless the project adds custom Alpine assets.
- The current branch has unrelated modified app/test files; this assessment did not alter them.
