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.

Key Goal: Add or upgrade modules without risking Central stability. If a module fails, the core platform remains operational.

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


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)
Data Ownership Rule: A module should not write directly into another module's DB/tables. Data sharing should happen via Central master tables (People/Branches) or via events.

3) Central Free/Core Modules

Why Free? These modules reduce friction, ensure every tenant has a solid foundation, and prevent paid modules from reimplementing the wheel. They power the ecosystem.

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.

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

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:


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
            
Note: In early phases, modules may run as packages inside the Monolith. In the enterprise approach shown above, they run as separate services with dedicated databases.

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

  1. Gateway: Rate limiting, WAF checks (checking for SQLi/XSS patterns).
  2. VerifyBearerToken: Decodes JWT/Sanctum token. Fails if expired or invalid signature.
  3. ResolveTenantContext: Identifies which Tenant data is being requested (from Subdomain or Header).
  4. EnsureTenantMembership: Checks if the User actually belongs to this Tenant.
  5. EnsureModuleEnabled: verifies tenant_modules table (cached in Redis) to see if 'hrm' is active.
  6. AuthorizePermission: Checks RBAC (e.g., does user have hrm:employee:create?).
  7. 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

  1. Central Scope – Detailed boundaries.
  2. Central Modules – Full list of capabilities.
  3. Use Cases – Functional requirements.
Go to Central Scope → Jump to Use Cases