# iraed/pm-os architecture

> Architecture diagram of the GitHub repository iraed/pm-os, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-02). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/iraed/pm-os
- Repository: https://github.com/iraed/pm-os

## Overview

#### Purpose and Runtime
PM-OS is a Laravel 11 modular-monolith SaaS for property-management companies, covering property onboarding, leasing, resident management, billing, and maintenance. It uses Vue 3/Inertia for the authenticated UI and PostgreSQL tenant databases. Docker Compose provides the local runtime: `Dockerfile`, `docker-compose.yml`, `docker/nginx/conf.d/default.conf`.

#### Application Entry Points
HTTP starts at Laravel route layers: central/web routes in `routes/web.php` and tenant-scoped routes in `routes/tenant.php`. Module APIs are independently registered, e.g. `app/Modules/Foundation/Routes/api.php`, `app/Modules/PropertyOnboarding/Routes/api.php`, and `app/Modules/Collection/Routes/api.php`. The browser shell and Inertia client begin at `resources/views/app.blade.php` and `resources/js/app.js`.

#### Tenant Isolation and Bootstrap
The system is database-per-tenant, with central plan/tenant records in `app/Core/MultiTenancy/Models/Plan.php` and `app/Core/MultiTenancy/Models/Tenant.php`. Tenancy behavior is configured in `config/tenancy.php`; tenant schema is separated from central migrations in `database/migrations/tenant/`. `app/Core/ModuleServiceProvider.php` is the central integration point for modular application bootstrapping.

#### Foundation Domain
Foundation owns the portfolio graph and authorization boundary: users, owners, properties, and units. Its HTTP controllers validate requests, apply policy checks, and return resource representations around `app/Modules/Foundation/Models/Property.php`, `app/Modules/Foundation/Http/Controllers/PropertyController.php`, and `app/Modules/Foundation/Policies/PropertyPolicy.php`. Other operational modules attach their records to this property/unit base.

#### Guided Property Onboarding
Onboarding is a workflow layer over Foundation that creates a property, adds units, gathers documents, inspections, and risk information, and emits lifecycle events. Requests enter `app/Modules/PropertyOnboarding/Http/Controllers/OnboardingController.php`; orchestration belongs in `app/Modules/PropertyOnboarding/Services/PropertyOnboardingService.php`; completion is signaled through `app/Modules/PropertyOnboarding/Events/PropertyOnboarded.php`. This separates multi-step workflow control from core property persistence.

#### Operational Lifecycle Modules
Leasing records tenancy contracts in `app/Modules/Leasing/Models/Lease.php`; resident identity/lifecycle is represented by `app/Modules/TenantManagement/Models/Resident.php`. Financial collection centers on invoices, schedules, and payments at `app/Modules/Collection/Models/Invoice.php`, `app/Modules/Collection/Models/PaymentSchedule.php`, and `app/Modules/Collection/Models/Payment.php`. Maintenance tracks reactive and preventive work via `app/Modules/Maintenance/Models/WorkOrder.php`, `app/Modules/Maintenance/Models/PmPlan.php`, and `app/Modules/Maintenance/Models/Inspection.php`.

#### Automation and AI Boundary
Scheduled/background jobs drive cross-domain exceptions and recurring work: `app/Jobs/Tenant/CheckLeaseExpirations.php`, `app/Jobs/Tenant/CheckOverdueInvoices.php`, and `app/Jobs/Tenant/TriggerPreventiveMaintenance.php`. Redis/Horizon is the intended queue runtime. AI remains provider-abstracted: `app/Modules/AIEngine/Contracts/AIProviderInterface.php` isolates callers from OpenAI-specific behavior in `app/Modules/AIEngine/Providers/OpenAIProvider.php`, with reporting orchestration in `app/Modules/AIEngine/Services/AIReportGenerator.php`. External Saudi integrations (Ejar, ZATCA, Sadad) are stated as readiness targets, not represented by implementation paths here.

Main entry points: [`app/Modules/Foundation/Models/Property.php`](https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Models/Property.php) (Property portfolio), [`app/Jobs/Tenant/CheckLeaseExpirations.php`](https://github.com/iraed/pm-os/blob/main/app/Jobs/Tenant/CheckLeaseExpirations.php) (Tenant automation jobs), [`config/tenancy.php`](https://github.com/iraed/pm-os/blob/main/config/tenancy.php) (Tenancy configuration), [`app/Modules/Foundation/Http/Controllers/PropertyController.php`](https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Http/Controllers/PropertyController.php) (Property controller)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime &amp; UI"]
  node_compose{{"Docker Compose<br/>local runtime<br/>[docker-compose.yml]"}}
  node_web_routes["Central web routes<br/>Laravel routes<br/>[web.php]"]
  node_tenant_routes["Tenant routes<br/>Laravel routes<br/>[tenant.php]"]
  node_inertia_client["Inertia Vue client<br/>authenticated UI<br/>[app.js]"]
  node_app_shell["Blade app shell<br/>HTML entry<br/>[app.blade.php]"]
end

subgraph group_tenancy["Tenancy &amp; Bootstrap"]
  node_module_provider["Module service provider<br/>module bootstrap"]
  node_tenancy_config["Tenancy configuration<br/>tenant bootstrap<br/>[tenancy.php]"]
  node_tenant_model[("Tenant &amp; plans<br/>central tenancy records<br/>[Tenant.php]")]
  node_tenant_schema["Tenant migrations<br/>tenant schema"]
  node_tenant_db[("Tenant PostgreSQL DBs<br/>database-per-tenant storage")]
end

subgraph group_domains["Domain Modules"]
  node_foundation_api["Foundation API routes<br/>module API<br/>[api.php]"]
  node_property_controller["Property controller<br/>HTTP controller"]
  node_property_policy["Property policy<br/>authorization policy<br/>[PropertyPolicy.php]"]
  node_property[("Property portfolio<br/>Foundation model<br/>[Property.php]")]
  node_onboarding["Property onboarding<br/>workflow service"]
  node_property_onboarded["Property onboarded<br/>lifecycle event"]
  node_leasing[("Leases<br/>Leasing model<br/>[Lease.php]")]
  node_residents[("Residents<br/>Tenant Management model<br/>[Resident.php]")]
  node_collection[("Billing &amp; collection<br/>financial models<br/>[Invoice.php]")]
  node_maintenance[("Maintenance<br/>work management models<br/>[WorkOrder.php]")]
end

subgraph group_automation["Automation &amp; AI"]
  node_tenant_jobs["Tenant automation jobs<br/>scheduled jobs"]
  node_redis_horizon["Redis / Horizon<br/>queue runtime"]
  node_ai_reports["AI report generator<br/>report orchestration"]
  node_ai_contract["AI provider contract<br/>provider abstraction"]
  node_openai_provider["OpenAI provider<br/>AI provider adapter<br/>[OpenAIProvider.php]"]
end

node_compose -->|"serves"| node_web_routes
node_web_routes -->|"renders"| node_app_shell
node_app_shell -->|"boots"| node_inertia_client
node_inertia_client -->|"requests"| node_tenant_routes
node_module_provider -->|"registers"| node_foundation_api
node_module_provider -->|"boots with"| node_tenancy_config
node_tenancy_config -->|"resolves"| node_tenant_model
node_tenancy_config -->|"selects"| node_tenant_db
node_tenant_schema -->|"provisions"| node_tenant_db
node_foundation_api -->|"dispatches"| node_property_controller
node_property_controller -->|"authorizes via"| node_property_policy
node_property_controller -->|"manages"| node_property
node_tenant_routes -->|"starts workflow"| node_onboarding
node_onboarding -->|"creates"| node_property
node_onboarding -->|"emits"| node_property_onboarded
node_property -->|"anchors"| node_leasing
node_property -->|"scopes"| node_residents
node_property -->|"scopes"| node_collection
node_property -->|"scopes"| node_maintenance
node_tenant_jobs -->|"runs on"| node_redis_horizon
node_tenant_jobs -.->|"checks expirations"| node_leasing
node_tenant_jobs -.->|"checks overdue invoices"| node_collection
node_tenant_jobs -.->|"triggers preventive work"| node_maintenance
node_ai_reports -->|"uses"| node_ai_contract
node_ai_contract -->|"implemented by"| node_openai_provider

click node_compose "https://github.com/iraed/pm-os/blob/main/docker-compose.yml"
click node_web_routes "https://github.com/iraed/pm-os/blob/main/routes/web.php"
click node_tenant_routes "https://github.com/iraed/pm-os/blob/main/routes/tenant.php"
click node_inertia_client "https://github.com/iraed/pm-os/blob/main/resources/js/app.js"
click node_app_shell "https://github.com/iraed/pm-os/blob/main/resources/views/app.blade.php"
click node_module_provider "https://github.com/iraed/pm-os/blob/main/app/Core/ModuleServiceProvider.php"
click node_tenancy_config "https://github.com/iraed/pm-os/blob/main/config/tenancy.php"
click node_tenant_model "https://github.com/iraed/pm-os/blob/main/app/Core/MultiTenancy/Models/Tenant.php"
click node_foundation_api "https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Routes/api.php"
click node_property_controller "https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Http/Controllers/PropertyController.php"
click node_property_policy "https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Policies/PropertyPolicy.php"
click node_property "https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Models/Property.php"
click node_onboarding "https://github.com/iraed/pm-os/blob/main/app/Modules/PropertyOnboarding/Services/PropertyOnboardingService.php"
click node_property_onboarded "https://github.com/iraed/pm-os/blob/main/app/Modules/PropertyOnboarding/Events/PropertyOnboarded.php"
click node_leasing "https://github.com/iraed/pm-os/blob/main/app/Modules/Leasing/Models/Lease.php"
click node_residents "https://github.com/iraed/pm-os/blob/main/app/Modules/TenantManagement/Models/Resident.php"
click node_collection "https://github.com/iraed/pm-os/blob/main/app/Modules/Collection/Models/Invoice.php"
click node_maintenance "https://github.com/iraed/pm-os/blob/main/app/Modules/Maintenance/Models/WorkOrder.php"
click node_tenant_jobs "https://github.com/iraed/pm-os/blob/main/app/Jobs/Tenant/CheckLeaseExpirations.php"
click node_ai_reports "https://github.com/iraed/pm-os/blob/main/app/Modules/AIEngine/Services/AIReportGenerator.php"
click node_ai_contract "https://github.com/iraed/pm-os/blob/main/app/Modules/AIEngine/Contracts/AIProviderInterface.php"
click node_openai_provider "https://github.com/iraed/pm-os/blob/main/app/Modules/AIEngine/Providers/OpenAIProvider.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_compose,node_web_routes,node_tenant_routes,node_inertia_client,node_app_shell toneBlue
class node_module_provider,node_tenancy_config,node_tenant_model,node_tenant_schema,node_tenant_db toneAmber
class node_foundation_api,node_property_controller,node_property_policy,node_property,node_onboarding,node_property_onboarded,node_leasing,node_residents,node_collection,node_maintenance toneMint
class node_tenant_jobs,node_redis_horizon,node_ai_reports,node_ai_contract,node_openai_provider toneRose
```

## Components

### Runtime & UI

- [Docker Compose](https://github.com/iraed/pm-os/blob/main/docker-compose.yml): local runtime · Runs Laravel, Nginx, and supporting services locally. · `docker-compose.yml`
- [Central web routes](https://github.com/iraed/pm-os/blob/main/routes/web.php): Laravel routes · `routes/web.php`
- [Tenant routes](https://github.com/iraed/pm-os/blob/main/routes/tenant.php): Laravel routes · `routes/tenant.php`
- [Inertia Vue client](https://github.com/iraed/pm-os/blob/main/resources/js/app.js): authenticated UI · `resources/js/app.js`
- [Blade app shell](https://github.com/iraed/pm-os/blob/main/resources/views/app.blade.php): HTML entry · `resources/views/app.blade.php`

### Tenancy & Bootstrap

- [Module service provider](https://github.com/iraed/pm-os/blob/main/app/Core/ModuleServiceProvider.php): module bootstrap · Central integration point for modular application bootstrapping. · `app/Core/ModuleServiceProvider.php`
- [Tenancy configuration](https://github.com/iraed/pm-os/blob/main/config/tenancy.php): tenant bootstrap · Configures database-per-tenant behavior. · `config/tenancy.php`
- [Tenant & plans](https://github.com/iraed/pm-os/blob/main/app/Core/MultiTenancy/Models/Tenant.php): central tenancy records · `app/Core/MultiTenancy/Models/Tenant.php`
- **Tenant migrations**: tenant schema
- **Tenant PostgreSQL DBs**: database-per-tenant storage

### Domain Modules

- [Foundation API routes](https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Routes/api.php): module API · `app/Modules/Foundation/Routes/api.php`
- [Property controller](https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Http/Controllers/PropertyController.php): HTTP controller · Validates requests and applies property authorization. · `app/Modules/Foundation/Http/Controllers/PropertyController.php`
- [Property policy](https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Policies/PropertyPolicy.php): authorization policy · `app/Modules/Foundation/Policies/PropertyPolicy.php`
- [Property portfolio](https://github.com/iraed/pm-os/blob/main/app/Modules/Foundation/Models/Property.php): Foundation model · Base property and unit graph for operational modules. · `app/Modules/Foundation/Models/Property.php`
- [Property onboarding](https://github.com/iraed/pm-os/blob/main/app/Modules/PropertyOnboarding/Services/PropertyOnboardingService.php): workflow service · Creates properties and gathers units, documents, inspections, and risk data. · `app/Modules/PropertyOnboarding/Services/PropertyOnboardingService.php`
- [Property onboarded](https://github.com/iraed/pm-os/blob/main/app/Modules/PropertyOnboarding/Events/PropertyOnboarded.php): lifecycle event · `app/Modules/PropertyOnboarding/Events/PropertyOnboarded.php`
- [Leases](https://github.com/iraed/pm-os/blob/main/app/Modules/Leasing/Models/Lease.php): Leasing model · `app/Modules/Leasing/Models/Lease.php`
- [Residents](https://github.com/iraed/pm-os/blob/main/app/Modules/TenantManagement/Models/Resident.php): Tenant Management model · `app/Modules/TenantManagement/Models/Resident.php`
- [Billing & collection](https://github.com/iraed/pm-os/blob/main/app/Modules/Collection/Models/Invoice.php): financial models · Invoices, payment schedules, and payments. · `app/Modules/Collection/Models/Invoice.php`
- [Maintenance](https://github.com/iraed/pm-os/blob/main/app/Modules/Maintenance/Models/WorkOrder.php): work management models · Work orders, preventive plans, and inspections. · `app/Modules/Maintenance/Models/WorkOrder.php`

### Automation & AI

- [Tenant automation jobs](https://github.com/iraed/pm-os/blob/main/app/Jobs/Tenant/CheckLeaseExpirations.php): scheduled jobs · Checks lease expirations, overdue invoices, and preventive maintenance. · `app/Jobs/Tenant/CheckLeaseExpirations.php`
- **Redis / Horizon**: queue runtime
- [AI report generator](https://github.com/iraed/pm-os/blob/main/app/Modules/AIEngine/Services/AIReportGenerator.php): report orchestration · `app/Modules/AIEngine/Services/AIReportGenerator.php`
- [AI provider contract](https://github.com/iraed/pm-os/blob/main/app/Modules/AIEngine/Contracts/AIProviderInterface.php): provider abstraction · `app/Modules/AIEngine/Contracts/AIProviderInterface.php`
- [OpenAI provider](https://github.com/iraed/pm-os/blob/main/app/Modules/AIEngine/Providers/OpenAIProvider.php): AI provider adapter · `app/Modules/AIEngine/Providers/OpenAIProvider.php`

## Connections

- Docker Compose → Central web routes: serves
- Central web routes → Blade app shell: renders
- Blade app shell → Inertia Vue client: boots
- Inertia Vue client → Tenant routes: requests
- Module service provider → Foundation API routes: registers
- Module service provider → Tenancy configuration: boots with
- Tenancy configuration → Tenant & plans: resolves
- Tenancy configuration → Tenant PostgreSQL DBs: selects
- Tenant migrations → Tenant PostgreSQL DBs: provisions
- Foundation API routes → Property controller: dispatches
- Property controller → Property policy: authorizes via
- Property controller → Property portfolio: manages
- Tenant routes → Property onboarding: starts workflow
- Property onboarding → Property portfolio: creates
- Property onboarding → Property onboarded: emits
- Property portfolio → Leases: anchors
- Property portfolio → Residents: scopes
- Property portfolio → Billing & collection: scopes
- Property portfolio → Maintenance: scopes
- Tenant automation jobs → Redis / Horizon: runs on
- Tenant automation jobs → Leases: checks expirations
- Tenant automation jobs → Billing & collection: checks overdue invoices
- Tenant automation jobs → Maintenance: triggers preventive work
- AI report generator → AI provider contract: uses
- AI provider contract → OpenAI provider: implemented by
