ภาพรวม Backend Go (d:\smlaiaccount\backend)
Backend ของ SML Ai Account เป็นเซอร์วิส Go เดียว (โมดูล github.com/smlsoft/smlaiaccountapi, go 1.26.0) แบบ hexagonal: HTTP (chi v5) → use case → port → adapter ที่ต่อ PostgreSQL (pgx v5) / MinIO / ไฟล์ JSON. ระบบเป็น multi-tenant: หนึ่ง Provider มีฐานหลักของตัวเอง และแต่ละบริษัทมีฐานข้อมูลแยก. โน้ตชุดนี้ครอบคลุมแกนกลาง ยกเว้น internal/application/process (เอนจินเอกสารบัญชี → ภาพรวมกลุ่ม process ของ Backend (Process overview)).
ทำงานอย่างไร
ชั้นของระบบ (ดู สถาปัตยกรรม Hexagonal และ composition root ของ Go backend (Hexagonal Architecture + DI))
cmd— จุดเริ่มต้นและวงจรชีวิตเซอร์วิส (รันเป็น service ข้าม OS ด้วย kardianos/service) → วงจรชีวิตเซอร์วิสและการรัน binary เดียวหลาย OS (Service lifecycle).internal/di— composition root สร้างทุกชิ้นแล้วต่อสายกัน (di/container.go:62) → สถาปัตยกรรม Hexagonal และ composition root ของ Go backend (Hexagonal Architecture + DI).internal/adapter/inbound/http— router, middleware, handler ของแต่ละโมดูล. router ใส่Timeout(60s)และSecurityHeadersให้ทุกคำขอ (router.go:64-65) → Router, middleware และแผนผัง route ทั้งหมดของ backend (chi router).internal/application— use case:identity,tenant,blob,query(ในขอบเขตโน้ตนี้) และprocess(อีกชุด).internal/domain+ port — โครงสร้างและ interface ที่ชั้นนอกต้อง implement.internal/adapter/outbound— PostgreSQL, ไฟล์ registry, ที่เก็บ revocation, MinIO.internal/platform— ของกลาง:apperr,config,db(pool),docno,sqllit,search,security,httpserver,logger→ เครื่องมือกลาง platform: docno, sqllit, search, security (Platform utilities), รูปแบบ error และ response ของ API (apperr + response helper), ตัวแปรสภาพแวดล้อมและการโหลด config ของ backend (Environment config), ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager).
การไหลของคำขอหลัก
- เข้าสู่ระบบ:
{provider, dataGroup, username, password}→ หา Provider จาก registry → ต่อฐานหลัก/ฐานบริษัทของผู้เช่านั้น → ตรวจรหัสผ่าน (bcrypt หรือ plaintext เดิม) → ออก JWT HS256 → ขั้นตอน login / เลือกบริษัท / refresh / logout (Identity login flow), JWT session token และการเพิกถอน (JWT + revocation store). - ผู้เช่า: Provider Code
^[A-Z0-9]{2,20}$; ฐานหลัก ="smlerpmain"+lower(code)(คำนวณจากสูตร ไม่เก็บ); ฐานบริษัท = ค่าdata_database_name→ โมเดลผู้เช่าหลายราย: Tenant, Provider, Main DB, Company (Multi-tenant model), ทะเบียน Provider แบบไฟล์ JSON (Provider registry). - สิทธิ์: อ่านสิทธิ์เมนูจาก
image_file(JSON หรือ XML เดิมของ C#) แล้วบังคับด้วยRequireRight; admin =superadminหรือ level ≥ 9 → สิทธิ์เมนูและ middleware RequireRight (Menu rights / permission). - อ่าน/เขียนข้อมูลทั่วไป: ผ่าน Query Gateway (
/query/list|exec|execBatch) ซึ่งอ่านใน transaction read-only และจำกัดจำนวนแถว/ขนาด; ฝั่งเขียนมีนโยบายล็อกตารางเงิน/สต็อก/GL → Query Gateway: /query/list, limit, batch, exec, execBatch, นโยบายล็อกการเขียนผ่าน Query Gateway (Query write policy / lockdown). - รูปภาพ:
POST /blob/insertรับ multipart แล้วเก็บใน MinIO พร้อมภาพย่อ ฐานข้อมูลเก็บเพียง URL → แทรกแถวพร้อมรูปภาพ: POST /blob/insert + MinIO (Blob insert). - ฐานข้อมูล:
PoolManagerเปิด pool ต่อ (host, port, user, db) และรัน DDL ช่วย (companySchemaSQL,platform/db/pool.go:16) ทุกครั้งที่เปิด pool ใหม่ → ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager).
ส่วนจัดการ/เชื่อมภายนอก
- Admin API
/api/v1/admin/*(ยืนยันด้วย headerX-Admin-Api-Keyเทียบ envADMIN_API_KEY) → Admin API สำหรับจัดการ Provider/ผู้ใช้/ฐานข้อมูล/สิทธิ์เมนู (Admin API). - Workspace Google — ล็อกอินด้วยอีเมล สร้าง/เลือกบริษัท → Workspace Google: ล็อกอินด้วยอีเมล สร้างบริษัทใหม่ สมาชิก และผูก LINE (Workspace Google API).
- POS Sync — เครื่อง POS ดึง bootstrap/ส่งบิล/อัปโหลดสลิป ด้วย device token หรือ JWT ผู้ใช้ → POS Sync API: เครื่อง POS เชื่อมกับ Account (POS device sync).
การปล่อยระบบ
- Docker, Kubernetes,
Makefile(build/test/vet/lint — ไม่มีเป้าหมาย migrate) → การ build และ deploy backend: Docker, Kubernetes, Makefile (Deployment). - ไฟล์ SQL เดียวใน
migrations/ไม่มีตัวรัน; ตารางจริงถูกสร้างตอนรันโดยโค้ด Go → ไฟล์ migration และการสร้างตารางตอนรัน (Migrations / runtime DDL).
สารบัญโน้ต backend (ครบทุกไฟล์)
การตัดสินใจเชิงสถาปัตยกรรม 11 ข้อ (ADR-0001 ถึง 0011) อยู่ที่ สารบัญ ADR ของ backend (Architecture Decision Records).
ข้อควรระวังระดับระบบ
- ADR/เอกสารบางส่วนล้าสมัย — ให้ถือโค้ดเป็นความจริง: ที่เก็บ revocation เป็นไฟล์ (ไม่ใช่ตามที่ ADR-0004 เดิมบอก),
/query/execมีจริง, รูปภาพใช้ MinIO (ไม่ใช่ bytea), รหัสผ่านรองรับ bcrypt, README/PLAN เรื่องgolang-migrateไม่มีในgo.mod(README.md:85). - ออกแบบเป็นอินสแตนซ์เดียว: registry และ revocation store เป็นไฟล์พร้อม mutex ในโปรเซส — แต่ manifest K8s ตั้ง
replicas: 2(ยังไม่ยืนยันว่าแชร์ volume กัน) → ทะเบียน Provider แบบไฟล์ JSON (Provider registry), JWT session token และการเพิกถอน (JWT + revocation store), การ build และ deploy backend: Docker, Kubernetes, Makefile (Deployment). - ไม่มี rate limiter และไม่มี CORS ในโค้ด;
StatusSuspendedของ Provider ไม่ถูกบังคับใช้ → Router, middleware และแผนผัง route ทั้งหมดของ backend (chi router), โมเดลผู้เช่าหลายราย: Tenant, Provider, Main DB, Company (Multi-tenant model). - Admin/Workspace เชื่อใจข้อมูลที่ผู้เรียกส่งมา:
select-dbออก JWT จากอีเมล/รหัสผู้ใช้ที่ผู้เรียกระบุ, โหมดexecของMainQueryข้ามนโยบายเขียน → Admin API สำหรับจัดการ Provider/ผู้ใช้/ฐานข้อมูล/สิทธิ์เมนู (Admin API), Workspace Google: ล็อกอินด้วยอีเมล สร้างบริษัทใหม่ สมาชิก และผูก LINE (Workspace Google API), นโยบายล็อกการเขียนผ่าน Query Gateway (Query write policy / lockdown). - POS route แบบ
UserOnlyไม่ผ่านRequireRight(ยังไม่ยืนยันว่าฝั่ง frontend กั้นไว้หรือไม่) → POS Sync API: เครื่อง POS เชื่อมกับ Account (POS device sync). - เงิน:
sqllit.Literalพิมพ์float64เป็นทศนิยมฐานสอง — ส่งยอดเงินเป็นสตริงทศนิยมแทน → เครื่องมือกลาง platform: docno, sqllit, search, security (Platform utilities). - schema ในไฟล์ SQL กับ DDL ในโค้ด Go ไม่ตรงกัน (เช่น
cache_keyกับtile_key) → ไฟล์ migration และการสร้างตารางตอนรัน (Migrations / runtime DDL).
ที่มาในโค้ด
backend/internal/di/container.go:62— composition root.backend/internal/adapter/inbound/http/router.go:64-65— middleware ระดับ router.backend/internal/platform/db/pool.go:16—companySchemaSQLที่รันตอนเปิด pool.backend/internal/adapter/inbound/http/query/handler.go:245— จุดที่ตั้งClientRequest=trueของนโยบายเขียน.backend/internal/adapter/inbound/http/process/permission.go:191— การอ้างsml_audit_logในการแปลงสิทธิ์execBatch.backend/README.md:85,backend/Makefile— เอกสาร/เป้าหมาย build ที่ล้าสมัยหรือไม่มี migrate.
ดูเพิ่ม
สารบัญ ADR ของ backend (Architecture Decision Records) · ภาพรวมกลุ่ม process ของ Backend (Process overview) · ภาพรวม Frontend ของ SML Ai Account (Frontend overview) · สารบัญมาตรฐานและกฎเหล็กของ SML Ai Account (Standards Overview) · สมอง SML — หน้าแรก (Map of Content)