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

139 lines
5.5 KiB
Markdown

# 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):
```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
_(เขียนเอง)_