Skip to content

Architecture Diagrams

This page contains various architecture diagrams for the PRS system.

System Architecture

The following diagram shows the high-level architecture of the PRS system:

---
config:
  theme: neo
  look: default
  layout: elk
---
flowchart TD
subgraph C1["Admin Module"]
     direction LR
        C1a["User Management"]
        C1b["Item Management"]
        C1c["Company/Assoc Management"]
        C1d["Project Management"]
        C1e["Department Management"]
        C1f["Supplier Management"]
 end
 subgraph C2["Transaction Module"]
     direction LR
        C2a["Requisition"]
        C2b["Canvassing"]
        C2c["Purchase Order"]
        C2d["Receiving Report"]
        C2e["Invoice Report"]
        C2f["Payment Request"]
        C2g["Non-RS Payment"]
        C2h["History"]
 end
 subgraph C3["General Module"]
        C3a["Login, Logout, Dashboard"]
 end
 subgraph C4["Security"]
        C4a["2FA"]
 end
 subgraph C5["Notifications"]
        C5a["In-App"]
 end
 subgraph Modules["Modules"]
 direction LR
        C1 ~~~ C2
        C2 ~~~ C3
        C3 ~~~ C4
        C4 ~~~ C5
 end
 subgraph Database["Timescale Database"]
        D1["PostgreSQL"]
 end
 subgraph Storage["Local Storage"]
        S1["RAID 1"]
 end
 subgraph Monitoring ["Monitoring"]
        M1["Prometheus"]
        M2["Grafana"]
 end
 subgraph Portainer["Container (Portainer)"]
        A3a["NGINX Web Server"]
        Modules
        Database
        Storage
        Monitoring
  end
 subgraph Integrations["Integrations"]
        E2a["Cityland IBM I-Series Accounting System"]
  end
 subgraph NAS["NAS"]
        E1a["RAID 1"]
  end
 subgraph s1["On-Premise"]
        Portainer
        Integrations
        NAS
  end
  subgraph users["Users"]
        A1["Cityland IT Admin"] 
        A2["Cityland Users"]
  end
    A1-- VPN --> A3{"PRS Web App"}
    A2-- VPN --> A3
    A3 --> A3a
    A3a --> Modules
    Modules --> Database & Storage & NAS
    E2a --> Modules
    users --> A4[/"Google Auth"/]
     A1:::internal
     A3:::core
     A2:::internal
     A4:::external
     C1:::core
     C2:::core
     C3:::core
     C4:::core
     C5:::core

Database Schema

The following diagram shows a simplified version of the database schema:

erDiagram

%%Relations
    User ||--o{ Requisition : creates
    User ||--o{ Canvass : creates
    User ||--o{ ReceivingReport : creates
    User ||--o{ InvoiceReport : creates
    User ||--o{ PaymentRequest : creates
    User ||--o{ NonRSPayment : creates
    Requisition ||--|{ RequisitionItems : contains
    Requisition ||--|{ RequisitionApproval : requires
    Canvass ||--|{ CanvassItems : contains
    Canvass ||--|{ CanvassApproval : requires
    Canvass ||--o| PurchaseOrder : generates
    PurchaseOrder ||--|{ PurchaseOrderItems : contains
    PurchaseOrder ||--|{ PurchaseOrderApproval : requires
    PurchaseOrder ||--o{ ReceivingReport : has
    PurchaseOrder ||--o{ InvoiceReport : has
    ReceivingReport ||--|{ ReceivingReportItems : contains
    InvoiceReport ||--|{ ReceivingReport : contains
    PaymentRequest ||--|{ PaymentRequestApproval : requires
    PaymentRequest ||--|{ InvoiceReport : contains
    NonRSPayment ||--|{ NonRSPaymentItems : contains
    NonRSPayment ||--|{ NonRSPaymentApproval : requires

%%Entities
    User {
        int id PK
        string username
        string email
        string role_id
    }

    Requisition {
        int id PK
        int requesterId FK
        date requestDate
        string status
        string category
        string type
    }

    RequisitionItems {
        int id PK
        int requisitionId FK
        string itemType
        string description
        decimal quantity
        int accountCode
        string unit
    }

    RequisitionApproval {
        int id PK
        int requisitionId FK
        int approverId FK
        date approvalDate
        string status
    }

    Canvass {
        int id PK
        int requisitionId FK
        string status
    }

    CanvassItems {
        int id PK
        int requisitionId FK
        int supplierId FK
        decimal canvassQty
        decimal quotedPrice
    }

    CanvassApproval {
        int id PK
        int canvassId FK
        int approverId FK
        date approvalDate
        string status
    }

    PurchaseOrder {
        int id PK
        int requisitionId FK
        int supplierId FK
        date orderDate
        string status
        decimal totalAmount
    }

    PurchaseOrderItems {
        int id PK
        int purchaseOrderId FK
        string description
        decimal quantity
        decimal unitPrice
    }

    PurchaseOrderApproval {
        int id PK
        int purchaseOrderId FK
        int approverId FK
        date approvalDate
        string status
    }

    ReceivingReport {
        int id PK
        int purchaseOrderId FK
        date deliveryDate
        string status
    }

    ReceivingReportItems {
        int id PK
        int deliveryReportId FK
        date deliveryDate
        decimal quantity
    }

    InvoiceReport {
        int id PK
        int purchaseOrderId FK
        int deliveryReportID FK
        decimal invoiceAmount
    }

    PaymentRequest {
        int id PK
        int purchaseOrderId FK
        int invoiceReportID FK
        decimal prAmount
    }

    PaymentRequestApproval {
        int id PK
        int paymentRequestID FK
        int approverId FK
        date approvalDate
        string status
    }

    NonRSPayment {
        int id PK
        int requesterId FK
        date requestDate
        string status
        string category
        string type
        decimal amount
    }

    NonRSPaymentItems {
        int id PK
        int nonRSId FK
        string description
        decimal quantity
        string unit
    }

    NonRSPaymentApproval {
        int id PK
        int nonRSId FK
        int approverId FK
        date approvalDate
        string status
    }

Workflow Diagram

The following diagram shows the requisition workflow:

sequenceDiagram
  actor R as Requestor
  actor A as Approvers
  actor P as Purchasing
  actor RP as Requestor or Purchasing
  actor S as Supplier
  participant RS as Requisition Module
  participant CS as Canvassing Module
  participant PO as Purchase Order Module
  participant RR as Receiving Report Module
  participant IR as Invoice Report Module
  participant PR as Payment Request Module
  participant CL as Cityland Legacy

%%HAPPY PATH

%%Requisition
R->>RS: Create and Submit Requisition Slip
RS->>A: Notify for Approval
A->>RS: Edit and Approve RS
P->>RS: Assign RS

loop Repeat until all items are canvassed and approved <br> (Remaining Qty > 0)
%%Canvassing
P->>CS: Create Canvass Sheet based on approved RS and Submit
CS->>A: Notify for Approval
A->>CS: Edit and Approve CS


%%Purchase Order
CS->>PO: Generate PO <br> based on approved CS
P->>PO: Review, edit, and submit generated PO
PO->>A: Notify for Approval
A->>PO: Edit and Approve PO
P->>S: Send PO offline
P->>PO: Change status of PO to "For Delivery"

loop Repeat until all PO are delivered and fully paid
RP->>RR: Create DR/s per PO
RP->>IR: Create IR/s per PO and attach DR/s
P->>PR: Create PR/s per PO and attach IR/s
end

PR->>A: Notify for Approval
A->>PR: Edit and Approve PR
PR->>CL: Send PR to Accounting System

end

Component Diagram

The following diagram shows the main components of the PRS system based on the layered architecture:

flowchart TB
    subgraph "Client Layer"
        Browser[Web Browser]
    end

    subgraph "API Layer"
        Router[Router]
        Controllers[Controllers]
        Middlewares[Middlewares]
        Validators[Validators]
    end

    subgraph "Service Layer"
        Services[Services]
        Transactions[Transaction Management]
        BusinessLogic[Business Logic]
    end

    subgraph "Repository Layer"
        Repositories[Repositories]
        DataMappers[Data Mappers]
    end

    subgraph "Domain Layer"
        Entities[Domain Entities]
        Constants[Domain Constants]
        Schemas[Validation Schemas]
    end

    subgraph "Infrastructure Layer"
        DB[(Database)]
        Logging[Logging]
        ExternalAPIs[External APIs]
        Email[Email Service]
    end

    Browser --> Router
    Router --> Controllers
    Controllers --> Middlewares
    Controllers --> Validators
    Controllers --> Services
    Services --> BusinessLogic
    Services --> Transactions
    Services --> Repositories
    Repositories --> DataMappers
    Repositories --> DB
    Services --> Entities
    Services --> Constants
    Validators --> Schemas
    Services --> ExternalAPIs
    Services --> Email
    Controllers --> Logging
    Services --> Logging
    Repositories --> Logging

State Diagram

The following diagram shows the states of a requisition:

stateDiagram-v2
    [*] --> RS_Draft

    state RequisitionSlip_Status {
        RS_Draft --> For_RS_Approval: Submit
        For_RS_Approval --> Assigning: Fully Approved
        For_RS_Approval --> RS_Rejected: Reject
        RS_Rejected --> RS_Draft: Revise
        Assigning --> Assigned: Assign Purchasing
    }

    state fork_state <<fork>>
    Assigned --> fork_state: Enter Canvass

    state CanvassSheet_Status {
        fork_state --> CS_Draft
        fork_state --> RS_In_Progress
        CS_Draft --> For_CS_Approval: Submit
        For_CS_Approval --> CS_Approved: Fully Approved
        For_CS_Approval --> CS_Rejected: Reject
        CS_Rejected --> CS_Draft: Revise
        CS_Approved --> For_PO_Review: Generate PO
    }

    state PurchaseOrder_Status {
        For_PO_Review --> For_PO_Approval: Submit
        For_PO_Approval --> For_Sending: Fully Approved
        For_PO_Approval --> PO_Rejected: Reject
        PO_Rejected --> For_PO_Review: Revise
        For_Sending --> For_Delivery: Send to PO to supplier
    }

    For_Delivery --> RR_Draft: Create RR

    state ReceivingReport_Status{
        RR_Draft --> Delivered: Submit RR
    }

    Delivered --> IR_Draft: Create IR

    state InvoiceReport_Status{
        IR_Draft --> Invoice_Received: Submit IR
    }

    Invoice_Received --> PR_Draft: Create PR

    state PaymentRequest_Status{
        PR_Draft --> For_PR_Approval: Submit PR
        For_PR_Approval --> Closed: Fully Approved
        For_PR_Approval --> PR_Rejected: Reject
        PR_Rejected --> PR_Draft: Revise
    }

    state join_state <<join>>
    Delivered --> join_state: Fully delivered
    Closed --> join_state: Fully paid
    join_state --> Closed_PO: Both Ok

    state join_state2 <<join>>
    Closed_PO --> join_state2: All PO Closed
    RS_In_Progress --> join_state2: All item canvassed
    join_state2 --> Closed_RS: Both Ok

    Closed_RS --> [*]