Overview
CAFM System is a multi-tenant, Computer-Aided Facilities Management platform engineered to serve as a single source of truth for every maintainable asset across a large property portfolio. The client operates in a heavily regulated sector where statutory compliance, auditable record-keeping and the “Golden Thread” of building safety information are non-negotiable.
The brief was to replace fragmented, spreadsheet-driven processes with a purpose-built SaaS platform capable of supporting both the client's internal operations and external, isolated customer tenants — all from a single, shared application framework. The guiding principle throughout was “Capture Once, Use Many Times”: information entered against an asset automatically propagates to every connected module — PPM, Tests & Checks, Work Orders, Reactive Repairs, Compliance, Lifecycle Planning and Reporting.
The Challenge
The platform had to:
- Maintain a complete, hierarchical asset register (Portfolio → Property → Building → Floor → Area → System → Asset → Component).
- Drive statutory compliance, PPM scheduling and the Golden Thread directly from a single asset record.
- Provide immutable audit history — nothing is ever physically deleted.
- Minimise mobilisation effort through reusable templates and bulk onboarding.
- Operate as a commercial SaaS product with full data isolation, tenant-specific compliance rules, configurable workflows and per-tenant branding.
- Accommodate future capability (IoT, BIM, predictive maintenance) without structural rework.
The core engineering challenge was to deliver strict tenant isolation and a rich, interconnected domain model without collapsing into a monolith that would be brittle to change and impossible to scale per-domain.
The Solution
The platform was delivered as a domain-oriented microservice architecture — a set of independently deployable Laravel services behind a single ingress, consumed by a modern single-page application, and unified by a shared multi-tenancy package.
All client requests flow through a single Nginx entry point. The ingress extracts the tenant from the request subdomain, injects it as an X-Tenant-Slug header, and routes by path to the appropriate upstream service.
Authentication, identity, RBAC, media storage, cross-service messaging and real-time broadcast.
Property hierarchy and the asset register — sites, buildings, floors, spaces, assets, categories, hazards.
Work orders, PPM plans, reactive repairs, contractors, RAMS and versioned templates.
Cost centres, budgets, revisions, expenses, invoicing and forecasting.
Shared Composer package: tenant resolution, database switching and the immutable audit trail.
Nuxt 4 / Vue 3 single-page front end, serving every branded tenant from one deployment.
Multi-Tenancy
Multi-tenancy is not an afterthought — the platform was built from the ground up around it, delivered as a reusable Composer package consumed by every backend service, guaranteeing identical isolation semantics across the estate. Isolation is defence-in-depth:
- Physical isolation — a separate database per service, per tenant.
- Logical isolation — application-level query scoping via a
BelongsToTenanttrait. - Token binding — JWT claims carry the tenant context and are validated on every request.
- Automatic switching — middleware swaps the database connection per request, transparently to domain code.
- Super-admin override — a controlled cross-tenant access path for platform operations, behind explicit authorisation.
The package also provides tenant provisioning, per-tenant settings, cross-tenant querying for platform-level reporting, and request correlation as calls fan out across services.
The Asset Register & Golden Thread
The asset register in CAFM-Estates is the foundation of the platform, modelling the full estate hierarchy:
- Configurable taxonomy — categories and types let the technical team define new asset types without developer intervention.
- Extensible attributes — a flexible attribute/value pattern extends asset records without schema churn.
- Relationships — parent/child composition (System → Asset → Component) so maintenance rolls up into parent history.
- Hazards & safety — risk data feeding the Golden Thread.
- QR/barcode identification — server-side generated identifiers for physical tagging and on-site validation.
Because every certificate, manual, drawing and service report references the same asset record, uploading a document once makes it available everywhere it is required.
Maintenance, Compliance & Operations
- PPM — recurring, compliance-driven schedules, with multiple schedules supported per asset.
- Work Orders — full lifecycle with status history, timeline events, comments, line items and budget linkage.
- Reactive Repairs — service requests with routing decisions, information requests and time-slot scheduling.
- Templates — versioned work, check and bundle templates with completion and evidence rules, driving bulk onboarding rather than manual recreation.
- Contractors — invitations, quotes, categories and notes, plus in-house teams.
- RAMS — Risk Assessments & Method Statements as first-class, versioned records with risk matrices.
Financials
CAFM-Finance closes the loop between maintenance activity and cost: hierarchical cost centres (with materialised paths for efficient tree queries), budgets with auditable revision history, categorised expenses, PDF invoicing, and forecasting to support capital planning and replacement forecasting — all tied back to the same asset records.
Cross-Service Communication
Services are deliberately decoupled and communicate over well-defined channels:
- REST for CRUD, and GraphQL (Lighthouse) for read-oriented queries by the client and between services.
- RabbitMQ for asynchronous events, with consumers supervised as dedicated Docker services that restart on failure.
- WebSockets via Laravel Reverb for real-time notifications, consumed on the front end with Laravel Echo.
A representative pattern is centralised media handling: satellite services never store files locally. An upload is published to a RabbitMQ queue; CAFM-Core stores it in MinIO and returns a pre-signed URL, which the originating service caches — keeping object storage, access control and the Golden Thread document store authoritative in one place.
Security, Audit & Identity
- Authentication — JWTs are issued by CAFM-Core and verified by every other service. Satellite services hold no local users table; identity, roles and permissions are read entirely from JWT claims.
- Authorisation — role-based access control (Spatie), with two-factor authentication and Laravel Fortify for account security.
- Immutable audit trail — every change (user, timestamp, previous and new value, source) is recorded to a dedicated store. Audit history is never editable and nothing is physically deleted.
Front End
CAFM-Client is a Nuxt 4 / Vue 3 single-page application on a modern, type-safe toolchain: Nuxt UI 4 and Tailwind CSS 4 for an accessible component library, Pinia for state, Axios for REST, Laravel Echo for real-time updates, and Leaflet for spatial / site-plan visualisation. Tenant context is derived from the request host, so a single deployed SPA serves every branded tenant.
Engineering Standards
Engineering rigour was treated as a first-class deliverable:
- PHP 8.4 throughout, on Laravel 12 — the current major framework line.
- Static analysis with PHPStan / Larastan at level 9 and 100% type coverage enforced.
- Automated formatting and refactoring via Laravel Pint and Rector, gated in CI.
- Comprehensive Pest / PHPUnit suites across services, with Playwright and Cucumber for end-to-end and BDD coverage on the front end.
- A consistent developer experience — every service ships with Laravel Sail and reproducible Docker setup.
Technology Stack
| Language / Runtime | PHP 8.4, TypeScript / Node |
| Backend framework | Laravel 12 (Sail, Fortify, Sanctum, Horizon, Reverb) |
| API | REST, GraphQL (Lighthouse) |
| Front end | Nuxt 4, Vue 3, Pinia, Tailwind CSS 4, Nuxt UI, Leaflet |
| Auth | JWT, Spatie Permission (RBAC), Google2FA (MFA) |
| Messaging / Real-time | RabbitMQ, Laravel Reverb, Laravel Echo |
| Data | MySQL 8.4, Redis 7.4 |
| Object storage | MinIO (S3-compatible), Spatie Media Library, Flysystem S3 |
| Documents | DomPDF (invoices / reports), QR generation |
| Multi-tenancy | Bespoke shared Composer package (DB-per-tenant, audit) |
| Infrastructure | Docker Compose, Nginx ingress, Mailpit |
| Quality | PHPStan/Larastan L9, Pest, Pint, Rector, Playwright, Cucumber |
Outcomes
This case study describes work delivered for a client whose identity has been withheld. The platform is referred to throughout as “CAFM System”.