A Multi-Tenant Facilities Management Platform
A multi-tenant SaaS platform delivering a single source of truth for every maintainable asset - driving statutory compliance, planned preventive maintenance, work orders and the Golden Thread from one record, across isolated customer tenants.
Overview
Built as a greenfield project, this platform replaced manual processes and disconnected spreadsheets with a unified system spanning estate management, hierarchical asset registers, planned and reactive maintenance, contractor management and financial tracking. The architecture was designed for scale from day one - domain-driven design, service boundaries aligned to business capabilities, and asynchronous messaging to keep services fully decoupled. As principal developer, architect and domain specialist, I led the technical design, implementation and delivery of the entire platform.
The Challenge
The client needed a platform that could serve as a single, authoritative record for every maintainable asset across their property portfolio. The system had to enforce statutory compliance, support planned preventive maintenance scheduling, manage reactive work orders, and maintain an immutable audit trail - all while isolating each customer tenant's data completely. Key requirements included:
- A hierarchical asset register spanning regions, sites, buildings, floors, zones and individual assets
- Statutory compliance tracking with immutable history for audit and regulatory obligations
- SaaS multi-tenancy with true data isolation between customer organisations
- Planned preventive maintenance (PPM) scheduling with configurable templates
- Work order lifecycle management from raise through to completion and sign-off
- Future-proofing for IoT sensor integration and BIM model linking
The Solution
The platform was designed as a domain-oriented microservice architecture with six independently deployable services, each owning its own database and domain logic. Services communicate asynchronously via RabbitMQ, with a shared Docker network and centralised JWT authentication through the Core service.
Authentication, identity, RBAC, tenant provisioning and cross-cutting concerns
Property hierarchy, asset register, location management and the Golden Thread
Work orders, PPM schedules, contractor management and job lifecycle
Budgets, purchase orders, invoicing and cost tracking per asset
Shared Composer package enforcing tenant scoping across all services
Nuxt 4 front end consuming APIs from all backend services
Multi-Tenancy
Tenant isolation is enforced through a five-layer defence model, ensuring no data can leak between customer organisations at any level of the stack:
- Physical isolation - each tenant gets a dedicated MySQL database, provisioned automatically on onboarding
- Logical isolation - every Eloquent query is scoped through a global tenant trait, preventing cross-tenant reads at the ORM level
- JWT token binding - every authenticated request carries the tenant identifier, validated at the middleware layer before any database call
- Automatic database switching - the tenancy package resolves the correct database connection per-request based on the authenticated tenant context
- Super-admin override - a controlled pathway allowing platform administrators to impersonate tenant contexts for support and debugging
The Asset Register & Golden Thread
At the heart of the platform is a hierarchical asset register modelling the full physical estate: regions, sites, buildings, floors, zones, and individual maintainable assets. Every asset carries its own maintenance history, compliance records, documentation and linked media - forming the Golden Thread: an unbroken, auditable chain of information from installation through to decommissioning. The register supports bulk import, configurable asset types with custom attribute schemas, and QR code generation for field identification.
Maintenance, Compliance & Operations
The maintenance service manages the full lifecycle of both planned and reactive work. PPM schedules are configured as reusable templates linked to asset types, automatically generating work orders at defined intervals. Reactive work orders flow through a configurable status pipeline - raised, triaged, assigned, in-progress, completed, signed-off - with role-based access controlling who can transition between stages. Contractor management includes invitation workflows, skill-matching, and job assignment with full audit trails. Field engineers interact with assigned jobs through a React Native mobile app with offline capability.
Financials
The finance service tracks budgets, purchase orders and invoicing at the asset, site and portfolio level. Costs are attributed directly to maintenance activities, providing clear visibility of spend per asset and enabling budget forecasting based on PPM schedules and historical reactive costs.
Cross-Service Communication
All inter-service communication runs through RabbitMQ message queues, keeping services decoupled and independently deployable. Events such as contractor invitations, media upload requests, notification triggers and work order state changes are published to topic exchanges and consumed by the relevant services. A centralised media pipeline handles file uploads through MinIO (S3-compatible object storage) - downstream services publish upload requests, the Core service processes and stores files via Spatie Media Library, then publishes a response event back to the originating service.
Security, Audit & Identity
Authentication flows through the Core service using JWT tokens with tenant-scoped claims. Role-based access control is managed via Spatie Permission with per-tenant role definitions. Two-factor authentication is available via Google2FA. All state-changing operations are logged to an immutable audit trail, recording the acting user, tenant context, timestamp and full before/after payloads - critical for statutory compliance and dispute resolution.
Front End
The client application is built with Nuxt 4, Vue 3 and Tailwind CSS 4, consuming REST and GraphQL APIs from the backend services. State management uses Pinia with tenant-scoped stores. Real-time updates are delivered via Laravel Reverb WebSocket broadcasting through Laravel Echo, providing live work order status changes, notification feeds and collaborative editing without polling.
Engineering Standards
The codebase enforces PHPStan at level 9 with 100% type coverage across all backend services. Every service runs its own test suite, and the shared tenancy package includes integration tests validating isolation boundaries. CI pipelines run static analysis, tests and code style checks on every push.
Technology Stack
Technical Challenges
Domain-Oriented Service Boundaries
Designed and built six independent services with boundaries aligned to business capabilities rather than technical layers. Each service owns its database, domain logic and API surface, communicating asynchronously via RabbitMQ - enabling independent deployment, scaling and team ownership.
Five-Layer Tenant Isolation
Implemented a defence-in-depth multi-tenancy model combining physical database separation, ORM-level query scoping, JWT token binding, automatic connection switching and controlled super-admin overrides - ensuring zero data leakage between customer organisations.
Immutable Audit & Statutory Compliance
Built a comprehensive audit system recording every state change with full before/after payloads, user context and tenant scope. The immutable trail satisfies statutory compliance requirements and provides the evidentiary basis for regulatory audits and dispute resolution.