Central Validation Rules
Overview
A set of shared rules that admins create in the CMS and attach to questions across many forms — Thai mobile number formats, national ID numbers, employee codes, and so on. Each rule stores pattern (a regex), minLength, maxLength, errorMessage, and errorMessageTh in its properties column.
The feature exposes a single endpoint, named test in the code (inherited from the original source), but its real role is more significant: it is the service that Loading a Form's Structure calls to merge rules into questions, and it determines which pattern Form Answer Validation will apply.
Business Flow
GET /api/form-builder-rule returns the array of rules with status='active', read through a Redis cache.
The cache key is reproduced character for character from the source so that Go and Node land on the same key and can run side by side.
optionsJSONis the string{"where":{"status":"active"}}— an exact copy of theJSON.stringifyof theFindManyOptionsthe original controller passed in.- The suffix is the first 10 characters of
sha256(optionsJSON), produced byutil.GenerateShortHash. - The key takes the form
FORM_BUILDER_RULE:findAll:{suffix}, following the${MODULE_NAME}:${key}template. - On a cache hit that unmarshals successfully, the value is returned immediately; a malformed cache entry falls through to the database.
- A successful database read writes the value back to the cache with the default TTL from
REDIS_TTL. - Every error is swallowed and an empty array is returned, matching the source, which never lets this endpoint return a 500.
There are two deliberately different entry points:
FindAllWithCacheis used by the endpoint — cached, and error-swallowing.FindAllActiveis uncached and used by form-builder duringtransformPattern, because the source callsfindAllrather thanfindAllWithCacheat that point. With a cache there, an admin editing a rule would still see forms using the stale version.
If no Redis client named redis exists, the service degrades to reading live without panicking.
Key Files & Functions
| Item | Value |
|---|---|
| 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, whose Properties is raw JSON |
| Constants | moduleName = "FORM_BUILDER_RULE", findAllKey = "findAll", and optionsJSON |
Connections to Other Services
- The
form_builder_ruletable (statusand the jsonbproperties). internal/cache, a namespaced Redis wrapper backed by the client namedredis; namespace and TTL come fromdeps.Config.RedisCache.internal/util/hash.go→GenerateShortHash.- Consumed by Loading a Form's Structure during
transformPattern, and by Form Answer Submission through theformbuilder.Serviceit assembles in its own register. - The related client-web feature is
form-fill, which uses the mergedcommonRuleto validate on the client before submitting.