TenantAtlas/docs/stack-overview.md
ahmido bf43dad3d1 fix: enforce workspace surface scope for customer review workspace (#366)
## Summary
- keep `/admin/reviews/workspace` workspace-scoped in shell and sidebar context
- treat `tenant` query hints on the customer review workspace as page-level filters only
- update the customer review workspace tests and Spec 311 navigation contract to match the workspace-hub IA

## Testing
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php tests/Feature/Filament/PanelNavigationSegregationTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `git diff --check`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #366
2026-05-15 20:52:37 +00:00

19 KiB

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

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.