# 3.9 Logs Management (ประวัติการแก้ไข / Audit Log) --- title: 'Functional Requirements: Audit Log Management' version: 1.8.1 status: updated owner: Nattanin Peancharoen last_updated: 2026-03-24 related: - specs/01-requirements/01-01-objectives.md - specs/01-requirements/01-03-modules/01-03-00-index.md - specs/01-requirements/01-06-edge-cases-and-rules.md - specs/03-Data-and-Storage/03-01-data-dictionary.md - specs/01-requirements/01-02-business-rules/01-02-01-rbac-matrix.md - specs/06-Decision-Records/ADR-010-logging-monitoring.md --- ## 3.9.1. วัตถุประสงค์ Audit Log บันทึก **ทุก action สำคัญ** ในระบบ — ทั้ง CRUD เอกสาร, การ Login/Logout, เหตุการณ์ Security — เพื่อ Traceability, Compliance และการ Debug ในระบบ Production --- ## 3.9.2. โครงสร้างข้อมูล (Database Table) ใช้ตารางเดียว `audit_logs` ออกแบบสำหรับ **High-Volume Append-Only Write**: | Column | Type | หมายเหตุ | |---|---|---| | `audit_id` | BIGINT AUTO_INCREMENT | Primary Key (ร่วมกับ `created_at` เพื่อ Partition) | | `request_id` | VARCHAR(100) | Trace ID เชื่อมกับ Application Log (Distributed Tracing) | | `user_id` | INT | ผู้กระทำ (ไม่มี FK — ป้องกัน Partition constraint) | | `action` | VARCHAR(100) | รหัส action เช่น `rfa.create`, `login.success` | | `severity` | ENUM | `INFO` / `WARN` / `ERROR` / `CRITICAL` | | `entity_type` | VARCHAR(50) | Module/ตาราง เช่น `rfa`, `correspondence` | | `entity_id` | VARCHAR(50) | Primary ID ของ record ที่ได้รับผลกระทบ | | `details_json` | JSON | ข้อมูล Context เพิ่มเติม | | `ip_address` | VARCHAR(45) | IP Address ของผู้กระทำ | | `user_agent` | VARCHAR(255) | Browser/Client ของผู้กระทำ | | `created_at` | DATETIME | เวลาที่กระทำ | **Primary Key:** `(audit_id, created_at)` — รวม `created_at` เพื่อรองรับ **Partition Table** **ไม่มี FK** — ใช้ INDEX แทน เพื่อให้ Partition ทำงานได้ (MariaDB constraint) --- ## 3.9.3. Action Format รูปแบบ: `.` — เช่น: | action | ความหมาย | |---|---| | `login.success` / `login.failed` | เข้าสู่ระบบ | | `rfa.create` / `rfa.update` / `rfa.delete` | CRUD RFA | | `correspondence.create` / `correspondence.submit` | สร้าง / Submit Correspondence | | `circulation.create` / `circulation.close` / `circulation.force_close` | Circulation | | `drawing.upload` / `drawing.delete` | อัปโหลด / ลบ Drawing | | `file.virus_detected` | ClamAV พบ Virus | | `file.mime_mismatch` | MIME Type ไม่ตรง | | `user.deactivate` / `user.reactivate` | เปลี่ยนสถานะ User | --- ## 3.9.4. Severity | severity | ใช้เมื่อ | |---|---| | `INFO` | ทุก CRUD ปกติ, Login สำเร็จ | | `WARN` | Login ล้มเหลว, Re-assign Circulation | | `ERROR` | ระบบ Error, Failed Transaction | | `CRITICAL` | File Virus Detected, Force Close Circulation, Security Event | --- ## 3.9.5. Partitioning (Performance) `audit_logs` ใช้ **RANGE Partition by YEAR(created_at)**: ``` p_old → ก่อน 2024 p2024 → 2024 p2025 → 2025 ... p2030 → 2030 p_future → หลัง 2030 ``` - Query เฉพาะ Partition ที่เกี่ยวข้อง → ลด I/O อย่างมีนัยสำคัญ - Drop Partition เพื่อ Archive ข้อมูลเก่าได้โดยไม่กระทบ Production --- ## 3.9.6. RBAC | การกระทำ | Role ที่อนุญาต | |---|---| | ดู Audit Log ทั้งหมด | Superadmin, Org Admin (เฉพาะ org ตัวเอง) | | Export / Report | Superadmin | | ลบ Audit Log | **ห้ามลบ** — Append-Only เสมอ | --- ## 3.9.7. กรณีที่บันทึก Audit Log บังคับ | กรณี | severity | ระบุใน Edge Case | |---|---|---| | Cancel Correspondence ที่มี Circulation เปิด | `CRITICAL` | EC-CORR-001 | | Force Close Circulation + reason | `CRITICAL` | EC-CIRC-001, EC-CIRC-002 | | Re-assign Circulation (Assignee deactivated) | `WARN` | EC-CIRC-001 | | File Virus Detected (ClamAV) | `CRITICAL` | EC-FILE-001 | | File MIME Type Mismatch | `WARN` | EC-FILE-002 | | ทุก Login / Logout | `INFO` / `WARN` | — | | ทุก CRUD บน Document ทุกประเภท | `INFO` | — |