ภาพรวมแค็ตตาล็อก API
โน้ตนี้เป็นศูนย์กลาง (hub) ของมิติ "API catalog" ใน SML Brain: อธิบายว่าคำขอหนึ่งเดินทางผ่านอะไรบ้างตั้งแต่เบราว์เซอร์ถึงฐานข้อมูล, middleware ที่ครอบ, รูปแบบ response/error, ขีดจำกัด และดัชนีของโน้ต API ทั้ง 19 ฉบับ. รายละเอียดเชิงสถาปัตยกรรมอยู่ที่ ภาพรวม Backend Go ของ SML Ai Account (Backend overview), สถาปัตยกรรม Hexagonal และ composition root ของ Go backend (Hexagonal Architecture + DI), Router, middleware และแผนผัง route ทั้งหมดของ backend (chi router) และฝั่งหน้าเว็บที่ เส้นทาง API ฝั่ง Next.js ที่ส่งต่อไป Go backend (API proxy routes).
1. วงจรคำขอ (request lifecycle)
flowchart LR
C[เบราว์เซอร์ / แอป POS / ไคลเอนต์ MCP] --> N[Next.js route /api/...]
N --> G[Go chi router]
G --> M[middleware: RequestID, Recoverer, Timeout 60s, SecurityHeaders, RequestLogger]
M --> A[Auth / AdminAuth / RequireRight ต่อกลุ่ม]
A --> H[handler ใน adapter/inbound/http]
H --> S[service ใน application]
S --> D[(pgx pool ต่อบริษัท)]
| ขั้น | ทำอะไร | ที่มา |
|---|---|---|
| 1. ไคลเอนต์ | เว็บเรียก /api/... ของ Next (cookie session) ; แอป POS และ AI ภายนอกถือ token ของตัวเอง |
โน้ตแต่ละกลุ่ม |
| 2. Next proxy (BFF) | ตรวจ session (requireSession), ต่ออายุ/ขอ access token (getValidAccessToken), ส่งต่อไป Go ที่ SERVICE_BASE_URL ด้วย fetchServiceWithAuthRetry (ลองใหม่เมื่อ 401, เติม X-Admin-Api-Key ให้ endpoint ที่มี /admin), ห่อผลเป็น ok()/fail() |
frontend/src/lib/api-server.ts:34-51, 248, 388, 496, 555 |
| 3. Go router | chi router ลงทะเบียนกลุ่ม path ทั้งหมดไฟล์เดียว | backend/internal/adapter/inbound/http/router.go |
| 4. middleware global | RequestID -> Recoverer -> Timeout(60s) -> SecurityHeaders -> RequestLogger |
router.go:62-66 |
| 5. middleware ต่อกลุ่ม | Auth(verifier) อ่าน Authorization: Bearer, ตรวจ access token, ใส่ claims ลง context; AdminAuth(key) ตรวจ X-Admin-Api-Key แบบ constant-time; RequireRight ตรวจสิทธิ์เมนูตาม action |
middleware/auth.go:39, adminauth.go:11, permission.go |
| 6. handler | แปลง request, ดึง provider/database/user จาก claims (ไม่เชื่อค่าจาก body), เรียก service | adapter/inbound/http/<กลุ่ม>/handler.go |
| 7. service | ตรรกะธุรกิจ ใน application/* (query, process, identity, tenant ฯลฯ) |
backend/internal/application |
| 8. DB | pool แยกต่อบริษัท (ฐาน Main + ฐานบริษัท) ผ่านตัวจัดการ pool | ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager), โมเดลผู้เช่าหลายราย: Tenant, Provider, Main DB, Company (Multi-tenant model) |
หลักการสำคัญ: บริษัท/ผู้ใช้ที่ handler ใช้มาจาก JWT claims เสมอ (ดู JWT session token และการเพิกถอน (JWT + revocation store)) ดังนั้นไคลเอนต์เลือกบริษัทได้เฉพาะตอน select-company (API กลุ่ม /auth — ล็อกอิน เลือกบริษัท รีเฟรช ออกจากระบบ (Auth endpoints)).
2. แผนที่เส้นทางใน router.go
ฝั่ง Next มี route.ts ราว 75 ไฟล์ใต้ frontend/src/app/api/ (query, process/*, admin, auth, workspace, pos, mcp, โมดูลธุรกิจ และ route เฉพาะชั้น Next เช่น fraudwarning, workmonitor, help, lineoa, monitormap).
3. รูปแบบ response และ error
| ชั้น | สำเร็จ | ล้มเหลว | ที่มา |
|---|---|---|---|
| Go โมดูลธุรกิจ / query | JSON ดิบของผลลัพธ์ | {"error":{"message":"..."}} |
response/response.go:49-79 |
Go /process/* |
{"ok":true,"data":...} |
เหมือนข้างบน | API เครื่องยนต์ process /process/* — เส้นทาง สิทธิ์ ขนาดบอดี้ (Process engine run API) |
| Go admin / MCP tokens / POS | {"ok":true,"data":...} (POS บาง route {ok,section}) |
admin: {"ok":false,"error":"...","code":"..."}; POS ส่วนใหญ่ใช้ response.Error |
API คอนโซลผู้ดูแล /api/v1/admin — provider, user, database, main-query, menu-permissions (Admin console API), API จุดขาย POS (POS endpoints /api/v1/pos) |
| MCP JSON-RPC | result ใน JSON-RPC 2.0 |
error ใน HTTP 200 (ยกเว้น 401/405) |
API เซิร์ฟเวอร์ MCP แบบอ่านอย่างเดียว (MCP read-only gateway และการจัดการ token) |
| Next BFF | {ok:true,data} |
{ok:false,error,code} เช่น NO_TOKEN, NO_SESSION, BACKEND_UNAVAILABLE |
api-server.ts:34-51, 496-520 |
การแปลง apperr เป็นสถานะ HTTP: Validation=400, Unauthorized=401, Forbidden=403, NotFound=404, Conflict=409, อื่น ๆ=500 พร้อมข้อความ internal server error (ไม่เปิดเผยสาเหตุ) — รายละเอียดที่ รูปแบบ error และ response ของ API (apperr + response helper).
4. สรุปขีดจำกัดที่พบ
5. ดัชนีโน้ต API (19 ฉบับ)
6. ข้อสังเกตข้ามกลุ่ม (รวบรวมจากโน้ตย่อย)
- ค่าเงินในโมดูลธุรกิจเป็น float64 ขัดกับแนวปฏิบัติด้านเงิน/ความถูกต้องของข้อมูล (ความถูกต้องของข้อมูล: เงิน ภาษี Transaction เดียว และ Rebuild (Data Integrity, big.Rat, ExecBatch)).
- ชื่อบริษัท/tenant ไม่ถูกคัดลอกมาในโน้ต API; ใช้ placeholder เช่น
<token>,<provider>,<adminKey>แทน.
ที่มาในโค้ด
- backend/internal/adapter/inbound/http/router.go:62-66 (middleware global), :68-71, :73-84, :85-111, :114-123, :126-208, :211-247, :250-326, :329-349, :352-358, :360-371
- backend/internal/adapter/inbound/http/middleware/auth.go:39-61 (Auth), middleware/adminauth.go:11-28 (AdminAuth), middleware/permission.go (RequireRight)
- backend/internal/adapter/inbound/http/response/response.go:49-79 (รูปแบบ error)
- frontend/src/lib/api-server.ts:22 (SERVICE_BASE_URL), :34-51 (ok/fail), :248 (requireSession), :388 (fetchServiceWithAuthRetry), :496 (proxyToService), :555 (getValidAccessToken)
- frontend/src/app/api/**/route.ts (75 ไฟล์)