#process#router#handler#dispatcher#multi-tenant
ตัวกระจายคำขอของ process (Process dispatcher)
ในโค้ดไม่มีไฟล์ process.go ที่เป็น dispatcher กลาง การกระจายคำขอเกิดจาก 2 ชั้น: route group ใน router.go (จับ URL) และ *_handler.go ใน adapter/inbound/http/process/ (switch ตาม {action}) แล้วเรียกเมธอดของ *appprocess.Service ใน application/process/
ทำงานอย่างไร
เส้นทางของคำขอ: HTTP POST -> Auth (ตรวจ JWT) -> RequireRight (ตรวจสิทธิ์เมนู ดู การตรวจสิทธิ์เมนูของ route process (Process route rights)) -> handler -> Service -> ฐานข้อมูลของบริษัท
- ลงทะเบียน route 2 ชุดที่เหมือนกันทุกบรรทัด:
/processและ/api/v1/process(ใช้ middleware เดียวกันAuth+RequireRight(ex.Rights, processhttp.RequiredRight)) - route แบบตรง (1 URL = 1 handler): เช่น
/report/run,/report/pdf,/doc/cancel,/doc/approve,/doc/flow,/lookup/party-filter,/lookup/ref-doc-filter,/lookup/wh-filter,/lookup/wh-pick-check,/lookup/wh-perm-filter - route แบบกลุ่ม
/{กลุ่ม}/{action}ที่ handler ใช้switch chi.URLParam(r, "action"):
| กลุ่ม | handler | รายการ action ที่มีใน switch |
|---|---|---|
barcode |
Barcode |
item, save, discount-load, discount-save, ean13-check, ean13-generate, ean13-apply, print-items, format |
transgrid |
TransGrid |
line, formula, totals, shortcut, priceinfo, fx, refimport |
master |
Master |
nextcode, codeleave, assetdepdefaults, datalistget, datalistsave |
master-detail |
MasterDetail |
save, delete เท่านั้น (อื่น ๆ ตอบ not found) |
docpicture |
DocPicture |
formats, docs, get, save (+ GET /docpicture/image) |
itempicture |
ItemPicture |
list, get, save (+ GET /itempicture/image) |
itemdetail |
ItemDetail |
get, save |
itemmaster |
ItemMaster |
save, delete |
modifyprice |
ModifyPrice |
preview, apply (เมนู 2.1.25), action อื่นตอบ not found |
stocktools |
StockTools |
formats, barcodecheck, serialanalyze, serialscan, lotamountload/save, hiddencost*, lotauto*, notcounted*, itemnextcode, stockbeginning*, docnonext, checkpricesave, pointdoc*, itemsaved |
workflow |
Workflow |
change-code, journal-list/pass, gl-check, gl-close, fa-depreciation, asset-sale, audit-list, check-ic-trans, point-recal, import-transport-label, province-list/load, ai-* |
- action ที่ไม่รู้จัก:
Master/MasterDetailตอบapperr.KindNotFound(ข้อความ "unknown master action" / "unknown master-detail action") - ตัวช่วยกลาง
serve[I, P](generic) ถอด JSON เข้า structI, ประทับ session (SetScope(provider, database, user)) แล้วเรียกfn, ตอบ{"ok": true, "data": ...}; ผิดพลาดบันทึกh.log.Warn()แล้วส่งresponse.Error - handler รุ่นเก่าใช้
serveTrans(ตอบTransResultพร้อม log provider/company/user/docNo) - ขนาด body:
maxJSONBody = 16 << 20(16 MB); รูปสินค้าใช้itemPictureBodyLimit = 48 << 20
Multi-tenant
- ค่า
ProviderCode,DatabaseName,Usernameมาจาก JWT claims เสมอ ไม่อ่านจาก body (struct ใช้ tagjson:"-"เช่นRunReportInput) Service.companyPool(ctx, providerCode, databaseName)แปลง provider -> connection, สร้าง/ใช้ pool ของ database บริษัทซ้ำ (db.PoolManager) และรันerpSchemaSQLครั้งเดียวต่อ database (เก็บในsync.Map erpSchema) เพื่อสร้างตาราง/ดัชนีที่ขาดServiceเก็บconnections,poolsและ cache ในsync.Map(erpSchema,posSchema,posSeedDone,posDrains)
จุดที่ต้องระวัง
- route ใหม่ที่ไม่ได้เพิ่มใน
routeRightsจะต้องใช้สิทธิ์ Admin โดยปริยาย (ดู การตรวจสิทธิ์เมนูของ route process (Process route rights)) - คำขอที่ไม่มี token ที่ถูกต้องถูก
AuthตอบKindUnauthorized(middleware/auth.go:44-50, test ยืนยัน 401 ที่auth_test.go:42); handler ตรวจ claims ซ้ำอีกชั้น - กลุ่ม trans/gl/stock/cost/ap/pay ฯลฯ อยู่ใน route group เดียวกัน แต่เป็นขอบเขตของโน้ตบัญชี ดู ภาพรวมระบบบัญชี SML AI Account (Accounting Overview)
ที่มาในโค้ด
backend/internal/adapter/inbound/http/router.go:40-57- structExtraHandlers(มีProcess *processhttp.Handler)backend/internal/adapter/inbound/http/router.go:127-167-r.Route("/process", ...)พร้อมAuth+RequireRightbackend/internal/adapter/inbound/http/router.go:168-209-r.Route("/api/v1/process", ...)ชุดเดียวกันbackend/internal/adapter/inbound/http/process/handler.go:19-maxJSONBodybackend/internal/adapter/inbound/http/process/handler.go:189-serveTransbackend/internal/adapter/inbound/http/process/stocktools_handler.go:23- ฟังก์ชัน genericservebackend/internal/adapter/inbound/http/process/master_handler.go:17-38- switch action ของMasterbackend/internal/adapter/inbound/http/process/master_detail_handler.go:15-MasterDetailbackend/internal/adapter/inbound/http/process/docpicture_handler.go:111-135-ModifyPrice(preview|apply)backend/internal/adapter/inbound/http/middleware/auth.go:44-Authตอบ Unauthorizedbackend/internal/adapter/inbound/http/process/workflow_handler.go:18-Workflowbackend/internal/application/process/service.go:531-546- structServiceและNewServicebackend/internal/application/process/service.go:950-companyPool