ระบบแยกบริษัท/ฐานข้อมูล (tenant, provider, company) อย่างไร
ตอบสั้น: 1 ลูกค้า = 1 Provider (รหัสพิมพ์ใหญ่/เลข 2-20 ตัว) มี PostgreSQL ของตัวเอง ภายในมี Main Database smlerpmain<รหัส provider พิมพ์เล็ก> เก็บผู้ใช้/สิทธิ์/รายชื่อบริษัท และแต่ละบริษัทมี Company Database แยกเป็นของตัวเอง ชื่อฐานของบริษัทที่เลือกถูกฝังใน JWT claim databaseName แล้วทุกคำขอ (/query, /process, /blob) เปิด pool ไปฐานนั้นจาก claim เท่านั้น ไม่รับจาก body
รายละเอียด
ศัพท์: Provider (tenantId ใน JWT) → Main DB → Company (data_code, data_group ใน sml_database_list) → Company DB (data_database_name) ดูภาพรวมที่ โมเดลผู้เช่าหลายราย: Tenant, Provider, Main DB, Company (Multi-tenant model)
ข้อมูลการเชื่อมต่อ: เก็บเป็นไฟล์ JSON ต่อ provider ใน CONFIG_DIR (ทะเบียน Provider แบบไฟล์ JSON (Provider registry))
ลำดับ login แบบรหัสผ่าน (POST /auth/login, Service.Login service.go:51):
- ส่ง
provider+dataGroup+username+password→ หา connection ของ provider → คำนวณ Main DB ="smlerpmain" + lower(provider)(service.go:20, สูตรตายตัว) - อ่านผู้ใช้จาก
sml_user_list(ไม่สนตัวพิมพ์) แล้วตรวจรหัสผ่าน (ขั้นตอน login / เลือกบริษัท / refresh / logout (Identity login flow)) AccessibleCompanies(postgres_repository.go:132) หาบริษัทที่ผู้ใช้เข้าได้จากsml_database_list_user_and_groupJOINsml_database_listเงื่อนไขuser_or_group_status = 0เรียงตามroworder- 0 บริษัท → 403 · 1 บริษัท → ออก access+refresh token ทันที · หลายบริษัท → ออก
preAuthTokenพร้อมรายชื่อ ให้ผู้ใช้เลือกที่POST /auth/select-company(ระบบคิวรีรายการใหม่อีกรอบ ไม่เชื่อรายการที่ client ถือ)
ทางเข้าของหน้าเว็บ: หน้า /login มีปุ่มทดลองใช้ (Demo) และ Google แล้วไป /select-database เลือก/สร้างบริษัท (workspace/select-db ออก token ชุดเดียวกันด้วยบริษัทที่เลือก — workspace_google.go:674) ดู หน้าเข้าสู่ระบบและเลือกฐานข้อมูล (Login & select database)
ตอนใช้งาน: PoolManager.Get(databaseName, dsn) (pool.go:190) แคช pool ต่อ host|port|user|db จึงฐานเดียวกันใช้ pool เดียว
ข้อควรระวัง
levelใน token คือค่า ณ ตอนออก token อัปเดตเมื่อ select-company/refresh เท่านั้น (ทำไมถูกเด้งออกจากระบบ / ขึ้น "หมดเวลาใช้งาน" (token หมดอายุ, idle 30 นาที, logout) ทำงานอย่างไร)- ชื่อฐานที่ขึ้นต้น
smlerpmainสงวนไว้ Main DB ห้ามใช้เป็นฐานบริษัท (ValidateCreateInputของ MCP และ admin ปฏิเสธ)
ดูเพิ่ม
- โมเดลผู้เช่าหลายราย: Tenant, Provider, Main DB, Company (Multi-tenant model)
- ขั้นตอน login / เลือกบริษัท / refresh / logout (Identity login flow)
- JWT session token และการเพิกถอน (JWT + revocation store)
- ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager)
- หน้าเข้าสู่ระบบและเลือกฐานข้อมูล (Login & select database)
- เริ่มใช้บริษัท/ฐานข้อมูลใหม่ ต้องตั้งข้อมูลหลักอะไรบ้างก่อนบันทึกเอกสารได้
ที่มาในโค้ด
backend/internal/domain/tenant/provider.go:21รูปแบบรหัส provider^[A-Z0-9]{2,20}$backend/internal/application/identity/service.go:20ค่าคงที่ prefixsmlerpmain(ใช้ที่บรรทัด 58)backend/internal/application/identity/service.go:51Login(0/1/หลายบริษัท) และSelectCompanyที่บรรทัด 113backend/internal/adapter/outbound/identity/postgres_repository.go:132AccessibleCompanies(SQL บรรทัด 138-145)backend/internal/adapter/outbound/identity/jwt_token_service.go:31claimstenantId,companyCode,databaseNamebackend/internal/platform/db/pool.go:190PoolManager.Getbackend/internal/adapter/inbound/http/admin/workspace_google.go:674WorkspaceSelectDatabaseออก session ด้วยบริษัทที่เลือก