Migration และการสร้างตารางตอนรัน
โฟลเดอร์ backend/migrations/ มีไฟล์เดียวคือ 0001_audit_schema.sql และ ไม่มีโค้ด/สคริปต์ที่รันไฟล์นี้ — ตารางของโมดูลถูกสร้างตอนรันโดยโค้ด Go เอง (CREATE TABLE IF NOT EXISTS / ALTER TABLE ... IF NOT EXISTS) ทำให้ไฟล์ SQL กับโค้ดจริงไม่ตรงกัน. คำอธิบายใน README/PLAN เรื่อง golang-migrate เป็นแผนเก่าที่ไม่มีในโค้ด.
ทำงานอย่างไร
- ไฟล์
0001_audit_schema.sql(160 บรรทัด): คอมเมนต์หัวไฟล์บอกว่า "ดึง DDL ของโมดูลที่เคยรันผ่าน/query/execออกมา เพราะNewWriteStatementห้าม DDL (BE-01 Task 3) ต้องใช้สคริปต์ migration" (migrations/0001_audit_schema.sql:1-6) ตรงกับเหตุผลใน ADR-0006 /query/exec รับเฉพาะ DML + ตารางระบบต้อง level>=9 (ถูกแทนด้วย ADR-0011). ข้างในมี 7 ตาราง (ทุกอันเป็นIF NOT EXISTS):monitormap_tile_cache(+ indexidx_monitormap_tile_zxy),posconfig,pos_shift_log,etax_document_log,workmonitor_desk_nodes,workmonitor_activity_logs,workmonitor_summary_projection. ค่าเงิน/ยอดใช้NUMERIC(18,2)ถูกตามกฎ (ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager) อธิบายการอ่านกลับเป็นสตริงทศนิยม). - ชื่อไฟล์ไม่ตรงเนื้อหา: ชื่อ "audit_schema" แต่ไม่มีตาราง audit; ตาราง
sml_audit_logไม่ถูกสร้างที่ใดในโค้ด/SQL ของ backend — ถูกอ้างถึงเพียงที่process/permission.go:191เพื่อแปลงค่าแรกของvalues (1|2|3,เป็นสิทธิ์ Add/Edit/Delete ของ/query/execBatch(สิทธิ์เมนูและ middleware RequireRight (Menu rights / permission)) แปลว่าตารางนี้มาจากฐานข้อมูล SMLERP เดิม. - ไม่มีตัวรัน: ไม่พบการอ้างถึง
migrations/ใน Go,Makefile(เป้าหมายbuild/build-all/swagger/run/test/test-integration/vet/lint/tidy), Dockerfile หรือdeployments;go.modไม่มีgolang-migrate(การ build และ deploy backend: Docker, Kubernetes, Makefile (Deployment)). - ตารางจริงถูกสร้างตอนรัน โดยโค้ดแต่ละส่วน:
| ที่สร้าง | ตาราง | จังหวะ |
|---|---|---|
process/pos_config.go:17,373 EnsurePosTables |
posconfig ฯลฯ ของ POS |
ครั้งแรกต่อ (Provider, ฐาน) ใน process (posSeedDone), seed ข้อมูลตัวอย่างเฉพาะฐาน smldemo; error ของแต่ละ statement ถูกข้าม ("best effort") |
etax/handler.go:592 |
etax_document_log |
ตอนใช้งาน eTax |
monitormap/handler.go:132 |
monitormap_tile_cache |
ครั้งแรกต่อฐาน (schemaOnce) |
platform/db/pool.go:16 companySchemaSQL |
ตารางช่วยของบริษัท (ic_opposite_unit, erp_initial ฯลฯ) + ALTER ... ADD COLUMN IF NOT EXISTS |
ทุกครั้งที่เปิด pool ใหม่ (ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager)) |
admin/workspace_google.go:36 |
sml_google_account, sml_google_workspace_db, sml_google_workspace_member |
ทุกคำขอของ workspace (Workspace Google: ล็อกอินด้วยอีเมล สร้างบริษัทใหม่ สมาชิก และผูก LINE (Workspace Google API)) |
admin/handler.go, admin/menu_permissions.go, outbound/identity/postgres_repository.go:74 |
คอลัมน์ email, database_name ฯลฯ, ตาราง sml_tooltip |
ทุกคำขอที่เกี่ยวข้อง (Admin API สำหรับจัดการ Provider/ผู้ใช้/ฐานข้อมูล/สิทธิ์เมนู (Admin API)) |
- ผลคือ DDL ยังรันผ่าน connection ของแอป (ผู้ใช้ DB ต้องมีสิทธิ์ CREATE/ALTER) — เส้นทางที่ client ส่ง DDL ผ่าน
/query/execถูกปิดแล้ว แต่ handler ของโมดูลใช้AllowDDL/pool ตรงได้ (Query Gateway: /query/list, limit, batch, exec, execBatch).
ข้อควรระวัง
- schema ในไฟล์ไม่เหมือนโค้ดจริง: ตัวอย่างที่เทียบแล้ว —
monitormap_tile_cacheในไฟล์ใช้คีย์หลักcache_key VARCHAR(255)ส่วนโค้ดmonitormap/handler.go:132-134ใช้tile_key VARCHAR(80);etax_document_log.etax_doc_noในไฟล์เป็นVARCHAR(60) UNIQUEแต่โค้ดetax/handler.go:592-595ใช้varchar(50)ไม่มี UNIQUE และยังสั่งDROP CONSTRAINT IF EXISTS etax_document_log_etax_doc_no_key(etax/handler.go:636) เอา UNIQUE ออกโดยตั้งใจ. ถ้านำไฟล์ไปรันกับฐานใหม่ก่อน ตารางจะถูกสร้างด้วยโครงต่างจากที่โค้ดคาด และIF NOT EXISTSจะทำให้โค้ดไม่แก้ให้ — ให้ถือโค้ด Go เป็นความจริง (ยังไม่ได้เทียบทุกคอลัมน์ของposconfig/pos_shift_log). workmonitor_*และpos_shift_logไม่พบCREATE TABLEในโค้ด Go ของ backend — มีเฉพาะในไฟล์ SQL นี้ (อาจถูกสร้างโดยโมดูลอื่น/เลิกใช้แล้ว; ยังไม่ยืนยัน).- ค่า default ในไฟล์ (เลขผู้เสียภาษี/รหัสเครื่องตัวอย่างของ
posconfig) เป็นข้อมูลตัวอย่างฝังใน DDL — ไม่ควรใช้กับฐานจริง (ไม่คัดลอกค่าไว้ที่นี่). - ไม่มีระบบเวอร์ชัน/ตาราง
schema_migrations— เปลี่ยน schema ของฐานลูกค้าที่มีอยู่ทำได้เฉพาะADD COLUMN IF NOT EXISTSในโค้ด; การเปลี่ยนชนิด/ลบคอลัมน์ไม่มีกลไกรองรับ. - เอกสารที่ล้าสมัย: README/PLAN เขียนว่าใช้
golang-migrateสำหรับ control-plane และมีแพ็กเกจschema(README.md:85,104,131,docs/PLAN.md:81,100,234) — ในโค้ดไม่มี; control-plane จริงคือไฟล์ JSON (ทะเบียน Provider แบบไฟล์ JSON (Provider registry), ADR-0001 เก็บ config ของผู้เช่า (Provider) เป็นไฟล์ JSON ไม่ใช่ตาราง DB). - ตาราง
etax_document_logถูกจัดเป็น "ตารางเงิน" ในนโยบายล็อกการเขียน (นโยบายล็อกการเขียนผ่าน Query Gateway (Query write policy / lockdown)).
ที่มาในโค้ด
backend/migrations/0001_audit_schema.sql:1-160— DDL 7 ตาราง.backend/internal/application/process/pos_config.go:17-30,373-400—posConfigDDL,EnsurePosTables.backend/internal/adapter/inbound/http/etax/handler.go:590-600— DDLetax_document_log.backend/internal/adapter/inbound/http/monitormap/handler.go:128-140— DDLmonitormap_tile_cache.backend/internal/platform/db/pool.go:16-148,216-218— DDL ตอนเปิด pool.backend/internal/adapter/inbound/http/process/permission.go:185-200— การอ้างsml_audit_log.backend/Makefile— ไม่มีเป้าหมาย migrate.
ดูเพิ่ม
ภาพรวม Backend Go ของ SML Ai Account (Backend overview) · ตัวจัดการ connection pool ต่อฐานข้อมูล (PoolManager) · การ build และ deploy backend: Docker, Kubernetes, Makefile (Deployment) · สถาปัตยกรรม Hexagonal และ composition root ของ Go backend (Hexagonal Architecture + DI) · ADR-0006 /query/exec รับเฉพาะ DML + ตารางระบบต้อง level>=9 (ถูกแทนด้วย ADR-0011) · สารบัญ ADR ของ backend (Architecture Decision Records)