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 --> [*]