Files
sriphat-dataplatform/03-apiservice/CHANGES-2026-06-04.md
jigoong 3a5f9e9001 feat: replace SQLAdmin with Keycloak-protected API management page
- Disable SQLAdmin basic auth (comment out mount_admin, statics, redirect)
- Add /api-management page (Keycloak admin role required)
- Add admin_api_keys.py: REST endpoints for list/create clients and keys
- Add api_management.html: manage API clients, keys, permissions with copy-once key display
- Update index.html: API Management link -> /api-management
- Update auth middleware: add /api-management and /admin/users to PROTECTED_PATHS
- Add CHANGES-2026-06-04.md dev notes
2026-06-04 18:22:22 +07:00

5.5 KiB

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 <api-key>  (permission required: voc.data:write)
Content-Type: application/json

Request body (batch array):

[
  {
    "date": "2026-06-04",
    "topic": "บริการพยาบาล",
    "sub_topic": "ความรวดเร็ว",
    "level": "3",
    "depart_id": "OPD01",
    "dep_name": "ผู้ป่วยนอก"
  }
]

Response:

{
  "inserted": 1,
  "rowcount": 1,
  "supabase": { "success": true, "result": {...}, "error": null }
}

Database Table

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

(เขียนเอง)