# **🧊 āđāļœāļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļšāļĢāļ°āļšāļš (Test Plan) \- DMS v1.3.0 Backend** āđ€āļ­āļāļŠāļēāļĢāļ™āļĩāđ‰āļŠāļĢāļļāļ›āđāļœāļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļš, āļ‚āļąāđ‰āļ™āļ•āļ­āļ™, āđāļĨāļ°āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­āļ—āļĩāđˆāđƒāļŠāđ‰āđƒāļ™āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āļ§āļēāļĄāļ–āļđāļāļ•āđ‰āļ­āļ‡āļ‚āļ­āļ‡ NestJS Backend API (DMS v1.3.0) āļāđˆāļ­āļ™āļāļēāļĢ Deploy āđƒāļŠāđ‰āļ‡āļēāļ™āļˆāļĢāļīāļ‡āļĢāđˆāļ§āļĄāļāļąāļš Frontend ## **1\. āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ (Objectives)** * āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļĄāļąāđˆāļ™āđƒāļˆāļ§āđˆāļē API āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļģāļ‡āļēāļ™āļ•āļĢāļ‡āļ•āļēāļĄ requirements.md * āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ§āđˆāļēāļĢāļ°āļšāļšāļĢāļąāļāļĐāļēāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ (RBAC āđāļĨāļ° Security) āļ—āļģāļ‡āļēāļ™āđ„āļ”āđ‰āļ–āļđāļāļ•āđ‰āļ­āļ‡ 100% * āđ€āļžāļ·āđˆāļ­āļ„āđ‰āļ™āļŦāļēāđāļĨāļ°āđāļāđ‰āđ„āļ‚āļ‚āđ‰āļ­āļšāļāļžāļĢāđˆāļ­āļ‡ (Bugs) āļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡āļāļąāļšāļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­āļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨāđāļĨāļ° Business Logic * āđ€āļžāļ·āđˆāļ­āļĒāļ·āļ™āļĒāļąāļ™āļ§āđˆāļēāļĢāļ°āļšāļšāļ—āļ™āļ—āļēāļ™āļ•āđˆāļ­āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™āļžāļĢāđ‰āļ­āļĄāļāļąāļ™ (Concurrency) āđāļĨāļ°āļĄāļĩāļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļž (Performance) * āđ€āļžāļ·āđˆāļ­āļŠāđˆāļ‡āļĄāļ­āļš API āļ—āļĩāđˆāđ€āļŠāļ–āļĩāļĒāļĢāđāļĨāļ°āļĄāļĩāđ€āļ­āļāļŠāļēāļĢ (Swagger) āļ„āļĢāļšāļ–āđ‰āļ§āļ™āđƒāļŦāđ‰āđāļāđˆāļ—āļĩāļĄ Frontend ## **2\. āļ‚āļ­āļšāđ€āļ‚āļ•āļāļēāļĢāļ—āļ”āļŠāļ­āļš (Scope)** ### **āļŠāļīāđˆāļ‡āļ—āļĩāđˆāļ­āļĒāļđāđˆāđƒāļ™āļ‚āļ­āļšāđ€āļ‚āļ• (In-Scope)** * **API Functionality:** āļāļēāļĢāļ—āļ”āļŠāļ­āļš Endpoints āļ—āļąāđ‰āļ‡āļŦāļĄāļ” (CRUD, Search, Upload) * **Business Logic:** āļ•āļĢāļĢāļāļ°āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ (RFA, Correspondence), āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆ, āđāļĨāļ° Workflow * **Security:** āļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™ (JWT), āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ—āļ˜āļīāđŒ (RBAC Guard), āļāļēāļĢāļ›āđ‰āļ­āļ‡āļāļąāļ™ (Helmet, Rate Limiter) * **Data Integrity:** āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āļ§āļēāļĄāļ–āļđāļāļ•āđ‰āļ­āļ‡āļ‚āļ­āļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāļšāļąāļ™āļ—āļķāļāļĨāļ‡ MariaDB * **Performance:** āļāļēāļĢāļ—āļ”āļŠāļ­āļš Concurrency (āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆ) āđāļĨāļ°āļāļēāļĢāļ•āļ­āļšāļŠāļ™āļ­āļ‡āļ‚āļ­āļ‡ API * **Error Handling:** āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ§āđˆāļē Global Exception Filter āļ—āļģāļ‡āļēāļ™āđ„āļ”āđ‰āļ–āļđāļāļ•āđ‰āļ­āļ‡ ### **āļŠāļīāđˆāļ‡āļ—āļĩāđˆāļ­āļĒāļđāđˆāļ™āļ­āļāļ‚āļ­āļšāđ€āļ‚āļ• (Out-of-Scope)** * āļāļēāļĢāļ—āļ”āļŠāļ­āļš Next.js Frontend (UI/UX) * āļāļēāļĢāļ—āļ”āļŠāļ­āļšāļ•āļĢāļĢāļāļ°āļ āļēāļĒāđƒāļ™āļ‚āļ­āļ‡ N8N (āđ€āļĢāļēāļ—āļ”āļŠāļ­āļšāđāļ„āđˆāļ§āđˆāļē Backend *āļĒāļīāļ‡* Webhook āđ„āļ›āļŦāļĢāļ·āļ­āđ„āļĄāđˆ) * āļāļēāļĢāļ—āļ”āļŠāļ­āļš Penetration Test āļ‚āļąāđ‰āļ™āļŠāļđāļ‡ (āđ€āļ™āđ‰āļ™ Functional & Security āļžāļ·āđ‰āļ™āļāļēāļ™) ## **3\. āļŠāļ āļēāļžāđāļ§āļ”āļĨāđ‰āļ­āļĄāđāļĨāļ°āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­ (Environment & Tools)** | āļ›āļĢāļ°āđ€āļ āļ— | āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­/āļŠāļ āļēāļžāđāļ§āļ”āļĨāđ‰āļ­āļĄ | āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ | | :---- | :---- | :---- | | **āļŠāļ āļēāļžāđāļ§āļ”āļĨāđ‰āļ­āļĄ** | **Staging (QNAP)** | āļŠāļ āļēāļžāđāļ§āļ”āļĨāđ‰āļ­āļĄāļˆāļģāļĨāļ­āļ‡ (āļšāļ™ Docker) āļ—āļĩāđˆāđ€āļŦāļĄāļ·āļ­āļ™ Production āļ—āļĩāđˆāļŠāļļāļ” āļ›āļĢāļ°āļāļ­āļšāļ”āđ‰āļ§āļĒ backend, mariadb, elasticsearch, n8n (Mock Receiver) | | **āļāļēāļ™āļ‚āđ‰āļ­āļĄāļđāļĨ** | **DBeaver** | āđƒāļŠāđ‰āļŠāļģāļŦāļĢāļąāļšāđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­ MariaDB (Staging) āđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļšāļœāļĨāļĨāļąāļžāļ˜āđŒ (Data Verification) | | **API (Manual)** | **Postman / Insomnia** | āđƒāļŠāđ‰āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ—āļ”āļŠāļ­āļš API āļ”āđ‰āļ§āļĒāļ•āļ™āđ€āļ­āļ‡, āļŠāļģāļĢāļ§āļˆ Endpoints, āđāļĨāļ°āļŠāļĢāđ‰āļēāļ‡ Test Case | | **API (Automation)** | **Postman (Newman) / Supertest** | (E2E) āđƒāļŠāđ‰āļĢāļąāļ™ Test Case āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļīāđ€āļžāļ·āđˆāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļš API Contract | | **Unit/Integration** | **Jest / @nestjs/testing** | (Developer) āđƒāļŠāđ‰āļŠāļģāļŦāļĢāļąāļšāļ—āļ”āļŠāļ­āļš Logic āļ āļēāļĒāđƒāļ™ Service āđāļĨāļ° Guard (āļ•āļēāļĄāļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡ spec.ts āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ„āļ§āđ‰) | | **Concurrency** | **k6 (āđāļ™āļ°āļ™āļģ) / Node.js Script** | āđƒāļŠāđ‰āļŠāļģāļŦāļĢāļąāļšāļ—āļ”āļŠāļ­āļš Stress Test āđāļĨāļ° Concurrency (āđ‚āļ”āļĒāđ€āļ‰āļžāļēāļ° TC-CON-01) | | **Webhook** | **N8N (Webhook Node)** | āđƒāļŠāđ‰ N8N āļˆāļĢāļīāļ‡ (Staging) āļ•āļąāđ‰āļ‡āļ„āđˆāļē Webhook Node āđ€āļžāļ·āđˆāļ­āļĢāļąāļš Event āļˆāļēāļ NotificationService | ## **4\. āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒāļ—āļ”āļŠāļ­āļš (Detailed Test Scenarios)** āļ™āļĩāđˆāļ„āļ·āļ­ Test Case āļ—āļĩāđˆāļŠāļģāļ„āļąāļāļ—āļĩāđˆāļŠāļļāļ” āđ‚āļ”āļĒāđāļšāđˆāļ‡āļ•āļēāļĄāļ„āļ§āļēāļĄāđ€āļŠāļĩāđˆāļĒāļ‡āđāļĨāļ° Function ### **T1: āļāļēāļĢāļĢāļąāļāļĐāļēāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ (Security & RBAC) \- (āļ„āļ§āļēāļĄāđ€āļŠāļĩāđˆāļĒāļ‡āļŠāļđāļ‡āļĄāļēāļ)** | ID | āļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒ | āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļš (Steps) | āļœāļĨāļĨāļąāļžāļ˜āđŒāļ—āļĩāđˆāļ„āļēāļ”āļŦāļ§āļąāļ‡ (Expected) | āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­ | | :---- | :---- | :---- | :---- | :---- | | **TC-SEC-01** | **(RBAC) āļŦāđ‰āļēāļĄ Viewer āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢ** | 1\. (Postman) āđ€āļĢāļĩāļĒāļ POST /api/v1/auth/login āļ”āđ‰āļ§āļĒ User "Viewer" 2\. āļ„āļąāļ”āļĨāļ­āļ access\_token 3\. āđ€āļĢāļĩāļĒāļ POST /api/v1/correspondence (āđƒāļ™ Auth Header) āļžāļĢāđ‰āļ­āļĄ Body āļ—āļĩāđˆāļ–āļđāļāļ•āđ‰āļ­āļ‡ | 403 Forbidden (RBACGuard āļ—āļģāļ‡āļēāļ™) | Postman | | **TC-SEC-02** | **(RBAC) Editor āļ‚āđ‰āļēāļĄ Project** | 1\. (Postman) Login User "Editor" āļ—āļĩāđˆāļĄāļĩāļŠāļīāļ—āļ˜āļīāđŒāđ€āļ‰āļžāļēāļ° Project A 2\. (DBeaver) āļŦāļē ID āđ€āļ­āļāļŠāļēāļĢ (āđ€āļŠāđˆāļ™ corr\_id: 99\) āļ—āļĩāđˆāļ­āļĒāļđāđˆāđƒāļ™ Project B 3\. (Postman) āđ€āļĢāļĩāļĒāļ GET /api/v1/correspondence/99 āļ”āđ‰āļ§āļĒ Token āļ‚āļ­āļ‡ Editor | 403 Forbidden āļŦāļĢāļ·āļ­ 404 Not Found | Postman, DBeaver | | **TC-SEC-03** | **(RBAC) Super Admin** | 1\. (Postman) Login User "Super Admin" 2\. āđ€āļĢāļĩāļĒāļ Endpoint āļ—āļĩāđˆāļˆāļģāļāļąāļ”āļŠāļīāļ—āļ˜āļīāđŒāļŠāļđāļ‡ (āđ€āļŠāđˆāļ™ POST /api/v1/admin/users) | 201 Created (Super Admin āļ•āđ‰āļ­āļ‡āļœāđˆāļēāļ™āļ—āļļāļāļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš) | Postman | | **TC-SEC-04** | **(Rate Limit) Brute-force** | 1\. (Postman Runner āļŦāļĢāļ·āļ­ k6) āļ•āļąāđ‰āļ‡āļ„āđˆāļēāđƒāļŦāđ‰āđ€āļĢāļĩāļĒāļ POST /api/v1/auth/login (āļ”āđ‰āļ§āļĒāļĢāļŦāļąāļŠāļœāđˆāļēāļ™āļœāļīāļ”) 110 āļ„āļĢāļąāđ‰āļ‡ (Limit āļ„āļ·āļ­ 100\) 2\. āļŠāļąāļ‡āđ€āļāļ•āļœāļĨāļĨāļąāļžāļ˜āđŒ | Request āļ—āļĩāđˆ 1-100: 401 Unauthorized Request āļ—āļĩāđˆ 101+: 429 Too Many Requests | k6, Postman | | **TC-SEC-05** | **(Security) Helmet** | 1\. (Postman) āđ€āļĢāļĩāļĒāļ Endpoint āđƒāļ”āļāđ‡āđ„āļ”āđ‰ (āđ€āļŠāđˆāļ™ GET /api/v1/health) 2\. āļ•āļĢāļ§āļˆāļŠāļ­āļš Response Headers | āļ•āđ‰āļ­āļ‡āļĄāļĩ Headers āđ€āļŠāđˆāļ™ X-Content-Type-Options: nosniff, Strict-Transport-Security, X-Frame-Options: SAMEORIGIN | Postman | ### **T2: āļ•āļĢāļĢāļāļ°āļŦāļĨāļąāļ (Core Logic & Concurrency) \- (āļ„āļ§āļēāļĄāđ€āļŠāļĩāđˆāļĒāļ‡āļŠāļđāļ‡)** | ID | āļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒ | āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļš (Steps) | āļœāļĨāļĨāļąāļžāļ˜āđŒāļ—āļĩāđˆāļ„āļēāļ”āļŦāļ§āļąāļ‡ (Expected) | āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­ | | :---- | :---- | :---- | :---- | :---- | | **TC-CON-01** | **(Concurrency) āļŠāļĢāđ‰āļēāļ‡āđ€āļĨāļ‚āļ—āļĩāđˆāđ€āļ­āļāļŠāļēāļĢ** | 1\. (k6/Script) āļŠāļĢāđ‰āļēāļ‡ Script āļ—āļĩāđˆāđ€āļĢāļĩāļĒāļ POST /api/v1/correspondence (āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāđƒāļŦāļĄāđˆ) 50 āļ„āļĢāļąāđ‰āļ‡ *āļžāļĢāđ‰āļ­āļĄāļāļąāļ™* (Simultaneously) 2\. (Postman) Login Admin 3\. (DBeaver) āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ•āļēāļĢāļēāļ‡ correspondences āđāļĨāļ° document\_number\_counters | 1\. Script āļ—āļąāđ‰āļ‡ 50 āļ„āļĢāļąāđ‰āļ‡āļŠāļģāđ€āļĢāđ‡āļˆ (201 Created) 2\. (DBeaver) document\_number\_counters āļĄāļĩ last\_number: 50 3\. correspondences āļĄāļĩāđ€āļ­āļāļŠāļēāļĢ 50 āļ‰āļšāļąāļš āđ‚āļ”āļĒ *āđ„āļĄāđˆāļĄāļĩ* correspondence\_number āļ‹āđ‰āļģāļāļąāļ™āđ€āļĨāļĒ | k6, DBeaver | | **TC-FUNC-01** | **(Data) āļŠāļĢāđ‰āļēāļ‡ RFA (Complex)** | 1\. (Postman) Login User (āđ€āļŠāđˆāļ™ "Editor") 2\. āđ€āļĢāļĩāļĒāļ POST /api/v1/rfa āļžāļĢāđ‰āļ­āļĄ DTO āļ—āļĩāđˆāļ‹āļąāļšāļ‹āđ‰āļ­āļ™ (āļĄāļĩ rfa\_type\_id, title, attachments, shop\_drawings) | 1\. 201 Created 2\. (DBeaver) āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ§āđˆāļēāļĄāļĩāļ‚āđ‰āļ­āļĄāļđāļĨāļ–āļđāļāļŠāļĢāđ‰āļēāļ‡āļ‚āļķāđ‰āļ™āđƒāļ™ 3 āļ•āļēāļĢāļēāļ‡āļŦāļĨāļąāļ: \- correspondences (āļ•āļēāļĢāļēāļ‡āđāļĄāđˆ) \- rfas (āļ•āļēāļĢāļēāļ‡āđāļĄāđˆ RFA) \- rfa\_revisions (āļ•āļēāļĢāļēāļ‡āļĨāļđāļ Revision 0\) | Postman, DBeaver | ### **T3: āļāļēāļĢāļ—āļģāļ‡āļēāļ™āļ‚āļ­āļ‡āđ‚āļĄāļ”āļđāļĨ (Module Functionality)** | ID | āļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒ | āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļš (Steps) | āļœāļĨāļĨāļąāļžāļ˜āđŒāļ—āļĩāđˆāļ„āļēāļ”āļŦāļ§āļąāļ‡ (Expected) | āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­ | | :---- | :---- | :---- | :---- | :---- | | **TC-FUNC-02** | **(File) āļ­āļąāļ›āđ‚āļŦāļĨāļ”āđ„āļŸāļĨāđŒ** | 1\. (Postman) Login User 2\. āđ€āļĢāļĩāļĒāļ POST /api/v1/files/upload (āļ›āļĢāļ°āđ€āļ āļ— form-data, key file) 3\. (DBeaver) āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ•āļēāļĢāļēāļ‡ attachments | 1\. 201 Created āļ„āļ·āļ™āļ„āđˆāļēāļ‚āđ‰āļ­āļĄāļđāļĨ Attachment (āđ€āļŠāđˆāļ™ ID, stored\_filename) 2\. (DBeaver) āļĄāļĩāđāļ–āļ§āđƒāļŦāļĄāđˆāđƒāļ™āļ•āļēāļĢāļēāļ‡ attachments 3\. (āļ–āđ‰āļēāļ—āļģāđ„āļ”āđ‰) āļ•āļĢāļ§āļˆāļŠāļ­āļš QNAP /share/dms-data/... āļ§āđˆāļēāļĄāļĩāđ„āļŸāļĨāđŒāļˆāļĢāļīāļ‡ | Postman, DBeaver | | **TC-FUNC-03** | **(File) āļ”āļēāļ§āļ™āđŒāđ‚āļŦāļĨāļ” (āļœāđˆāļēāļ™ Auth)** | 1\. (Postman) āļ—āļģ TC-FUNC-02 āđ€āļžāļ·āđˆāļ­āļ­āļąāļ›āđ‚āļŦāļĨāļ”āđ„āļŸāļĨāđŒ (āļŠāļĄāļĄāļ•āļīāđ„āļ”āđ‰ attachment\_id: 123\) 2\. āđ€āļĢāļĩāļĒāļ GET /api/v1/files/download/123 (āļ•āđ‰āļ­āļ‡āđƒāļŠāđˆ Auth Header) | 200 OK āđāļĨāļ°āđ„āļ”āđ‰āļ‚āđ‰āļ­āļĄāļđāļĨāđ„āļŸāļĨāđŒāļāļĨāļąāļšāļĄāļē | Postman | | **TC-FUNC-04** | **(Search) Elasticsearch** | 1\. (Postman) āļŠāļĢāđ‰āļēāļ‡āđ€āļ­āļāļŠāļēāļĢāđƒāļŦāļĄāđˆ POST /api/v1/correspondence (āļˆāļ”āļˆāļģ Title āđ„āļ§āđ‰) 2\. (āļĢāļ­ 10 āļ§āļīāļ™āļēāļ—āļĩ āđƒāļŦāđ‰ Elastic Index) 3\. āđ€āļĢāļĩāļĒāļ GET /api/v1/search?query=\[Title āļ—āļĩāđˆāļˆāļ”āđ„āļ§āđ‰\] | 200 OK āđāļĨāļ°āļœāļĨāļĨāļąāļžāļ˜āđŒāļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļ•āđ‰āļ­āļ‡āļĄāļĩāđ€āļ­āļāļŠāļēāļĢāļ—āļĩāđˆāđ€āļžāļīāđˆāļ‡āļŠāļĢāđ‰āļēāļ‡ | Postman | | **TC-FUNC-05** | **(Notification) N8N Webhook** | 1\. (N8N) āļŠāļĢāđ‰āļēāļ‡ Workflow āđƒāļŦāļĄāđˆ, āđƒāļŠāđ‰ "Webhook" Node (āđ€āļ›āļīāļ” Test Mode) 2\. (Postman) Login User 3\. āđ€āļĢāļĩāļĒāļ POST /api/v1/circulation (āļŠāļĢāđ‰āļēāļ‡āđƒāļšāđ€āļ§āļĩāļĒāļ™āđƒāļŦāļĄāđˆ) | 1\. (Postman) 201 Created 2\. (N8N) Webhook Node āđ„āļ”āđ‰āļĢāļąāļšāļ‚āđ‰āļ­āļĄāļđāļĨ Payload ({ event: 'NEW\_CIRCULATION\_TASK', ... }) | Postman, N8N | | **TC-FUNC-06** | **(Audit) Audit Log** | 1\. (Postman) Login Admin 2\. āđ€āļĢāļĩāļĒāļ DELETE /api/v1/admin/roles/10 (āļĨāļš Role āļŠāļĄāļĄāļ•āļī) 3\. (DBeaver) āļ•āļĢāļ§āļˆāļŠāļ­āļš audit\_logs | 1\. (DBeaver) āļĄāļĩāđāļ–āļ§āđƒāļŦāļĄāđˆāđƒāļ™ audit\_logs 2\. āļ‚āđ‰āļ­āļĄāļđāļĨāļ–āļđāļāļ•āđ‰āļ­āļ‡: action: 'role.delete', entity\_type: 'role', entity\_id: '10', user\_id: \[Admin ID\] | Postman, DBeaver | ### **T4: āļāļēāļĢ Deploy (NFR)** | ID | āļŠāļ–āļēāļ™āļāļēāļĢāļ“āđŒ | āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļš (Steps) | āļœāļĨāļĨāļąāļžāļ˜āđŒāļ—āļĩāđˆāļ„āļēāļ”āļŦāļ§āļąāļ‡ (Expected) | āđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļĄāļ·āļ­ | | :---- | :---- | :---- | :---- | :---- | | **TC-NFR-01** | **(Health) Health Check** | 1\. (Browser/Postman) āđ€āļĢāļĩāļĒāļ GET /api/v1/health (āļˆāļēāļ Staging URL) | 200 OK āđāļĨāļ° JSON Response āđāļŠāļ”āļ‡ status: "ok" āđāļĨāļ°āļŠāļ–āļēāļ™āļ° DB | Postman, Browser | | **TC-NFR-02** | **(Error) Global Filter** | 1\. (Postman) āđ€āļĢāļĩāļĒāļ Endpoint āļ—āļĩāđˆāđ„āļĄāđˆāļĄāļĩāļ­āļĒāļđāđˆāļˆāļĢāļīāļ‡ (āđ€āļŠāđˆāļ™ GET /api/v1/invalid\_path) | 404 Not Found Response Body āļ•āđ‰āļ­āļ‡āļĄāļĩāđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡ JSON āļ—āļĩāđˆāļāļģāļŦāļ™āļ”āđ„āļ§āđ‰ (āđ€āļŠāđˆāļ™ { "statusCode": 404, "message": "Cannot GET /api/v1/invalid\_path", ... }) | Postman |