# 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.