Overview
RonnieERP is designed as a Central Hub + Plugin Modules platform. Central provides the foundation (identity, tenancy, access control, billing, and shared master data), while business modules (HRM, Attendance, Accounts, Inventory, etc.) run as independent plugins.
1) Architecture Concept
The system is built with a strong separation of concerns: Central Hub handles cross-cutting platform responsibilities and acts as the authority for tenants, users, permissions, module licensing, and billing. Each Module owns its business logic and (optionally) its own database.
Core Philosophy
- Modularity: Modules are isolated packages/services that plug into the ecosystem.
- Isolation: Each module has its own lifecycle, codebase, migrations, and optionally DB.
- Stability: Central stays small, stable, and heavily protected with governance.
- Multi-Tenancy: One platform supports many companies (tenants) with strict separation.
- Governance: Changes flow through controlled PRs, approvals, CI checks, and deployments.
2) What Central Owns vs What Modules Own
Central owns
- Tenants (companies), onboarding, company settings
- Users, authentication, sessions/tokens
- RBAC: roles/permissions, access control
- Module Marketplace: available modules, plans
- Tenant Modules: enable/disable modules per tenant
- Billing: subscriptions, invoices, payments, transactions
- Shared Master Data: People directory, branches, departments
- Audit & Logs: who did what, when, from where
- Support: ticket system
Modules own
- Business logic (HR policies, attendance rules, accounting rules)
- Module-specific data (leave requests, shift logs, ledgers)
- Module APIs (endpoints and validation rules)
- Module UI screens and workflows
- Events published/consumed by module
- Module DB (in multi-DB architecture)
3) Central Free/Core Modules
To ensure a ready-to-use ERP experience, Central ships with these core features:
I. Foundation & Security
- Signup/Login/2FA: Secure authentication gateway.
- Tenant Onboarding: Company profile, timezone, currency wizard.
- Users + RBAC: Invite system and granular permission matrix.
- Audit Logs: Immutable history of "Who did What".
II. Master Data
- People Directory: The "Single Source of Truth" for human identities.
- Branches & Departments: The organizational tree structure.
III. Commercial & Support
- Module Marketplace: Browse & Enable plugins.
- Billing Portal: Invoices, Cards, Transaction History.
- Support Tickets: Internal helpdesk for employees.
IV. Productivity (Free Utilities)
- Calendar: basic team scheduling.
- Notes & Todos: Simple task tracking to keep users engaged.
Visualizing the Core Ecosystem
flowchart TD
subgraph Central_Hub [Central Hub Core]
direction TB
Auth[Auth & RBAC]
Dir[People Directory]
Org[Branches & Depts]
Bill[Billing & Marketplace]
Audit[Audit Logs]
Ticket[Support Tickets]
end
subgraph Plugin_Layer [Paid Plugin Layer]
HRM[HRM Module]
Att[Attendance Module]
Acc[Accounts Module]
end
HRM -->|Consumes| Dir
Att -->|Consumes| Org
Acc -->|Consumes| Bill
style Central_Hub fill:#f3f4f6,stroke:#2563eb
style Plugin_Layer fill:transparent,stroke:#9333ea,stroke-dasharray: 5 5
Deep Dive: Core Features
1. Branches & Departments (Master Data)
Instead of HRM having "Departments" and Inventory having "Warehouses" that are disconnected, Central owns the Organizational Structure.
- What it is: A tree of physical locations (Branches) and functional units (Departments).
- Usage:
- HRM uses it for "Employee A belongs to Sales Dept".
- Attendance uses it for "Shift B applies to New York Branch".
- Accounts uses it for "Cost Center: Marketing".
Data Usage Diagram
flowchart LR
Central[Central Hub]
HRM[HRM Service]
Att[Attendance Service]
Acc[Accounts Service]
Central -- Owns --> Branches[Branches Table]
Central -- Owns --> Depts[Departments Table]
HRM -.->|Ref ID| Branches
Att -.->|Ref ID| Depts
Acc -.->|Ref ID| Branches
Central -.-> Note[Authoritative Source]
style Note fill:#fff,stroke:#333,stroke-dasharray: 5 5
2. Audit Logs
Compliance is mandatory for ERPs. Central intercepts every request via middleware and logs it to an immutable `audit_logs` table (and potentially cold storage).
- Scope: Actions like `user.login`, `module.enabled`, `employee.created`.
- Security: Logs cannot be deleted by Tenant Admins.
Audit Logging Flow
flowchart LR
User[User Request] --> GW[Gateway]
GW --> Mid[Central Middleware w/ Audit]
Mid --> DB[(Audit Log DB)]
Mid --> Mod{Authorized?}
Mod -- Yes --> Service[Target Module]
Mod -- No --> Deny[403 Forbidden]
style DB fill:#f9f,stroke:#333
3. Tickets & Support
A built-in ticketing system allows Employees to report issues (e.g., "My Laptop is broken" or "Incorrect Payslip") directly to Tenant Admins. This keeps communication inside the ERP rather than lost in emails.
4. Productivity Tools
Sticky features like a shared Calendar or simple Notes ensure users log in daily, even if they don't have heavy ERP tasks to do. These are "loss leaders" to drive engagement.
4) Multi-Tenancy Model (Central)
RonnieERP is multi-tenant, meaning one platform supports multiple companies. Every request must be associated with a tenant context. Tenant context can be resolved by:
- Subdomain (recommended):
companyA.yourerp.com - Tenant selection after login (user chooses company)
- Header:
X-Tenant-IDfor internal APIs/Postman
5) High-Level System Diagram
flowchart TD
U((User)) --> FE[React + Vite Frontend]
FE --> GW[API Gateway / Reverse Proxy]
subgraph Core_Platform ["Core Platform"]
GW --> CENTRAL[Central Hub Service]
CENTRAL --> CDB[(Central DB)]
CENTRAL --> CACHE[(Redis Cache)]
CENTRAL --> AUTH[Auth + RBAC]
CENTRAL --> LIC[Licensing]
CENTRAL --> BILL[Billing]
end
subgraph Async_Backbone ["Integration Bus"]
CENTRAL -- Publish --> BUS{Event Bus}
end
subgraph Modules ["Plugin Modules"]
BUS -- Subscribe --> HRM[HRM Service]
BUS -- Subscribe --> ATT[Attendance Service]
BUS -- Subscribe --> ACC[Accounts Service]
HRM --> HRMDB[(HRM DB)]
ATT --> ATTDB[(Attendance DB)]
ACC --> ACCDB[(Accounts DB)]
GW --> HRM
GW --> ATT
GW --> ACC
end
HRM -.->|Read Master| CENTRAL
ATT -.->|Read Master| CENTRAL
6) Request & Authorization Sequence
Enterprise Security Model: No request bypasses the security layer. Every API call is intercepted to verify Identity AND Authority. We use a Middleware Pipeline to enforce this.
Security Flow Checklist
- Gateway: Rate limiting, WAF checks (checking for SQLi/XSS patterns).
- VerifyBearerToken: Decodes JWT/Sanctum token. Fails if expired or invalid signature.
- ResolveTenantContext: Identifies which Tenant data is being requested (from Subdomain or Header).
- EnsureTenantMembership: Checks if the User actually belongs to this Tenant.
- EnsureModuleEnabled: verifies
tenant_modulestable (cached in Redis) to see if 'hrm' is active. - AuthorizePermission: Checks RBAC (e.g., does user have
hrm:employee:create?). - AuditTrailMiddleware: Logs the action.
Middleware Pipeline
flowchart LR
Req[Request] --> GW[Gateway]
GW --> Auth[Verify Token]
Auth --> Ten[Resolve Tenant]
Ten --> Mem[Check Membership]
Mem --> Lic[Check Module Active]
Lic --> Perm[Check Permissions]
Perm --> Ctrl[Controller Action]
Lic -.->|Cache Hit| Redis[(Redis)]
Perm -.->|Cache Hit| Redis
Full Sequence Diagram
sequenceDiagram
autonumber
participant User
participant FE as Frontend
participant GW as Gateway
participant Central
participant Redis
participant DB as Central DB
User->>FE: Open HRM Employee List
FE->>GW: GET /api/hrm/employees
note right of FE: Header: Authorization Bearer <token>
GW->>Central: Forward Request
rect rgb(240, 248, 255)
note right of Central: Security Middleware Chain
Central->>Central: Verify JWT Signature
Central->>Redis: Get User Context & Permissions
alt Cache Miss
Central->>DB: Fetch User + Roles + Tenant Modules
DB-->>Central: Data
Central->>Redis: Cache (TTL 10min)
end
Central->>Central: Check Tenant Membership
Central->>Central: Check 'HRM' Module Enabled
Central->>Central: Check Permission 'hrm:view'
end
alt Access Denied
Central-->>GW: 403 Forbidden
GW-->>FE: Show Error
else Access Granted
Central->>GW: Proxy to Module / Execute
GW-->>FE: JSON Response
end
7) Module Enablement Flowchart
How a tenant activates a new feature (e.g., enabling the Payroll module).
flowchart TD
Start([Admin clicks Enable]) --> PlanCheck{Plan includes Module?}
PlanCheck -- No --> Prompt[Show Upgrade Dialog]
Prompt --> End([Stop])
PlanCheck -- Yes --> DBCreate[Create tenant_modules record]
DBCreate --> PayCheck{Payment Required?}
PayCheck -- Yes --> Gateway[Process Payment Details]
Gateway -- Fail --> Pending[Set Status: Pending] --> End
Gateway -- Success --> Active[Set Status: Active]
PayCheck -- No --> Active
Active --> Mid[Update Redis Cache]
Mid --> Event[Publish 'module.enabled' Event]
Event --> Sub[Module Service Subscribes]
Sub --> Setup[Run Tenant Migrations/Seeds]
Setup --> Ready([Module Ready in UI])
8) Non-Functional Requirements (ERP-grade)
Why we build it this way.
Reliability & Fault Isolation
Why: In a monolith, one bad update to the "Chat" feature shouldn't crash "Payroll".
Modules run in isolation. If the Attendance module crashes or throws 500s, the User Management and basic ERP functions continue to work perfectly.
Performance & Caching
Why: Checking permissions against the DB on every request is too slow.
We use Redis to cache User permissions and Module status. Authentication usually happens in <10ms via cache hits.
Fault Isolation Diagram
flowchart TD
User --> Hub[Central Hub]
Hub --> ModA[Module A: HRM]
Hub --> ModB[Module B: Chat]
style ModB fill:#ffcccc,stroke:#ff0000
ModA -->|Works| OK[Status 200]
ModB -->|Crashed| Err[Status 500]
OK --> UI[User Interface]
Err -->|Fallback| UI
%% Using a sub-node or label for the note behavior in flowchart
UI -.-> Note["App stays alive even if Chat is down"]
style Note fill:#fff,stroke:#333,stroke-dasharray: 5 5
9) Technology Stack (Baseline)
The chosen technologies maximize stability and developer experience.
| Component | Technology | Why this choice? |
|---|---|---|
| Backend | Laravel 12 (PHP) | Best-in-class Eloquent ORM, Queues, and rapid development tools. |
| Database | PostgreSQL | Superior handling of JSONB (for settings), Schema support (for multi-tenancy), and strong concurrency. |
| Frontend | Legacy JS / React | Component-based architecture matching our modular backend design. |
| Event Bus | Redis Streams / RabbitMQ | Decouples services so they don't depend on each other's uptime. |
Why PostgreSQL?
flowchart TD
CentralApp --> DB[(PostgreSQL Cluster)]
subgraph DB_Features [PostgreSQL Capabilities]
JSONB[JSONB Columns]
Schemas[Schemas per Tenant]
ACID[Strict ACID]
end
DB --> JSONB
DB --> Schemas
DB --> ACID
JSONB -->|Stores| Settings[Dynamic Module Settings]
Schemas -->|Isolates| TenantData[Tenant Data Isolation]
10) Data Sync Strategy
When a Module needs data from Central (like a User's name), it doesn't query the Central table with a JOIN. Instead, it subscribes to events and keeps a local Read Model.
sequenceDiagram
participant Admin
participant HRM
participant Bus as EventBus
participant Attendance
participant AttDB as Attendance DB
Admin->>HRM: Create Employee "John Doe"
HRM->>Bus: Publish 'employee.created'
par Fan Out
Bus->>Attendance: Consume Event
and
Bus->>OtherMod: Consume Event
end
Attendance->>AttDB: Insert into 'local_employees_lookup'
note right of AttDB: ID, Name, Dept (Read Only)
note over Attendance, AttDB: Now Attendance can show John's name
without querying HRM Service.
11) Customization & Security Boundaries
Customization
Modules are extensible "Plugins".
- Routes: Modules register their own API routes.
- Menus: Modules inject items into the sidebar.
- Versioning: Upgrades happen via SemVer without breaking Core.
Threat Model
We assume the browser is untrusted.
- No Direct DB Access: Impossible for frontend to query DB.
- Cross-Tenant Block: Middleware explicitly filters by
tenant_id. - PrivEsc Limit: RBAC checks on every route.
Trust Boundaries Diagram
flowchart TD
subgraph Untrusted_Zone [Untrusted Zone]
Browser
MobileApp
end
subgraph DMZ [DMZ]
Gateway[API Gateway / WAF]
LB[Load Balancer]
end
subgraph Trusted_Zone [Trusted Private Network]
Central[Central Application]
Mod1[Module A]
Mod2[Module B]
DB[(Databases)]
end
Browser --x|Blocked| DB
Browser -->|HTTPS| Gateway
Gateway -->|Sanitized Request| Central
Central -->|Query| DB
12) Next Steps
- Central Scope – Detailed boundaries.
- Central Modules – Full list of capabilities.
- Use Cases – Functional requirements.