กฎ Validation กลาง (Form Builder Rule)
ภาพรวม
ชุด "กฎกลาง" ที่แอดมินสร้างไว้ใน CMS แล้วนำไปผูกกับคำถามในหลายฟอร์มได้ เช่น รูปแบบเบอร์มือถือไทย เลขบัตรประชาชน หรือรหัสพนักงาน แต่ละกฎเก็บ pattern (regex), minLength, maxLength, errorMessage และ errorMessageTh ไว้ในคอลัมน์ properties
feature นี้มี endpoint เพียงตัวเดียวซึ่งชื่อในโค้ดคือ test (สืบทอดมาจาก source เดิม) แต่บทบาทจริงสำคัญกว่านั้นมาก เพราะเป็น service ที่ โหลดโครงฟอร์ม เรียกใช้เพื่อนำ rule ไป merge ลงในคำถาม และเป็นตัวกำหนดว่า การตรวจความถูกต้องของคำตอบ จะใช้ pattern ใด
Business Flow
GET /api/form-builder-rule คืน array ของ rule ที่มี status='active' โดยอ่านผ่าน Redis cache
การสร้าง cache key ถูกเลียนแบบจาก source แบบตัวต่อตัวเพื่อให้ Go และ Node ชนกันที่ key เดียวกัน ทำให้รันคู่ขนานได้
optionsJSONคือสตริง{"where":{"status":"active"}}ซึ่งเป็นสำเนาของJSON.stringifyของFindManyOptionsที่ controller เดิมส่งเข้ามาแบบเป๊ะ ๆ- suffix คือ
sha256(optionsJSON)ที่ตัดเอา 10 ตัวแรก ผ่านฟังก์ชันutil.GenerateShortHash - key มีรูปแบบ
FORM_BUILDER_RULE:findAll:{suffix}ตามแม่แบบ${MODULE_NAME}:${key} - หาก cache hit และ unmarshal สำเร็จจะคืนค่าทันที แต่ถ้า cache entry พังรูปจะ fall through ไปอ่าน DB แทน
- เมื่ออ่าน DB สำเร็จจะเขียน cache กลับด้วย default TTL จาก
REDIS_TTL - error ทุกชนิดถูกกลืน แล้วคืน array ว่าง เพื่อ parity กับ source ที่ไม่ปล่อยให้ endpoint นี้ตอบ 500
มีทางเข้า 2 แบบที่ต่างกันโดยเจตนา
FindAllWithCacheใช้โดย endpoint มี cache และกลืน errorFindAllActiveไม่มี cache ใช้โดย form-builder ในขั้นตอนtransformPatternเพราะ source เรียกfindAllไม่ใช่findAllWithCacheที่จุดนั้น หากใช้ cache แอดมินที่แก้ rule แล้วฟอร์มจะยังคงใช้ค่าเก่าอยู่
หากไม่มี Redis client ที่ชื่อ redis service จะ degrade ไปเป็นการอ่านสดโดยไม่ panic
ไฟล์และฟังก์ชันหลัก
| รายการ | ค่า |
|---|---|
| Route | GET /api/form-builder-rule |
| Register | internal/formbuilderrule/register.go → Register(r, deps) |
| Handler | internal/formbuilderrule/handler.go → (*Handler).Test |
| Service | internal/formbuilderrule/service.go → FindAllWithCache, FindAllActive, getRedisKey |
| Repository | internal/formbuilderrule/repository.go → FindAllActive |
| Entity | internal/formbuilderrule/entity.go → FormBuilderRule ซึ่งมี Properties เป็น raw JSON |
| ค่าคงที่ | moduleName = "FORM_BUILDER_RULE", findAllKey = "findAll" และ optionsJSON |
จุดเชื่อมต่อกับ Service อื่น
- ตาราง
form_builder_rule(คอลัมน์statusและ jsonbproperties) internal/cacheซึ่งเป็น namespaced Redis wrapper ทำงานร่วมกับ Redis client ชื่อredisโดย namespace และ TTL มาจากdeps.Config.RedisCacheinternal/util/hash.go→GenerateShortHash- ถูกใช้โดย โหลดโครงฟอร์ม ในขั้น
transformPatternและโดย ส่งคำตอบฟอร์ม ผ่านformbuilder.Serviceที่ประกอบซ้ำใน register ของตัวเอง - ฝั่ง client-web ที่เกี่ยวข้องคือ feature
form-fillซึ่งใช้commonRuleที่ merge มาแล้วเพื่อ validate ฝั่ง client ก่อนส่ง