# 🛠ïļ Section 2: System Architecture (āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄāđāļĨāļ°āđ€āļ—āļ„āđ‚āļ™āđ‚āļĨāļĒāļĩ) --- title: 'System Architecture' version: 1.5.0 status: first-draft owner: Nattanin Peancharoen last_updated: 2025-11-30 related: - specs/01-objectives.md --- āļŠāļ·āđˆāļ­āļāļģāļŦāļ™āļ” āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄāđāļšāļš Headless/API-First āļ—āļĩāđˆāļ—āļąāļ™āļŠāļĄāļąāļĒ āļ—āļģāļ‡āļēāļ™āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļšāļ™ QNAP Server āļœāđˆāļēāļ™ Container Station āđ€āļžāļ·āđˆāļ­āļ„āļ§āļēāļĄāļŠāļ°āļ”āļ§āļāđƒāļ™āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāđāļĨāļ°āļšāļģāļĢāļļāļ‡āļĢāļąāļāļĐāļē ## **2.1 Infrastructure & Environment:** - Domain: `np-dms.work`, `www.np-dms.work` - IP: 159.192.126.103 - Server: QNAP (Model: TS-473A, RAM: 32GB, CPU: AMD Ryzen V1500B) - Containerization: Container Station (Docker & Docker Compose) āđƒāļŠāđ‰ UI āļ‚āļ­āļ‡ Container Station āđ€āļ›āđ‡āļ™āļŦāļĨāļąāļ āđƒāļ™āļāļēāļĢ configuration āđāļĨāļ°āļāļēāļĢāļĢāļąāļ™ docker command - Development Environment: VS Code/Cursor on Windows 11 - Data Storage: /share/dms-data āļšāļ™ QNAP - āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”: āđ„āļĄāđˆāļŠāļēāļĄāļēāļĢāļ–āđƒāļŠāđ‰ .env āđƒāļ™āļāļēāļĢāļāļģāļŦāļ™āļ”āļ•āļąāļ§āđāļ›āļĢāļ āļēāļĒāļ™āļ­āļāđ„āļ”āđ‰ āļ•āđ‰āļ­āļ‡āļāļģāļŦāļ™āļ”āđƒāļ™ docker-compose.yml āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™ ## **2.2 āļāļēāļĢāļˆāļąāļ”āļāļēāļĢ Configuration (āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡):** - āđƒāļŠāđ‰ docker-compose.yml āļŠāļģāļŦāļĢāļąāļš environment variables āļ•āļēāļĄāļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ‚āļ­āļ‡ QNAP - Secrets Management: - āļŦāđ‰āļēāļĄāļĢāļ°āļšāļļ Sensitive Secrets (Password, Keys) āđƒāļ™ docker-compose.yml āļŦāļĨāļąāļ - āļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰āđ„āļŸāļĨāđŒ docker-compose.override.yml (āļ—āļĩāđˆāļ–āļđāļ gitignore) āļŠāļģāļŦāļĢāļąāļš Inject Environment Variables āļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ„āļ§āļēāļĄāļĨāļąāļšāđƒāļ™āđāļ•āđˆāļĨāļ° Environment (Dev/Prod) - āđ„āļŸāļĨāđŒ docker-compose.yml āļŦāļĨāļąāļāđƒāļŦāđ‰āđƒāļŠāđˆāļ„āđˆāļē Dummy āļŦāļĢāļ·āļ­āļ§āđˆāļēāļ‡āđ„āļ§āđ‰ - āđāļ•āđˆāļ•āđ‰āļ­āļ‡āļĄāļĩ mechanism āļŠāļģāļŦāļĢāļąāļšāļˆāļąāļ”āļāļēāļĢ sensitive secrets āļ­āļĒāđˆāļēāļ‡āļ›āļĨāļ­āļ”āļ āļąāļĒ āđ‚āļ”āļĒāđƒāļŠāđ‰: - Docker secrets (āļ–āđ‰āļēāļĢāļ­āļ‡āļĢāļąāļš) - External secret management (Hashicorp Vault) āļŦāļĢāļ·āļ­ - Encrypted environment variables - Development environment āļĒāļąāļ‡āđƒāļŠāđ‰ .env āđ„āļ”āđ‰ āđāļ•āđˆāļ•āđ‰āļ­āļ‡āđ„āļĄāđˆ commit āđ€āļ‚āđ‰āļē version control - āļ•āđ‰āļ­āļ‡āļĄāļĩ configuration validation during application startup - āļ•āđ‰āļ­āļ‡āđāļĒāļ configuration āļ•āļēāļĄ environment (development, staging, production) - Docker Network: āļ—āļļāļ Service āļˆāļ°āđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­āļœāđˆāļēāļ™āđ€āļ„āļĢāļ·āļ­āļ‚āđˆāļēāļĒāļāļĨāļēāļ‡āļŠāļ·āđˆāļ­ lcbp3 āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļŠāļēāļĄāļēāļĢāļ–āļŠāļ·āđˆāļ­āļŠāļēāļĢāļāļąāļ™āđ„āļ”āđ‰ ## **2.3 Core Services:** - Code Hosting: Gitea (Self-hosted on QNAP) - Application name: git - Service name: gitea - Domain: git.np-dms.work - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āđ€āļ›āđ‡āļ™āļĻāļđāļ™āļĒāđŒāļāļĨāļēāļ‡āđƒāļ™āļāļēāļĢāđ€āļāđ‡āļšāđāļĨāļ°āļˆāļąāļ”āļāļēāļĢāđ€āļ§āļ­āļĢāđŒāļŠāļąāļ™āļ‚āļ­āļ‡āđ‚āļ„āđ‰āļ” (Source Code) āļŠāļģāļŦāļĢāļąāļšāļ—āļļāļāļŠāđˆāļ§āļ™ - Backend / Data Platform: NestJS - Application name: lcbp3-backend - Service name: backend - Domain: backend.np-dms.work - Framework: NestJS (Node.js, TypeScript, ESM) - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āļˆāļąāļ”āļāļēāļĢāđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ (Data Models), āļŠāļĢāđ‰āļēāļ‡ API, āļˆāļąāļ”āļāļēāļĢāļŠāļīāļ—āļ˜āļīāđŒāļœāļđāđ‰āđƒāļŠāđ‰ (Roles & Permissions), āđāļĨāļ°āļŠāļĢāđ‰āļēāļ‡ Workflow āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ‚āļ­āļ‡āļĢāļ°āļšāļš - Database: MariaDB 11.8 - Application name: lcbp3-db - Service name: mariadb - Domain: db.np-dms.work - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļĨāļąāļāļŠāļģāļŦāļĢāļąāļšāđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļąāđ‰āļ‡āļŦāļĄāļ” - Tooling: DBeaver (Community Edition), phpmyadmin āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ­āļ­āļāđāļšāļšāđāļĨāļ°āļˆāļąāļ”āļāļēāļĢāļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ - Database Management: phpMyAdmin - Application name: lcbp3-db - Service: phpmyadmin:5-apache - Service name: pma - Domain: pma.np-dms.work - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āļˆāļąāļ”āļāļēāļĢāļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ mariadb āļœāđˆāļēāļ™ Web UI - Frontend: Next.js - Application name: lcbp3-frontend - Service name: frontend - Domain: lcbp3.np-dms.work - Framework: Next.js (App Router, React, TypeScript, ESM) - Styling: Tailwind CSS + PostCSS - Component Library: shadcn/ui - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āļŠāļĢāđ‰āļēāļ‡āļŦāļ™āđ‰āļēāļ•āļēāđ€āļ§āđ‡āļšāđāļ­āļ›āļžāļĨāļīāđ€āļ„āļŠāļąāļ™āļŠāļģāļŦāļĢāļąāļšāđƒāļŦāđ‰āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āđ€āļ‚āđ‰āļēāļĄāļēāļ”āļđ Dashboard, āļˆāļąāļ”āļāļēāļĢāđ€āļ­āļāļŠāļēāļĢ, āđāļĨāļ°āļ•āļīāļ”āļ•āļēāļĄāļ‡āļēāļ™ āđ‚āļ”āļĒāļˆāļ°āļŠāļ·āđˆāļ­āļŠāļēāļĢāļāļąāļš Backend āļœāđˆāļēāļ™ API - Workflow Automation: n8n - Application name: lcbp3-n8n - Service: n8nio/n8n:latest - Service name: n8n - Domain: n8n.np-dms.work - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āļˆāļąāļ”āļāļēāļĢ workflow āļĢāļ°āļŦāļ§āđˆāļēāļ‡ Backend āđāļĨāļ° Line - Reverse Proxy: Nginx Proxy Manager - Application name: lcbp3-npm - Service: Nginx Proxy Manager (nginx-proxy-manage: latest) - Service name: npm - Domain: npm.np-dms.work - āļŦāļ™āđ‰āļēāļ—āļĩāđˆ: āđ€āļ›āđ‡āļ™āļ”āđˆāļēāļ™āļŦāļ™āđ‰āļēāđƒāļ™āļāļēāļĢāļĢāļąāļš-āļŠāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ āļˆāļąāļ”āļāļēāļĢāđ‚āļ”āđ€āļĄāļ™āļ—āļąāđ‰āļ‡āļŦāļĄāļ”, āļ—āļģāļŦāļ™āđ‰āļēāļ—āļĩāđˆāđ€āļ›āđ‡āļ™ Proxy āļŠāļĩāđ‰āđ„āļ›āļĒāļąāļ‡ Service āļ—āļĩāđˆāļ–āļđāļāļ•āđ‰āļ­āļ‡, āđāļĨāļ°āļˆāļąāļ”āļāļēāļĢ SSL Certificate (HTTPS) āđƒāļŦāđ‰āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī - Search Engine: Elasticsearch - Cache: Redis ## **2.4 Business Logic & Consistency (āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡):** - 2.4.1 Unified Workflow Engine (āļŦāļĨāļąāļ): - āļĢāļ°āļšāļšāļāļēāļĢāđ€āļ”āļīāļ™āđ€āļ­āļāļŠāļēāļĢāļ—āļąāđ‰āļ‡āļŦāļĄāļ” (Correspondence, RFA, Circulation) āļ•āđ‰āļ­āļ‡ āđƒāļŠāđ‰ Engine āļāļĨāļēāļ‡āđ€āļ”āļĩāļĒāļ§āļāļąāļ™ āđ‚āļ”āļĒāļāļģāļŦāļ™āļ” Logic āļœāđˆāļēāļ™ Workflow DSL (JSON Configuration) āđāļ—āļ™āļāļēāļĢāđ€āļ‚āļĩāļĒāļ™ Hard-coded āļĨāļ‡āđƒāļ™āļ•āļēāļĢāļēāļ‡ - Workflow Versioning (āđ€āļžāļīāđˆāļĄ): āļĢāļ°āļšāļšāļ•āđ‰āļ­āļ‡āļĢāļ­āļ‡āļĢāļąāļšāļāļēāļĢāļāļģāļŦāļ™āļ” Version āļ‚āļ­āļ‡ Workflow Definition āđ‚āļ”āļĒāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđ€āļĢāļīāđˆāļĄāļāļĢāļ°āļšāļ§āļ™āļāļēāļĢāđ„āļ›āđāļĨāđ‰āļ§ (In-progress instances) āļˆāļ°āļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰ Workflow Version āđ€āļ”āļīāļĄ āļˆāļ™āļāļ§āđˆāļēāļˆāļ°āļŠāļīāđ‰āļ™āļŠāļļāļ”āļāļĢāļ°āļšāļ§āļ™āļāļēāļĢ āļŦāļĢāļ·āļ­āđ„āļ”āđ‰āļĢāļąāļšāļ„āļģāļŠāļąāđˆāļ‡ Migrate āļˆāļēāļ Admin āđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™āļ„āļ§āļēāļĄāļ‚āļąāļ”āđāļĒāđ‰āļ‡āļ‚āļ­āļ‡ State - 2.4.2 Separation of Concerns: - Module āļ•āđˆāļēāļ‡āđ† (Correspondence, RFA, Circulation) āļˆāļ°āđ€āļāđ‡āļšāđ€āļ‰āļžāļēāļ°āļ‚āđ‰āļ­āļĄāļđāļĨāļ‚āļ­āļ‡āđ€āļ­āļāļŠāļēāļĢ (Data) āļŠāđˆāļ§āļ™āļŠāļ–āļēāļ™āļ°āđāļĨāļ°āļāļēāļĢāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļŠāļ–āļēāļ™āļ° (State Transition) āļˆāļ°āļ–āļđāļāļˆāļąāļ”āļāļēāļĢāđ‚āļ”āļĒ Workflow Engine - 2.4.3 Idempotency & Locking: - āđƒāļŠāđ‰āļāļĨāđ„āļāđ€āļ”āļīāļĄāđƒāļ™āļāļēāļĢāļ›āđ‰āļ­āļ‡āļāļąāļ™āļāļēāļĢāļ—āļģāļĢāļēāļĒāļāļēāļĢāļ‹āđ‰āļģ - 2.4.4 Optimistic Locking: - āđƒāļŠāđ‰ Version Column āđƒāļ™ Database āļ„āļ§āļšāļ„āļđāđˆāļāļąāļš Redis Lock āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ āđ€āļžāļ·āđˆāļ­āđ€āļ›āđ‡āļ™ Safety Net āļŠāļąāđ‰āļ™āļŠāļļāļ”āļ—āđ‰āļēāļĒ - 2.4.5 āļˆāļ°āđ„āļĄāđˆāļĄāļĩāļāļēāļĢāđƒāļŠāđ‰ SQL Triggers - āđ€āļžāļ·āđˆāļ­āļ›āđ‰āļ­āļ‡āļāļąāļ™āļ•āļĢāļĢāļāļ°āļ‹āđˆāļ­āļ™āđ€āļĢāđ‰āļ™ (Hidden Logic) āđāļĨāļ°āļ„āļ§āļēāļĄāļ‹āļąāļšāļ‹āđ‰āļ­āļ™āđƒāļ™āļāļēāļĢāļ”āļĩāļšāļąāļ ## **2.5 Data Migration āđāļĨāļ° Schema Versioning:** - āļ•āđ‰āļ­āļ‡āļĄāļĩ database migration scripts āļŠāļģāļŦāļĢāļąāļšāļ—āļļāļ schema change āđ‚āļ”āļĒāđƒāļŠāđ‰ TypeORM migrations - āļ•āđ‰āļ­āļ‡āļĢāļ­āļ‡āļĢāļąāļš rollback āļ‚āļ­āļ‡ migration āđ„āļ”āđ‰ - āļ•āđ‰āļ­āļ‡āļĄāļĩ data seeding strategy āļŠāļģāļŦāļĢāļąāļš environment āļ•āđˆāļēāļ‡āđ† (development, staging, production) - āļ•āđ‰āļ­āļ‡āļĄāļĩ version compatibility between schema versions - Migration scripts āļ•āđ‰āļ­āļ‡āļœāđˆāļēāļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļšāđƒāļ™ staging environment āļāđˆāļ­āļ™ production - āļ•āđ‰āļ­āļ‡āļĄāļĩ database backup āļāđˆāļ­āļ™āļ—āļģ migration āđƒāļ™ production ## **2.6 āļāļĨāļĒāļļāļ—āļ˜āđŒāļ„āļ§āļēāļĄāļ—āļ™āļ—āļēāļ™āđāļĨāļ°āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļœāļīāļ”āļžāļĨāļēāļ” (Resilience & Error Handling Strategy)** - 2.6.1 Circuit Breaker Pattern: āđƒāļŠāđ‰āļŠāļģāļŦāļĢāļąāļš external service calls (Email, LINE, Elasticsearch) - 2.6.2 Retry Mechanism: āļ”āđ‰āļ§āļĒ exponential backoff āļŠāļģāļŦāļĢāļąāļš transient failures - 2.6.3 Fallback Strategies: Graceful degradation āđ€āļĄāļ·āđˆāļ­āļšāļĢāļīāļāļēāļĢāļ āļēāļĒāļ™āļ­āļāļĨāđ‰āļĄāđ€āļŦāļĨāļ§ - 2.6.4 Error Handling: Error messages āļ•āđ‰āļ­āļ‡āđ„āļĄāđˆāđ€āļ›āļīāļ”āđ€āļœāļĒāļ‚āđ‰āļ­āļĄāļđāļĨ sensitive - 2.6.5 Monitoring: Centralized error monitoring āđāļĨāļ° alerting system