# Changes — 2026-06-04 ## สรุป วันนี้เพิ่ม 2 feature ใหม่ใน `03-apiservice`: 1. **VOC Data endpoint** — รับข้อมูลข้อร้องเรียน (Voice of Customer) จาก programmatic client 2. **API Management page** — หน้าจัดการ API clients/keys ด้วย Keycloak admin auth แทน SQLAdmin basic auth เดิม --- ## Feature 1 — VOC Data Endpoint ### ไฟล์ที่แก้ไข | ไฟล์ | การเปลี่ยนแปลง | |------|----------------| | `app/api/v1/schemas.py` | เพิ่ม `VocDataIn` schema | | `app/db/models.py` | เพิ่ม `RawVocData` model (table: `rawdata.raw_voc_data`) | | `app/api/v1/routes.py` | เพิ่ม `POST /api/v1/voc-data` endpoint | ### Endpoint ``` POST /api/v1/voc-data Authorization: Bearer (permission required: voc.data:write) Content-Type: application/json ``` **Request body** (batch array): ```json [ { "date": "2026-06-04", "topic": "บริการพยาบาล", "sub_topic": "ความรวดเร็ว", "level": "3", "depart_id": "OPD01", "dep_name": "ผู้ป่วยนอก" } ] ``` **Response:** ```json { "inserted": 1, "rowcount": 1, "supabase": { "success": true, "result": {...}, "error": null } } ``` ### Database Table ```sql CREATE TABLE rawdata.raw_voc_data ( id BIGSERIAL PRIMARY KEY, date DATE NOT NULL, topic VARCHAR(200) NOT NULL, sub_topic VARCHAR(200) NOT NULL, level VARCHAR(50) NOT NULL, depart_id VARCHAR(50) NOT NULL, dep_name VARCHAR(200), created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); ``` - `id` เป็น BIGSERIAL auto-increment — server generate เอง, client ไม่ต้องส่ง - ทุก record ที่ส่งมาจะ INSERT เพิ่มเสมอ (ไม่มี upsert/on_conflict) - สร้าง table อัตโนมัติจาก `Base.metadata.create_all()` ตอน startup - Dual-write ไปยัง Supabase (`raw_voc_data` table) เหมือน endpoint อื่นๆ ### Deploy status ✅ Deploy แล้ว บน server .8 — table `rawdata.raw_voc_data` ถูกสร้างแล้ว --- ## Feature 2 — API Management Page (Keycloak auth) ### ปัญหาเดิม SQLAdmin panel (`/admin/`) ใช้ basic auth (username/password จาก `.env`) แยกต่างหากจาก Keycloak ซึ่งเป็น auth system หลักของระบบ ### การแก้ไข ปิด SQLAdmin และสร้างหน้าจัดการ API keys ใหม่ที่ใช้ Keycloak admin auth แทน ### ไฟล์ที่แก้ไข | ไฟล์ | การเปลี่ยนแปลง | |------|----------------| | `app/main.py` | ลบ SQLAdmin imports/mounts (`sqladmin`, statics, `mount_admin`) | | `app/admin.py` | Comment out `/admin` redirect route | | `app/middleware/auth_middleware.py` | เพิ่ม `/api-management`, `/admin/users` ใน `PROTECTED_PATHS` | | `app/routes/pages.py` | เพิ่ม `GET /api-management` route | | `app/templates/index.html` | เปลี่ยน link จาก `/admin/` → `/api-management` | ### ไฟล์ใหม่ | ไฟล์ | คำอธิบาย | |------|---------| | `app/routes/admin_api_keys.py` | REST endpoints สำหรับจัดการ API clients/keys (Keycloak admin auth) | | `app/templates/api_management.html` | หน้าจัดการ API clients และ keys | ### Endpoints ใหม่ (ทั้งหมดต้องการ Keycloak admin role) | Method | Path | คำอธิบาย | |--------|------|---------| | GET | `/admin/api-keys/clients` | List ทุก API client พร้อม nested keys | | POST | `/admin/api-keys/clients` | สร้าง API client ใหม่ | | POST | `/admin/api-keys/generate` | สร้าง API key (คืน plaintext ครั้งเดียว) | | POST | `/admin/api-keys/{id}/regenerate` | Regenerate key (คืน plaintext ครั้งเดียว) | | PATCH | `/admin/api-keys/{id}/toggle` | Toggle is_active | ### Features ของหน้า `/api-management` - Stats: จำนวน clients, total keys, active keys - สร้าง API Client พร้อมกำหนดชื่อ - สร้าง API Key พร้อมกำหนด permissions เป็น JSON array - แสดง plaintext key ใน modal ครั้งเดียวหลัง generate/regenerate พร้อมปุ่ม Copy - Activate/Deactivate key - เข้าถึงได้ที่ `https://ai.sriphat.com/apiservice/api-management` (ต้อง login ด้วย Keycloak admin account) ### Deploy status ⏳ ยังไม่ deploy — รอ review ก่อน --- ## Blockers / สิ่งที่ค้างอยู่ - **Airflow API token** ยังไม่ได้ config → Finance upload จะ set status=error หลัง upload สำเร็จ (ไฟล์อัปขึ้น MinIO ได้ แต่ trigger DAG ไม่ได้) - **VOC API key** — ยังต้องสร้าง ApiClient + ApiKey ที่มี permission `voc.data:write` สำหรับ client ที่จะส่งข้อมูล (ทำได้หลัง deploy Feature 2) --- ## 🧠 Decision & Lesson _(เขียนเอง)_