Compare commits

120 Commits

Author SHA1 Message Date
admin cd7d20ccd4 690609:2223 Prepare to MOD AI flow [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-09 22:23:59 +07:00
admin 75d07b5ac9 690608:1520 ADR-035-135 #09
CI / CD Pipeline / build (push) Successful in 5m7s
CI / CD Pipeline / deploy (push) Successful in 4m40s
2026-06-08 15:20:34 +07:00
admin 52b96d01de 690608:0012 ADR-035-135 #08
CI / CD Pipeline / build (push) Successful in 5m5s
CI / CD Pipeline / deploy (push) Successful in 3m48s
2026-06-08 00:12:31 +07:00
admin a0f77ad121 690607:2321 ADR-035-135 #07
CI / CD Pipeline / build (push) Successful in 5m20s
CI / CD Pipeline / deploy (push) Successful in 6m42s
2026-06-07 23:21:55 +07:00
admin 16aab2279c 690606:1705 ADR-035-135 #06
CI / CD Pipeline / build (push) Successful in 5m19s
CI / CD Pipeline / deploy (push) Successful in 3m11s
2026-06-06 17:05:51 +07:00
admin 15dec6c3fc 690606:1538 ADR-035-135 #05
CI / CD Pipeline / build (push) Successful in 5m21s
CI / CD Pipeline / deploy (push) Successful in 3m14s
2026-06-06 15:38:10 +07:00
admin 33c3935164 690606:1441 ADR-035-135 #04.2
CI / CD Pipeline / build (push) Successful in 4m51s
CI / CD Pipeline / deploy (push) Successful in 7m18s
2026-06-06 14:41:26 +07:00
admin 6bcd1a5c58 690606:1413 ADR-035-135 #04.1
CI / CD Pipeline / build (push) Failing after 4m2s
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-06 14:13:59 +07:00
admin de4201d7d3 690606:1408 ADR-035-135 #04
CI / CD Pipeline / deploy (push) Has been cancelled
CI / CD Pipeline / build (push) Has been cancelled
2026-06-06 14:08:57 +07:00
admin e3e0de66e9 690606:1354 ADR-035-135 #03.1 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-06 13:54:36 +07:00
admin 866fea7946 690606:1253 ADR-035-135 #03
CI / CD Pipeline / build (push) Successful in 7m27s
CI / CD Pipeline / deploy (push) Successful in 3m19s
2026-06-06 12:53:37 +07:00
admin 85c7415b8a 260606:1127 ADR-035-234 #2.1 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-06 11:27:42 +07:00
admin ed1b302274 690606:1120 ADR-035-135 #02
CI / CD Pipeline / build (push) Successful in 5m11s
CI / CD Pipeline / deploy (push) Successful in 3m32s
2026-06-06 11:20:13 +07:00
admin 26cc71ce60 690605:2335 ADR-035-135 #1
CI / CD Pipeline / build (push) Successful in 4m54s
CI / CD Pipeline / deploy (push) Successful in 6m19s
2026-06-05 23:35:22 +07:00
admin 285c007dff Add specs/06-Decision-Records/ADR-035-addon.md
CI / CD Pipeline / build (push) Successful in 5m30s
CI / CD Pipeline / deploy (push) Successful in 1m32s
2026-06-05 19:20:56 +07:00
admin 03aa4efcf0 690605:1725 ADR-035-135 #0 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 17:25:40 +07:00
admin 4f90ed688f 690605:1517 ADR-034-134 #11 fix Step 2 #02
CI / CD Pipeline / build (push) Successful in 5m21s
CI / CD Pipeline / deploy (push) Successful in 4m27s
2026-06-05 15:17:54 +07:00
admin 548dba6476 690605:1247 ADR-034-134 #11 fix Step 2
CI / CD Pipeline / build (push) Successful in 6m5s
CI / CD Pipeline / deploy (push) Successful in 6m30s
2026-06-05 12:47:38 +07:00
admin 4a808dd9c4 690605:1126 ADR-034-134 #10.9 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 11:26:04 +07:00
admin e71602e90c 690605:1121 ADR-034-134 #10.8 [skip CI] 2026-06-05 11:21:57 +07:00
admin bd96c4122c 260605:1105 ADR-034-134 #10.7 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 11:05:55 +07:00
admin 661710f349 690605:1056 ADR-034-134 #10.6 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 10:56:42 +07:00
admin eae94cf1f3 690605:1032 ADR-034-134 #10.5 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 10:32:27 +07:00
admin eeb9f6c686 690605:1017 ADR-034-134 #10.4 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 10:17:28 +07:00
admin 37174788bf 690605:0941 ADR-034-134 #10.3 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 09:41:13 +07:00
admin 2db4810dfc 690605:0922 ADR-034-134 #10.2 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 09:22:41 +07:00
admin 8b6ef392f5 690605:0840 ADR-034-134 #10.1 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-05 08:40:29 +07:00
admin eef557675b 690604:1720 ADR-034-134 #10
CI / CD Pipeline / build (push) Successful in 4m57s
CI / CD Pipeline / deploy (push) Successful in 3m37s
2026-06-04 17:20:54 +07:00
admin 1a399400ff 690604:1613 ADR-034-134 #09.5 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-04 16:14:00 +07:00
admin 29314a7ec4 690604:1601 ADR-034-134 #09.4 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-04 16:01:24 +07:00
admin 70fbac1b49 690604:1554 ADR-034-134 #09.3 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-04 15:54:07 +07:00
admin 1c3d9906e4 690604:1549 ADR-034-134 #09.2 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-04 15:49:27 +07:00
admin c841be1b31 690604:1535 ADR-034-134 #09.1 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-04 15:35:24 +07:00
admin 94583bd30f 690604:1327 ADR-034-134 #09
CI / CD Pipeline / build (push) Successful in 5m5s
CI / CD Pipeline / deploy (push) Successful in 4m7s
2026-06-04 13:27:26 +07:00
admin 17dff31dec 690604:1305 ADR-034-134 #08.1 [skip CI]
CI / CD Pipeline / build (push) Has been skipped
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-04 13:05:23 +07:00
admin b14a0b3d58 690604:1208 ADR-034-134 #08
CI / CD Pipeline / build (push) Successful in 5m39s
CI / CD Pipeline / deploy (push) Successful in 7m54s
2026-06-04 12:08:19 +07:00
admin 03963fd896 690604:1203 ADR-034-134 #07.2 [skip CI]
CI / CD Pipeline / build (push) Has been cancelled
CI / CD Pipeline / deploy (push) Has been cancelled
2026-06-04 12:03:54 +07:00
admin 663ed13522 690604:1156 ADR-034-134 #07.1 [skip CI]
CI / CD Pipeline / build (push) Successful in 5m33s
CI / CD Pipeline / deploy (push) Has been cancelled
2026-06-04 11:56:35 +07:00
admin 9c122c8328 690604:1139 ADR-034-134 #07
CI / CD Pipeline / build (push) Successful in 5m16s
CI / CD Pipeline / deploy (push) Successful in 5m1s
2026-06-04 11:39:56 +07:00
admin 4d243c16e6 690604:1107 ADR-034-134 #06
CI / CD Pipeline / build (push) Successful in 5m32s
CI / CD Pipeline / deploy (push) Successful in 3m41s
2026-06-04 11:07:29 +07:00
admin 994b41aa37 690604:1043 ADR-034-134 #05
CI / CD Pipeline / build (push) Successful in 5m47s
CI / CD Pipeline / deploy (push) Successful in 7m4s
2026-06-04 10:43:34 +07:00
admin b79895e6fb 690604:1008 ADR-034-134 #04
CI / CD Pipeline / build (push) Successful in 4m58s
CI / CD Pipeline / deploy (push) Successful in 7m33s
2026-06-04 10:08:22 +07:00
admin fb224a116c 690604:0832 ADR-034-134 #03
CI / CD Pipeline / build (push) Successful in 4m57s
CI / CD Pipeline / deploy (push) Successful in 9m45s
2026-06-04 08:32:32 +07:00
admin e0eabfb350 690603:2146 ADR-034-134 #02
CI / CD Pipeline / build (push) Successful in 5m28s
CI / CD Pipeline / deploy (push) Successful in 7m11s
2026-06-03 21:46:10 +07:00
admin 3274dede7a 690603:2041 ADR-034-134 #01
CI / CD Pipeline / build (push) Failing after 4m28s
CI / CD Pipeline / deploy (push) Has been skipped
2026-06-03 20:41:42 +07:00
admin 754d609399 fix(ai): correct double-wrap in OCR engine endpoints causing e.map error
CI / CD Pipeline / build (push) Successful in 4m50s
CI / CD Pipeline / deploy (push) Successful in 14m18s
Controller was returning { data: engines } which TransformInterceptor
wrapped again into { data: { data: engines } }. extractData() only peeled
one layer, leaving an object instead of the array — causing .map() to fail
in OcrEngineSelector.

- Return data directly from getOcrEngines() and selectOcrEngine()
- Add Array.isArray guard in OcrEngineSelector as defensive layer
2026-06-02 15:49:39 +07:00
admin e4948ad4c8 690602:1503 ADR-033-233 #05
CI / CD Pipeline / build (push) Successful in 4m52s
CI / CD Pipeline / deploy (push) Successful in 9m57s
2026-06-02 15:03:27 +07:00
admin be851ee311 690602:1419 ADR-033-233 #04
CI / CD Pipeline / build (push) Successful in 5m44s
CI / CD Pipeline / deploy (push) Successful in 12m41s
2026-06-02 14:19:17 +07:00
admin cb9ecb2de6 690602:1334 ADR-033-233 #03
CI / CD Pipeline / build (push) Successful in 5m8s
CI / CD Pipeline / deploy (push) Successful in 7m57s
2026-06-02 13:34:22 +07:00
admin b939a25456 690602:1254 ADR-033-233 #02.1 [skip CI]
CI / CD Pipeline / build (push) Successful in 5m14s
CI / CD Pipeline / deploy (push) Successful in 2m4s
2026-06-02 12:54:23 +07:00
admin 8909629d8f 690602:1245 ADR-033-233 #02
CI / CD Pipeline / build (push) Successful in 4m59s
CI / CD Pipeline / deploy (push) Successful in 5m35s
2026-06-02 12:45:57 +07:00
admin bc754e66fd 690602:0957 ADR-033-233 #01
CI / CD Pipeline / build (push) Successful in 4m52s
CI / CD Pipeline / deploy (push) Successful in 17m39s
2026-06-02 09:57:48 +07:00
admin 7f35c3a585 690601:2213 ADR-032-232 #10 fix: add typhoon-ocr1.5-3b option to sandbox engine selector
CI / CD Pipeline / build (push) Successful in 4m55s
CI / CD Pipeline / deploy (push) Successful in 7m55s
2026-06-01 22:13:47 +07:00
admin 2cc07ee2e5 690601:2143 ADR-032-232 #09
CI / CD Pipeline / build (push) Successful in 4m34s
CI / CD Pipeline / deploy (push) Successful in 4m0s
2026-06-01 21:43:19 +07:00
admin 69db07fe35 690601:1934 ADR-032-232 #08.1 docs: update ADR-032 and tasks.md with multipart upload decision [skip CI][skip CI]
CI / CD Pipeline / build (push) Has been cancelled
CI / CD Pipeline / deploy (push) Has been cancelled
2026-06-01 19:34:24 +07:00
admin acc19f4a44 690601:1929 ADR-032-232 #08
CI / CD Pipeline / build (push) Successful in 5m21s
CI / CD Pipeline / deploy (push) Successful in 4m25s
2026-06-01 19:29:55 +07:00
admin 2bbe67b4c5 690601:1911 ADR-032-232 #07.2 [skip CI]
CI / CD Pipeline / build (push) Successful in 5m56s
CI / CD Pipeline / deploy (push) Successful in 1m51s
2026-06-01 19:11:36 +07:00
admin 7bc6eefad2 690601:1834 ADR-032-232 #07.1 [skip CI]
CI / CD Pipeline / build (push) Successful in 5m13s
CI / CD Pipeline / deploy (push) Successful in 1m50s
2026-06-01 18:34:41 +07:00
admin 09505f5793 690601:1816 ADR-032-232 #07
CI / CD Pipeline / build (push) Successful in 5m2s
CI / CD Pipeline / deploy (push) Successful in 4m1s
2026-06-01 18:16:25 +07:00
admin cd2bd5bf19 690601:1621 ADR-032-232 #06
CI / CD Pipeline / build (push) Successful in 5m23s
CI / CD Pipeline / deploy (push) Successful in 5m31s
2026-06-01 16:21:17 +07:00
admin 20f9fa1e85 690601:1221 ADR-032-232 #05
CI / CD Pipeline / build (push) Successful in 5m26s
CI / CD Pipeline / deploy (push) Successful in 4m49s
2026-06-01 12:21:54 +07:00
admin b8954b300d 690601:1020 ADR-032-232 #04
CI / CD Pipeline / build (push) Successful in 5m9s
CI / CD Pipeline / deploy (push) Successful in 4m24s
2026-06-01 10:20:50 +07:00
admin 00ae9d3067 690601:0957 ADR-032-232 #03
CI / CD Pipeline / build (push) Successful in 4m43s
CI / CD Pipeline / deploy (push) Successful in 4m48s
2026-06-01 09:57:50 +07:00
admin 3c80617ffb 690601:0914 ADR-032-232 #02
CI / CD Pipeline / build (push) Successful in 4m58s
CI / CD Pipeline / deploy (push) Successful in 4m4s
2026-06-01 09:14:57 +07:00
admin 268f34198b 690530:2238 ADR-032-232 #01.0 [skip ci] 2026-05-30 22:38:04 +07:00
admin ae1b1f35e1 feat(ai): ADR-032 Typhoon OCR integration - models, processors, cache, VRAM monitor, sandbox UI
CI / CD Pipeline / build (push) Successful in 4m51s
CI / CD Pipeline / deploy (push) Successful in 12m7s
2026-05-30 22:18:51 +07:00
admin f86fcc05f5 690530:1459 ADR-030-231-ocr-sandbox-two-step-flow #05.4 [skip ci] 2026-05-30 14:59:19 +07:00
admin 9404596012 690530:1448 ADR-030-231-ocr-sandbox-two-step-flow #05.3 [skip ci] 2026-05-30 14:48:53 +07:00
admin 10024a66c3 690530:1434 ADR-030-231-ocr-sandbox-two-step-flow #05.2 [skip ci] 2026-05-30 14:34:37 +07:00
admin b7a7b1e84d 690530:1420 ADR-030-231-ocr-sandbox-two-step-flow #05.1 [skip ci] 2026-05-30 14:20:54 +07:00
admin 30d9d721fb 690530:1345 ADR-030-231-ocr-sandbox-two-step-flow #05
CI / CD Pipeline / build (push) Successful in 5m43s
CI / CD Pipeline / deploy (push) Successful in 9m8s
2026-05-30 13:45:18 +07:00
admin c9edd62a0b 690530:1329 ADR-030-231-ocr-sandbox-two-step-flow #04.6 [skip ci] 2026-05-30 13:29:08 +07:00
admin ddc9332122 690530:1317 ADR-030-231-ocr-sandbox-two-step-flow #04.5 [skip ci] 2026-05-30 13:17:16 +07:00
admin e82cb0e68b 690530:1315 ADR-030-231-ocr-sandbox-two-step-flow #04.4 [skip ci] 2026-05-30 13:15:18 +07:00
admin b1c838a637 690530:1313 ADR-030-231-ocr-sandbox-two-step-flow #04.3 [skip ci] 2026-05-30 13:13:44 +07:00
admin d13d5a06cc 690530:1311 ADR-030-231-ocr-sandbox-two-step-flow #04.2 [skip ci] 2026-05-30 13:11:46 +07:00
admin 3bf0f506eb 690530:1305 ADR-030-231-ocr-sandbox-two-step-flow #04 [skip ci] 2026-05-30 13:05:48 +07:00
admin c88354347b 690530:1239 ADR-030-231-ocr-sandbox-two-step-flow #04
CI / CD Pipeline / build (push) Successful in 5m11s
CI / CD Pipeline / deploy (push) Successful in 4m23s
2026-05-30 12:39:17 +07:00
admin 33c62993d5 690530:1206 ADR-030-231-ocr-sandbox-two-step-flow #03
CI / CD Pipeline / build (push) Successful in 4m58s
CI / CD Pipeline / deploy (push) Successful in 8m36s
2026-05-30 12:06:32 +07:00
admin 499d787aa5 690530:1154 ADR-030-231-ocr-sandbox-two-step-flow #02
CI / CD Pipeline / build (push) Successful in 5m17s
CI / CD Pipeline / deploy (push) Failing after 1m12s
2026-05-30 11:54:23 +07:00
admin b0b7d12d5a 690530:1121 ADR-030-231-ocr-sandbox-two-step-flow #01
CI / CD Pipeline / build (push) Successful in 5m10s
CI / CD Pipeline / deploy (push) Failing after 3m15s
2026-05-30 11:21:37 +07:00
admin 1ba563aa70 690530:0906 ADR-030-230 context aware #12
CI / CD Pipeline / build (push) Successful in 4m54s
CI / CD Pipeline / deploy (push) Successful in 7m49s
2026-05-30 09:06:23 +07:00
admin 63ded10341 690530:0820 ADR-030-230 context aware #11
CI / CD Pipeline / build (push) Successful in 5m19s
CI / CD Pipeline / deploy (push) Successful in 4m19s
2026-05-30 08:20:08 +07:00
admin 32204c9305 690530:0805 ADR-030-230 context aware #10
CI / CD Pipeline / build (push) Failing after 4m32s
CI / CD Pipeline / deploy (push) Has been skipped
2026-05-30 08:05:48 +07:00
admin 6799cb1715 Update backend/Dockerfile
CI / CD Pipeline / build (push) Successful in 4m40s
CI / CD Pipeline / deploy (push) Failing after 3m4s
2026-05-29 22:34:24 +07:00
admin f33487f511 690529:1702 ADR-030-230 context aware #09
CI / CD Pipeline / build (push) Successful in 4m53s
CI / CD Pipeline / deploy (push) Failing after 2m16s
2026-05-29 17:02:12 +07:00
admin 8367ced926 fix(backend): fix expose name mapping bug in AiPromptResponseDto causing HTTP 500
CI / CD Pipeline / build (push) Successful in 4m27s
CI / CD Pipeline / deploy (push) Failing after 5m18s
2026-05-29 15:23:59 +07:00
admin 8b05f0f05c 690529:1520 ADR-030-230 context aware #08
CI / CD Pipeline / build (push) Successful in 4m22s
CI / CD Pipeline / deploy (push) Failing after 6m11s
2026-05-29 15:20:21 +07:00
admin d19131fa75 690529:1307 ADR-030-230 context aware #07
CI / CD Pipeline / build (push) Successful in 4m32s
CI / CD Pipeline / deploy (push) Successful in 5m52s
2026-05-29 13:07:45 +07:00
admin 95c1c31e1f 690529:1218 ADR-030-230 context aware #06
CI / CD Pipeline / build (push) Successful in 5m25s
CI / CD Pipeline / deploy (push) Successful in 6m11s
2026-05-29 12:18:53 +07:00
admin 0dcd7f460b 690529:1151 ADR-030-230 context aware #05
CI / CD Pipeline / build (push) Successful in 4m18s
CI / CD Pipeline / deploy (push) Successful in 9m30s
2026-05-29 11:51:57 +07:00
admin b68a750e4f 690529:1116 ADR-030-230 context aware #04
CI / CD Pipeline / build (push) Successful in 4m39s
CI / CD Pipeline / deploy (push) Successful in 7m59s
2026-05-29 11:16:03 +07:00
admin 5d46504c1d 690529:0926 ADR-030-230 context aware #03
CI / CD Pipeline / build (push) Successful in 5m3s
CI / CD Pipeline / deploy (push) Successful in 4m47s
2026-05-29 09:26:18 +07:00
admin 4391bbe61d 690528:1524 ADR-030-230 context aware #02
CI / CD Pipeline / build (push) Failing after 4m14s
CI / CD Pipeline / deploy (push) Has been skipped
2026-05-28 15:24:41 +07:00
admin 960cd78b8a 690526:1239 ADR-023-229 dynamic prompt #03
CI / CD Pipeline / build (push) Successful in 5m12s
CI / CD Pipeline / deploy (push) Successful in 6m42s
2026-05-26 12:39:29 +07:00
admin 01de542d15 fix(husky): use absolute paths in pre-commit for type checks
CI / CD Pipeline / build (push) Successful in 4m50s
CI / CD Pipeline / deploy (push) Successful in 1m37s
- Use git rev-parse --show-toplevel for absolute paths
- Fixes 'cd frontend: No such file or directory' error
- Fix type cast parsing error in virtual-column.service.spec.ts
2026-05-26 12:20:20 +07:00
admin 9502d789b9 chore(husky): revert pre-commit to lint-staged only
CI / CD Pipeline / build (push) Failing after 3m14s
CI / CD Pipeline / deploy (push) Has been skipped
Type check blocked by broken virtual-column.service.spec.ts.
Will fix test file separately and re-enable type check.
2026-05-26 11:40:50 +07:00
admin 83d1517afc fix(ai-prompts): import UserModule to resolve RbacGuard dependency
CI / CD Pipeline / build (push) Successful in 4m45s
CI / CD Pipeline / deploy (push) Successful in 4m20s
2026-05-26 11:10:03 +07:00
admin 1da666b090 Merge pull request '690525:2327 ADR-023-229 dynamic prompt #01' (#1) from 229-dynamic-prompt-management into main
CI / CD Pipeline / build (push) Successful in 4m23s
CI / CD Pipeline / deploy (push) Failing after 11m28s
Reviewed-on: #1
2026-05-26 10:36:19 +07:00
admin b3d3f6db95 690526:0905 ADR-023-229 dynamic prompt #02
CI / CD Pipeline / build (pull_request) Successful in 4m37s
CI / CD Pipeline / deploy (pull_request) Has been skipped
2026-05-26 09:05:34 +07:00
admin fd3bee394c 690526:0824 ADR-023-229 dynamic prompt #02 2026-05-26 08:24:04 +07:00
admin 82a0444013 690525:2327 ADR-023-229 dynamic prompt #01 2026-05-25 23:27:33 +07:00
admin 1139e54086 690525:1720 ADR-028-228-migration-OCR #06 dynamic prompt
CI / CD Pipeline / build (push) Successful in 4m29s
CI / CD Pipeline / deploy (push) Successful in 1m50s
2026-05-25 17:20:48 +07:00
admin d315488d83 690525:1541 ADR-028-228-migration-OCR #05 ocr-sidecar working
CI / CD Pipeline / build (push) Successful in 4m14s
CI / CD Pipeline / deploy (push) Successful in 5m0s
2026-05-25 15:41:56 +07:00
admin 87c3defc76 690525:1526 ADR-028-228-migration-OCR #05 [skip ci] 2026-05-25 15:26:46 +07:00
admin 1460ffb676 690525:1514 ADR-028-228-migration-OCR #04 [skip ci] 2026-05-25 15:14:06 +07:00
admin 4267f82db9 690525:1451 ADR-028-228-migration-OCR #03 [skip ci] 2026-05-25 14:51:28 +07:00
admin c9e578a33e 690525:1444 ADR-028-228-migration-OCR #02
CI / CD Pipeline / build (push) Successful in 4m32s
CI / CD Pipeline / deploy (push) Successful in 1m42s
2026-05-25 14:44:08 +07:00
admin 256a31b38c 690525:1418 ADR-028-228-migration-OCR #01
CI / CD Pipeline / build (push) Successful in 4m22s
CI / CD Pipeline / deploy (push) Successful in 3m58s
2026-05-25 14:18:02 +07:00
admin 001237ea35 690525:1320 ADR-028-228-migration #06
CI / CD Pipeline / build (push) Successful in 4m18s
CI / CD Pipeline / deploy (push) Successful in 7m41s
2026-05-25 13:20:17 +07:00
admin dcd1a9855e 690524:2148 ADR-028-228-migration #05
CI / CD Pipeline / build (push) Successful in 4m8s
CI / CD Pipeline / deploy (push) Successful in 3m42s
2026-05-24 21:48:30 +07:00
admin 1564f8648d 690524:1919 ADR-028-228-migration #04
CI / CD Pipeline / build (push) Successful in 4m10s
CI / CD Pipeline / deploy (push) Successful in 3m52s
2026-05-24 19:19:46 +07:00
admin 93fd95a6b3 690524:1435 ADR-028-228-migration #03
CI / CD Pipeline / build (push) Successful in 3m59s
CI / CD Pipeline / deploy (push) Successful in 5m18s
2026-05-24 14:35:05 +07:00
admin a63fe0fb5c 690524:1054 ADR-028-228-migration #02
CI / CD Pipeline / build (push) Successful in 4m7s
CI / CD Pipeline / deploy (push) Successful in 4m42s
2026-05-24 10:54:44 +07:00
admin 5a17f969b8 690523:2327 ADR-028-228-migration #01
CI / CD Pipeline / build (push) Successful in 4m38s
CI / CD Pipeline / deploy (push) Successful in 3m6s
2026-05-23 23:27:52 +07:00
admin ff5cadc9f2 690523:1623 ADR-028-228 #05
CI / CD Pipeline / build (push) Successful in 4m55s
CI / CD Pipeline / deploy (push) Successful in 5m49s
2026-05-23 16:23:12 +07:00
admin c04c5d1902 690522:2153 ADR-028-228 #04
CI / CD Pipeline / build (push) Failing after 4m13s
CI / CD Pipeline / deploy (push) Has been skipped
2026-05-22 21:53:41 +07:00
admin 3bf34ea840 690522:2140 ADR-028-228 #03
CI / CD Pipeline / build (push) Successful in 5m39s
CI / CD Pipeline / deploy (push) Failing after 3m9s
2026-05-22 21:40:19 +07:00
admin 433b149c85 690522:2125 ADR-028-228 #02
CI / CD Pipeline / build (push) Successful in 4m47s
CI / CD Pipeline / deploy (push) Failing after 5m39s
2026-05-22 21:25:08 +07:00
admin 942cda486c feat(migration): merge ADR-028 migration architecture refactor into main
CI / CD Pipeline / build (push) Successful in 5m45s
CI / CD Pipeline / deploy (push) Failing after 5m24s
Branch: 228-migration-arch-refactor
Tests: 670/670 PASS (Jest backend + Vitest frontend)
Validation: PASS 32/32 tasks, 18/18 FRs
ADR: ADR-028, ADR-023A, ADR-009, ADR-016, ADR-019, ADR-008, ADR-007
2026-05-22 17:12:20 +07:00
506 changed files with 32919 additions and 5531 deletions
+10 -10
View File
@@ -6,8 +6,8 @@
> # Speckit Agent Infrastructure (v1.9.0) > # Speckit Agent Infrastructure (v1.9.0)
> >
> - Version: 1.9.0 > - Version: 1.9.0
> - Last Updated: 2026-05-13 > - Last Updated: 2026-05-22
> - Core Principle: **Sync with AGENTS.md v1.9.0** > - Core Principle: **Sync with AGENTS.md v1.9.6**
--- ---
@@ -95,18 +95,18 @@ The toolkit is organized into modular components that provide both the logic (Sc
│ └── util-speckit-*.md # Utilities (checklist, diff, migrate, etc.) │ └── util-speckit-*.md # Utilities (checklist, diff, migrate, etc.)
├── rules/ # Project Context & Validation Rules ├── rules/ # Project Context & Validation Rules
│ ├── 00-project-context.md # Role, Persona, Rule Tiers (v1.9.0) │ ├── 00-project-context.md # Role, Persona, Rule Tiers (v1.9.6)
│ ├── 01-adr-019-uuid.md # UUID Strategy (Critical) │ ├── 01-adr-019-uuid.md # UUID Strategy (Critical)
│ ├── 02-security.md # Security Requirements │ ├── 02-security.md # Security Requirements (ADR-023/023A)
│ ├── 03-typescript.md # TypeScript Standards │ ├── 03-typescript.md # TypeScript Standards
│ ├── 04-domain-terminology.md # DMS Glossary Compliance │ ├── 04-domain-terminology.md # DMS Glossary Compliance
│ ├── 05-forbidden-actions.md # Critical Prohibited Patterns │ ├── 05-forbidden-actions.md # Critical Prohibited Patterns
│ ├── 06-backend-patterns.md # NestJS Architecture Rules │ ├── 06-backend-patterns.md # NestJS Architecture Rules
│ ├── 07-frontend-patterns.md # Next.js App Router Rules │ ├── 07-frontend-patterns.md # Next.js App Router Rules
│ ├── 08-development-flow.md # Development Workflow │ ├── 08-development-flow.md # Development Workflow (Tier 3 SPECIALIZED WORK)
│ ├── 09-commit-checklist.md # Pre-commit Validation │ ├── 09-commit-checklist.md # Pre-commit Validation
│ ├── 10-error-handling.md # ADR-007 Compliance │ ├── 10-error-handling.md # ADR-007 Compliance
│ └── 11-ai-integration.md # ADR-018/020 AI Boundaries │ └── 11-ai-integration.md # ADR-023/023A AI Boundaries
└── scripts/ └── scripts/
├── bash/ # Bash Core (Kinetic logic) ├── bash/ # Bash Core (Kinetic logic)
@@ -265,9 +265,9 @@ If you change your mind mid-project:
--- ---
## 🏗️ LCBP3-DMS Project Notes (v1.9.0) ## 🏗️ LCBP3-DMS Project Notes (v1.9.6)
### 📊 Current Status: Production Ready (2026-04-14) ### 📊 Current Status: Production Ready (2026-05-22)
| Area | Status | | Area | Status |
| ------------- | ------------------------------- | | ------------- | ------------------------------- |
@@ -306,7 +306,7 @@ If you change your mind mid-project:
- ❌ DO NOT bypass Release Gates before deploying — `04-08-release-management-policy.md` - ❌ DO NOT bypass Release Gates before deploying — `04-08-release-management-policy.md`
- ❌ DO NOT start Migration without Gate #1 approval — `03-06-migration-business-scope.md` - ❌ DO NOT start Migration without Gate #1 approval — `03-06-migration-business-scope.md`
- ❌ DO NOT use TypeORM Migrations — modify schema SQL directly (ADR-009) - ❌ DO NOT use TypeORM Migrations — modify schema SQL directly (ADR-009)
- ❌ DO NOT give Ollama direct DB access — all writes via DMS API (ADR-018) - ❌ DO NOT give Ollama direct DB access — all writes via DMS API (ADR-023/023A)
- ❌ DO NOT use `any` TypeScript type anywhere - ❌ DO NOT use `any` TypeScript type anywhere
--- ---
@@ -325,7 +325,7 @@ If you change your mind mid-project:
# Run version validation # Run version validation
./scripts/bash/validate-versions.sh ./scripts/bash/validate-versions.sh
# Fix by updating all files to v1.9.0 # Fix by updating all files to v1.9.6
# Then re-run validation to confirm # Then re-run validation to confirm
``` ```
+145 -37
View File
@@ -1,56 +1,164 @@
# NAP-DMS Project Context & Core Rules # NAP-DMS Project Context & Rules
- Version: 1.9.3 - For: Devin Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
- Last Updated: 2026-05-15 - Version: 1.9.10 | Last synced from repo: 2026-06-06
- Status: Production Ready - Repo: [https://git.np-dms.work/np-dms/lcbp3](https://git.np-dms.work/np-dms/lcbp3)
- Canonical Source: AGENTS.md - Skill pack: `.agents/skills/` (v1.9.0, 21 skills) — see [`skills/README.md`](./.agents/skills/README.md) + [`skills/_LCBP3-CONTEXT.md`](./.agents/skills/_LCBP3-CONTEXT.md)
## 🎭 Role & Persona ## 🧠 Role & Persona
Act as a **Senior Full Stack Developer** specialized in NestJS, Next.js, and TypeScript. Act as **Senior Full Stack Developer** specialized in NestJS, Next.js, TypeScript, DMS. Focus: Data Integrity, Security, Maintainability, Performance.
Focus on **Data Integrity, Security, Maintainability, and Performance**.
You are a **Document Intelligence Engine**every response must be precise, spec-compliant, and production-ready. You are a **Document Intelligence Engine**not a general chatbot. Every response must be **precise**, **spec-compliant**, and **production-ready**.
--- ---
## 🔴 Tier 1 — CRITICAL (CI BLOCKER) ## 🧩 Thought & Planning Protocol (Powered by Everything-Claude-Code)
1. **Identifier Strategy (ADR-019)** Before writing any code or taking any action in Tier 1 and Tier 2, the AI must demonstrate the following thinking process:
- ห้ามใช้ `parseInt()` บน UUID
- ใช้ `publicId` (string) สำหรับการติดต่อภายนอก (API/URL) เท่านั้น ### 1. Analysis Phase (Explore & Analyze)
2. **Database Management (ADR-009)**
- ห้ามใช้ TypeORM Migrations หรือ `synchronize: true` Problem Understanding: Restate what the user wants in clear, unambiguous terms.
- การแก้ Schema ต้องแก้ที่ SQL files ใน `specs/03-Data-and-Storage/` เท่านั้น Context Search: Identify the relevant Spec files or ADRs from the "Key Spec Files" table that must be read before starting.
3. **Security (ADR-016)** Constraints Identification: Identify key constraints (e.g. Security rules, UUID patterns, or Domain terminology).
- ทุก API ต้องมี `CASL Guard` และตรวจสอบสิทธิ์ผ่าน RBAC Matrix
- การอัปโหลดไฟล์ต้องเป็น Two-Phase (Temp → Commit) และต้องสแกน ClamAV ### 2. Planning Phase (Plan)
4. **AI Boundary (ADR-018)**
- AI Agent ต้องทำงานผ่าน DMS API เท่านั้น ห้ามเขียนลง Database หรือ Storage โดยตรง Alternative Exploration: Present at least 2 solution approaches (where possible) with pros/cons analysis.
Step-by-Step Roadmap: Write a file-by-file plan of changes before executing.
Verification Plan: Specify how to verify the work is complete (e.g. "which unit tests to write" or "which file to check the schema in").
### 3. Execution & Refinement (Execute & Refine)
Follow the plan step by step, and pause to ask if any uncertainty arises.
If significant logic changes are made, summarize what was done for the user after completion.
--- ---
## 📐 TypeScript Rules & Coding Standards (v1.9.0) ## ⚙️ DMS Workflow Engine Protocol
- **File Header:** ทุกไฟล์ต้องขึ้นต้นด้วย `// File: path/filename` กฎนี้ใช้คุม Logic การไหลของเอกสาร (RFA, Transmittal, Correspondence) เพื่อป้องกัน Race Condition และรักษาความถูกต้องของสถานะ:
- **Change Log:** ต้องมีส่วน `// Change Log` ที่หัวไฟล์
- **Language:** ตัวแปร/Logic เป็น English, Comment/JSDoc เป็น **Thai** - **State Management:** ตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ เพื่อป้องกันการอนุมัติซ้ำซ้อน (ดู `05-06-code-snippets.md` `[workflow-transition]`)
- **Explicit Typing:** กำหนด Type ให้ชัดเจนเสมอ ห้ามใช้ `any` - **Concurrency Control:** การจอนเลขที่เอกสารต้องใช้ **Redis Redlock** หรือ **TypeORM `@VersionColumn`** เท่านั้น (ADR-002)
- **Cleanliness:** ห้ามมีบรรทัดว่างในฟังก์ชัน, Export ได้เพียง 1 symbol หลักต่อไฟล์ - **Background Jobs:** งานนานหรือการแจ้งเตือนต้องส่งไปทำที่ **BullMQ** ห้ามเขียนแบบ Inline (ADR-008)
- **Term Consistency:** ห้ามใช้ "Approval Flow" ให้ใช้ **"Workflow Engine"** และห้ามใช้ "Letter" ให้ใช้ **"Correspondence"** (หมายเหตุ: "จดหมาย" ในคอมเมนต์ภาษาไทย = Correspondence ที่ครอบคลุมทุกประเภท)
--- ---
## 📁 Specs Folder Organization (Hybrid Model) ## 🛡️ Security & Integrity Audit Protocol
- **Core (00-06):** ข้อมูลอ้างอิงถาวร (Permanent Source of Truth) กฎนี้ให้ AI เป็น Gatekeeper ก่อน Commit โดยเน้น **Tier 1 — CRITICAL**:
- **Feature (100-300):** สำหรับงาน Implementation ใหม่
- `100-Infrastructures/` - **UUID Validation:** ตรวจสอบว่าเป็น **UUIDv7** และห้ามใช้ `parseInt()` บน UUID (ADR-019)
- `200-fullstacks/` - **RBAC Check:** API ใหม่ต้องมี **CASL Guard** และตรวจสอบ 4-Level RBAC Matrix (ADR-016)
- `300-others/` - **Data Isolation:** AI ต้องรันผ่าน **Ollama บน Admin Desktop** เท่านั้น ห้ามเข้าถึง DB/storage โดยตรง (ADR-023)
- **Input Sanitization:** ไฟล์อัปโหลดต้องผ่าน **Two-Phase** (Temp → Commit) และสแกนด้วย **ClamAV** (ADR-016)
--- ---
## 🔄 Workflow Engine (ADR-001/021) ## 🧭 Rule Enforcement Tiers
- ใช้ DSL-based state machine ### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
- การเปลี่ยนสถานะต้องตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ
- งานที่ใช้เวลานานต้องส่งไปที่ **BullMQ** เท่านั้น Build fails หากละเมิด:
- Security (Auth, RBAC, Validation)
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
- Database correctness — verify schema before writing queries
- File upload security (ClamAV + whitelist)
- AI validation boundary (ADR-023)
- Error handling strategy (ADR-007)
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
Must fix ก่อน merge:
- Architecture patterns (thin controller, business logic in service)
- Test coverage (80%+ business logic, 70%+ backend overall)
- Cache invalidation
- Naming conventions
- **TypeScript Standards:** Missing JSDoc, explicit types, or file headers
### 🟢 Tier 3 — SPECIALIZED WORK
Requires domain-specific knowledge:
- **ADR-021 Integration:** Workflow Engine & Context implementation
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
- **Complex Business Logic:** Multi-step workflows with state management
- **Performance Optimization:** Database queries, caching strategies, bulk operations
### 🔵 Tier 4 — GUIDELINES
Best practice — follow when possible:
- Code style / formatting (Prettier handles)
- Comment completeness
- Minor optimizations
---
## 📐 TypeScript Rules & Coding Standards
### 📝 Core Standards
- **Strict Mode** — all strict checks enforced.
- **ZERO `any` types** — use proper types or `unknown` + narrowing.
- **ZERO `console.log`** — use NestJS `Logger` (backend) or remove (frontend).
- **English for Code** — use English for all code identifiers, variables, and logic.
- **Thai for Comments** — use Thai for comments, documentation, and JSDoc.
- **Explicit Typing** — explicitly define types for all variables, parameters, and return values.
- **JSDoc** — use JSDoc for all public classes and methods.
### 🏗️ File & Function Structure
- **File Headers** — every file MUST start with `// File: path/filename` on the first line.
- **Change Log** — include `// Change Log` at the top of the file to track modifications.
- **Single Export** — export **only one main symbol** per file.
- **Function Style** — avoid unnecessary blank lines inside functions.
---
## 🚫 Forbidden Actions
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
---
## 🚧 Out of Scope — Never Do Without Explicit Approval
| ❌ Never Do Autonomously | ⚠️ Why Approval Is Required |
| --------------------------------------------------------------- | ---------------------------------------------------------------- |
| `DROP` or `RENAME` a column / table | Irreversible data loss — requires DBA + PM sign-off |
| Push directly to `main` / `master` branch | Bypasses CI, code review, and release gates |
| Generate or insert seed data into production database | May corrupt live data or violate business state invariants |
| Delete files from permanent storage | Files may be referenced in active documents or audit trails |
| Modify RBAC permission matrix without security team approval | Defines access control for all users — security boundary change |
| Upgrade major library versions (NestJS, Next.js, TypeORM, etc.) | Breaking changes require full regression test cycle |
| Disable or modify authentication / authorization guards | Creates unguarded endpoints — immediate security risk |
| Change Redis lock TTL or disable Redlock | Risk of document number race condition (ADR-002) |
| Create or supersede an ADR unilaterally | Architecture decisions require team consensus and review process |
| Add new columns to production tables without schema review | Must update Data Dictionary + downstream queries simultaneously |
+3 -3
View File
@@ -9,9 +9,9 @@
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days 5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints 6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan 7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
8. **AI Isolation (ADR-018):** Ollama on Admin Desktop ONLY — NO direct DB/storage access 8. **AI Isolation (ADR-023/023A):** Ollama on Admin Desktop ONLY — NO direct DB/storage access; 2-model stack `gemma4:e4b Q8_0` + `nomic-embed-text`; all inference via BullMQ (`ai-realtime` / `ai-batch`)
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages 9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
10. **AI Integration (ADR-020):** RFA-First approach with unified pipeline architecture 10. **AI Integration (ADR-023/023A):** RFA-First approach; n8n orchestrates Migration Phase only via DMS API — never calls Ollama directly; `QdrantService.search()` requires `projectPublicId` as mandatory param
11. **AI Audit Trail:** Log all AI interactions and human validations 11. **AI Audit Trail:** Log all AI interactions and human validations
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse 12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
@@ -26,7 +26,7 @@
- [ ] No SQL injection vulnerabilities - [ ] No SQL injection vulnerabilities
- [ ] File upload validation (whitelist + ClamAV) - [ ] File upload validation (whitelist + ClamAV)
- [ ] Rate limiting applied to auth endpoints - [ ] Rate limiting applied to auth endpoints
- [ ] AI boundary enforcement (ADR-023) - no direct DB/storage access - [ ] AI boundary enforcement (ADR-023/023A) - no direct DB/storage access
- [ ] AI audit logging implemented for AI interactions - [ ] AI audit logging implemented for AI interactions
- [ ] AI outputs validated before use (human-in-the-loop) - [ ] AI outputs validated before use (human-in-the-loop)
- [ ] Error handling follows ADR-007 layered classification - [ ] Error handling follows ADR-007 layered classification
+1 -1
View File
@@ -1,4 +1,4 @@
# TypeScript Rules (v1.9.3) # TypeScript Rules
## Core Standards ## Core Standards
+18 -12
View File
@@ -2,17 +2,17 @@
## DMS Glossary ## DMS Glossary
| ✅ Use | ❌ Don't Use | | ✅ Use | ❌ Don't Use | คำอธิบายเพิ่มเติม |
| ------------------ | ------------------------------------- | | ------------------ | ------------------------------------- | ------------------------------------------------ |
| Correspondence | Letter, Communication, Document | | Correspondence | Letter, Communication, Document | ครอบคลุมทุกประเภท: Letter, RFA, Memo, ฯลฯ |
| RFA | Approval Request, Submit for Approval | | RFA | Approval Request, Submit for Approval | เอกสารขออนุมัติ (ชนิดหนึ่งของ Correspondence) |
| Transmittal | Delivery Note, Cover Letter | | Transmittal | Delivery Note, Cover Letter | เอกสารนำส่ง (ชนิดหนึ่งของ Correspondence) |
| Circulation | Distribution, Routing | | Circulation | Distribution, Routing | ใบเวียนเอกสารภายใน (ชนิดหนึ่งของ Correspondence) |
| Shop Drawing | Construction Drawing | | Shop Drawing | Construction Drawing | แบบก่อสร้าง |
| Contract Drawing | Design Drawing, Blueprint | | Contract Drawing | Design Drawing, Blueprint | แบบคู่สัญญา |
| Workflow Engine | Approval Flow, Process Engine | | Workflow Engine | Approval Flow, Process Engine | เครื่องมือจัดการลำดับงาน |
| Document Numbering | Document ID, Auto Number | | Document Numbering | Document ID, Auto Number | ระบบจัดการเลขที่เอกสาร |
| RBAC | Permission System (generic) | | RBAC | Permission System (generic) | การควบคุมสิทธิ์ตามบทบาท |
## Full Glossary ## Full Glossary
@@ -23,13 +23,19 @@
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
| Document | Path | Use When | | Document | Path | Use When |
| ----------------------- | ----------------------------------------------------------------- | ------------------------------- | | ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology | | **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query | | **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules | | **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows | | **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work | | **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work | | **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns | | **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns | | **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals | | **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
+19 -19
View File
@@ -2,25 +2,25 @@
## ❌ Never Do This ## ❌ Never Do This
| ❌ Forbidden | ✅ Correct Approach | | ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
| ----------------------------------------------- | ----------------------------------------------------------------- | | ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| SQL Triggers for business logic | NestJS Service methods | | SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
| `.env` files in production | `docker-compose.yml` environment section | | `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
| TypeORM migration files | Edit schema SQL directly (ADR-009) | | TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
| Inventing table/column names | Verify against `lcbp3-v1.9.0-schema-02-tables.sql` | | Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
| `any` TypeScript type | Proper types / generics | | `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | | `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
| `req: any` in controllers | `RequestWithUser` typed interface | | `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | | `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
| Exposing INT PK in API responses | UUIDv7 (ADR-019) | | Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023) | | AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
| Direct file operations bypassing StorageService | `StorageService` for all file moves | | Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
| Inline email/notification sending | BullMQ queue job | | Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | | Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
| AI direct cloud API calls | On-premises Ollama only (ADR-023) | | AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023) | | AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama/Qdrant (ADR-023A) | | n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
| Qdrant query without projectPublicId filter | QdrantService.search(projectPublicId: string) required (ADR-023A) | | Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
## Schema Changes (ADR-009) ## Schema Changes (ADR-009)
+1 -2
View File
@@ -1,4 +1,3 @@
# Frontend Patterns (Next.js) # Frontend Patterns (Next.js)
## Form Handling ## Form Handling
@@ -17,7 +16,7 @@ interface ProjectOption {
} }
// Select options // Select options
const options = contracts.map(c => ({ const options = contracts.map((c) => ({
label: `${c.contractName} (${c.contractCode})`, label: `${c.contractName} (${c.contractCode})`,
value: c.publicId!, // Use publicId, no fallback to id value: c.publicId!, // Use publicId, no fallback to id
})); }));
+173 -5
View File
@@ -9,7 +9,7 @@
3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql` 3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql`
4. **Check data dictionary** — confirm field meanings + business rules 4. **Check data dictionary** — confirm field meanings + business rules
5. **Scan edge cases**`01-06-edge-cases-and-rules.md` 5. **Scan edge cases**`01-06-edge-cases-and-rules.md`
6. **Check ADRs** — verify decisions align (ADR-009, ADR-018, ADR-019) 6. **Check ADRs** — verify decisions align (ADR-009, ADR-019, ADR-023)
7. **Write code** — TypeScript strict, no `any`, no `console.log` 7. **Write code** — TypeScript strict, no `any`, no `console.log`
## 🟡 Normal Work — UI / Feature / Integration ## 🟡 Normal Work — UI / Feature / Integration
@@ -28,15 +28,183 @@
- Add minimal test if logic changed - Add minimal test if logic changed
- Check forbidden patterns before commit - Check forbidden patterns before commit
### 🟢 Specialized Work — ADR-021, AI Runtime Layer, Complex Logic
**MUST complete:**
1. **Domain Knowledge Check** - Read relevant ADRs (ADR-021, ADR-023/023A, ADR-024~028)
2. **Pattern Verification** - Check existing implementations in codebase
3. **Specialized Requirements** - Follow domain-specific patterns
4. **Complex Logic Testing** - Multi-scenario test coverage
5. **Performance Validation** - Load testing if applicable
**For ADR-021 Integration:**
- Read ADR-021 - Integrated workflow & step attachments
- Check ADR-001 - Unified workflow engine patterns
- Verify WorkflowEngineService - Polymorphic instance handling
- Add workflow fields - Expose workflowInstanceId, workflowState, availableActions
- Include IntegratedBanner - Frontend workflow lifecycle display
- Test workflow transitions - State changes and action validation
**For AI Infrastructure (ADR-023/023A):**
- Verify AI boundary enforcement - No direct DB/storage access
- Check BullMQ 2-queue setup - ai-realtime + ai-batch
- Validate Qdrant multi-tenancy - projectPublicId filter required
- Test human-in-the-loop validation workflows
- Audit AI interaction logging to ai_audit_logs
**For AI Runtime Layer (ADR-024/025/026/027):**
- ADR-024: Pattern Layer first (ai_intent_patterns DB + Redis cache 5 min) → LLM Fallback (gemma4:e4b, semaphore max=3)
- ADR-025: Tool Registry dispatch — AI Gateway → Tool → Business Service; ToolResult DTO must use publicId only
- ADR-026: useAiChat() hook + side-panel UI; streaming response via SSE; TanStack Query cache
- ADR-027: Admin Console — dynamic model/prompt/intent control; CASL-guarded admin-only endpoints
**For Migration Pipeline (ADR-028):**
- Use Staging Queue pattern — never write directly to production tables
- Post-migration cleanup process required after each batch
- Migration Validation Gates must pass before promoting to production
**Expected output:**
- Backend services expose specialized context fields
- Frontend components use domain-specific patterns
- Complex state management with proper validation
- Performance metrics within acceptable thresholds
- Comprehensive test coverage for edge cases
---
## Context-Aware Triggers ## Context-Aware Triggers
| Request | Files to Check | Expected Response | | Request | Files to Check | Expected Response |
| -------------------- | -------------------------------------------------------------------- | --------------------------------------------------- | | --------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard | | "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard |
| "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases.md` | RHF+Zod + TanStack Query + Thai comments | | "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases-and-rules.md` | RHF+Zod + TanStack Query + Thai comments |
| "เพิ่ม field ใหม่" | `ADR-009`, `data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity | | "เพิ่ม field ใหม่" | `ADR-009`, `03-01-data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity |
| "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor | | "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor |
| "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow | | "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow |
| "ตรวจสอบ permission" | `seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix | | "ตรวจสอบ permission" | `lcbp3-v1.9.0-seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix |
| "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy | | "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy |
| "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns | | "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns |
| "AI integration" | `ADR-023`, `ADR-023A`, `ADR-024`, `ADR-025` | AI boundary + 2-model stack + BullMQ queue policy + Intent/Tool Layer |
| "Error handling" | `ADR-007` | Layered error classification + recovery |
| "File upload" | `ADR-016`, `05-02-backend-guidelines.md`, `03-Data-and-Storage/03-03-file-storage.md` | Two-phase upload → temp → commit; ClamAV + whitelist |
| "Notifications / Queue" | `ADR-008`, `05-02-backend-guidelines.md` | BullMQ job — never inline; check retry + dead-letter |
| "Add i18n / translate" | `05-08-i18n-guidelines.md` | i18n keys only — no hardcoded text |
| "Workflow / DSL" | `ADR-001`, `01-03-modules/01-03-06-unified-workflow.md` | DSL state machine + WorkflowEngineService |
| "Document numbering" | `ADR-002`, `01-02-business-rules/01-02-02-doc-numbering-rules.md` | Redis Redlock + DB optimistic lock (double-lock) |
| "ตรวจสอบ Workflow" | `01-06-edge-cases-and-rules.md`, `05-02-backend-guidelines.md`, `ADR-001`, `ADR-002` | เช็คการเปลี่ยน State, คิว BullMQ และการล็อกเลขที่เอกสาร |
| "Transmittal submit" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | submit() with EC-RFA-004 validation |
| "Circulation reassign" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | reassignRouting() with EC-CIRC-001 |
| "สร้าง workflow ใหม่" | `ADR-001`, `ADR-021`, `specs/200-fullstacks/203-unified-workflow-engine/` | DSL workflow definition + WorkflowEngineService setup |
| "ตรวจสอบ AI boundary" | `ADR-023`, `ADR-023A` | Verify Ollama isolation + BullMQ queues + Qdrant projectPublicId filter |
| "Intent classification" | `ADR-024`, `specs/200-fullstacks/224-intent-classification/` | Pattern Layer → LLM Fallback; ai_intent_patterns; Redis cache 5 min |
| "AI Tool Layer" | `ADR-025`, `specs/200-fullstacks/225-ai-tool-layer-architecture/` | Tool Registry; CASL-guarded dispatch; ToolResult publicId only |
| "Document Chat UI" | `ADR-026`, `specs/200-fullstacks/226-document-chat-ui-pattern/` | Side-panel; useAiChat() hook; streaming SSE; TanStack Query cache |
| "AI Admin Console" | `ADR-027`, `specs/200-fullstacks/227-ai-admin-console/` | Dynamic model/prompt/intent control; admin-only CASL endpoints |
| "Migration refactor" | `ADR-028`, `specs/200-fullstacks/228-migration-arch-refactor/` | Staging Queue; post-migration cleanup; validation gates |
| "จัดการ document numbering" | `ADR-002`, `specs/03-Data-and-Storage/03-04-document-numbering.md` | Redis Redlock + template system + preview/override workflows |
| "Audit ความปลอดภัย" | `ADR-016`, `ADR-019`, `ADR-023`, `ADR-023A` | ตรวจสอบ UUID pattern, CASL Guard, AI Boundary และ Qdrant multi-tenancy |
| "แก้ bug / bugfix" | `.agents/workflows/bugfix.md`, `error-catalog.md` | ใช้ bugfix workflow สำหรับเคสที่สาเหตุชัดเจน |
| "ตรวจแอปจริง" | `.windsurf/workflows/check-real-app.md` | ตรวจ endpoint/UI/console หลัง build pass — No Fake Evidence |
| "งานค้าง / resume" | `.windsurf/workflows/resume-pending-work.md` | อ่าน checkpoint เดิม → ตรวจ build → วางแผนต่อโดยไม่ทำงานซ้ำ |
---
## 🔌 MCP MariaDB Tools
MCP MariaDB server ให้เครื่องมือสำหรับตรวจสอบและจัดการ database โดยตรง ใช้สำหรับ:
- ตรวจสอบ schema กับ spec file `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
- Debug ปัญหา database โดยไม่ต้องเข้า MySQL client
- ตรวจสอบ data ใน production/staging
- Validate การเปลี่ยนแปลง schema ก่อน deploy
### Available Tools
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|------|----------|------------------|
| `mcp1_mysql_test_connection` | ทดสอบ connection กับ database | ตรวจสอบว่า MCP server เชื่อมต่อได้ |
| `mcp1_mysql_show_databases` | แสดง databases ทั้งหมด | ดูว่ามี database อะไรบ้าง |
| `mcp1_mysql_show_tables` | แสดง tables ทั้งหมดใน database | ดูรายชื่อ tables ใน `lcbp3` |
| `mcp1_mysql_describe_table` | ดู structure/columns ของ table | ตรวจสอบ columns, types, keys ของ `correspondences` |
| `mcp1_mysql_query` | รัน SELECT query | ดู data ใน table หรือ join query |
| `mcp1_mysql_insert` | INSERT data | เพิ่ม seed data หรือ test data |
| `mcp1_mysql_update` | UPDATE data | แก้ไข data ใน table |
| `mcp1_mysql_delete` | DELETE data | ลบ data ใน table |
### การใช้งานร่วมกับ Development Flow
**เมื่อเขียน query ใหม่:**
1. ใช้ `mcp1_mysql_describe_table` เพื่อตรวจสอบ columns และ types
2. เปรียบเทียบกับ `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
3. ใช้ `mcp1_mysql_query` เพื่อทดสอบ query ก่อน implement
**เมื่อเปลี่ยน schema (ADR-009):**
1. ใช้ `mcp1_mysql_describe_table` เพื่อดู structure ปัจจุบัน
2. สร้าง SQL delta ใน `specs/03-Data-and-Storage/deltas/`
3. ใช้ `mcp1_mysql_query` เพื่อตรวจสอบผลลัพธ์หลัง apply delta
**เมื่อ debug ปัญหา database:**
1. ใช้ `mcp1_mysql_query` เพื่อดู data จริง
2. เปรียบเทียบกับ spec และ data dictionary
3. ตรวจสอบ foreign keys และ constraints
### ข้อควรระวัง
- **❌ ห้ามใช้ MCP MariaDB สำหรับ DDL operations** (CREATE/ALTER/DROP) โดยตรง — ต้องใช้ SQL delta ตาม ADR-009
- **✅ ใช้สำหรับ DQL/DML operations** (SELECT/INSERT/UPDATE/DELETE) เพื่อ debug และ test เท่านั้น
- **⚠️ ระวัง DELETE operations** — อาจทำให้เสีย data ใน production
- **✅ ตรวจสอบ schema กับ spec file เสมอ** ก่อนเขียน query
---
## 🧠 MCP Memory Tools
MCP Memory server ให้เครื่องมือสำหรับจัดการ Knowledge Graph และ Long-term Memory ใช้สำหรับ:
- จัดเก็บความรู้และ context ของโปรเจกต์ในรูปแบบ Graph (Entities + Relations + Observations)
- ค้นหาและดึงข้อมูล context จาก memory ที่บันทึกไว้ใน session ก่อนหน้า
- สร้าง/แก้ไข/ลบ entities, relations, และ observations ใน knowledge graph
### Available Tools
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|------|----------|------------------|
| `mcp3_create_entities` | สร้าง entities ใหม่หลายตัวพร้อม observations | สร้าง entity ใหม่เช่น Project, User, Task |
| `mcp3_create_relations` | สร้าง relations ระหว่าง entities | สร้าง relation: Project → has → User |
| `mcp3_add_observations` | เพิ่ม observations ให้ entity ที่มีอยู่แล้ว | เพิ่ม context เพิ่มเติมให้ entity |
| `mcp3_delete_entities` | ลบ entities และ relations ที่เกี่ยวข้อง | ลบ entity ที่ไม่ใช้แล้ว |
| `mcp3_delete_relations` | ลบ relations ระหว่าง entities | ลบ relation ที่ผิดหรือไม่ใช้แล้ว |
| `mcp3_delete_observations` | ลบ observations จาก entity | ลบ context ที่ผิดหรือล้าสุด |
| `mcp3_open_nodes` | ดึงข้อมูล entities ตามชื่อ | ดึง entity ที่ระบุชื่อ |
| `mcp3_read_graph` | อ่าน knowledge graph ทั้งหมด | ดูทั้ง graph structure |
| `mcp3_search_nodes` | ค้นหา entities ตาม query | ค้นหา entity จากชื่อ, type, หรือ observation |
### การใช้งานร่วมกับ Development Flow
**เมื่อบันทึก context ใหม่:**
1. ใช้ `mcp3_create_entities` เพื่อสร้าง entities ใหม่ (ถ้ายังไม่มี)
2. ใช้ `mcp3_create_relations` เพื่อเชื่อมโยง entities
3. ใช้ `mcp3_add_observations` เพื่อเพิ่ม context/observations
**เมื่อค้นหา context:**
1. ใช้ `mcp3_search_nodes` เพื่อค้นหา entities ที่เกี่ยวข้อง
2. ใช้ `mcp3_open_nodes` เพื่อดึงข้อมูล entities ที่ต้องการ
3. ใช้ `mcp3_read_graph` เพื่อดู relations ระหว่าง entities
**เมื่อแก้ไข context:**
1. ใช้ `mcp3_add_observations` เพื่อเพิ่ม observations ใหม่
2. ใช้ `mcp3_delete_observations` เพื่อลบ observations ที่ผิด
3. ใช้ `mcp3_create_relations` หรือ `mcp3_delete_relations` เพื่อปรับ relations
### ข้อควรระวัง
- **✅ ใช้สำหรับบันทึก context ที่ต้องใช้ร่วมกันหลาย session** — เช่น การตัดสินใจสำคัญ, architecture decisions, rollout history
- **⚠️ ระวังการลบ entities** — อาจทำให้เสีย context ที่ยังใช้งานอยู่
- **✅ ตรวจสอบว่า entity มีอยู่แล้วก่อนสร้าง** — ใช้ `mcp3_search_nodes` หรือ `mcp3_open_nodes` ก่อน
- **✅ ใช้ชื่อ entity ที่ชัดเจนและไม่ซ้ำกัน** — เพื่อป้องกันความสับสน
+1 -1
View File
@@ -1,4 +1,3 @@
# Commit Checklist # Commit Checklist
## Pre-Commit Verification ## Pre-Commit Verification
@@ -28,6 +27,7 @@ type(scope): description
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
Examples: Examples:
- `feat(correspondence): add originator organization validation` - `feat(correspondence): add originator organization validation`
- `fix(uuid): correct parseInt usage to string comparison` - `fix(uuid): correct parseInt usage to string comparison`
- `spec(agents): bump to v1.8.5 - refactor structure` - `spec(agents): bump to v1.8.5 - refactor structure`
+2 -8
View File
@@ -1,4 +1,3 @@
# ADR-007 Error Handling Strategy # ADR-007 Error Handling Strategy
## CRITICAL RULES ## CRITICAL RULES
@@ -12,7 +11,7 @@
## Error Classification ## Error Classification
| Error Type | Description | User Message | Technical Log | | Error Type | Description | User Message | Technical Log |
|------------|-------------|--------------|---------------| | -------------- | ------------------------- | ------------------------ | -------------------------- |
| **Validation** | Input validation failures | Clear field-level errors | Full validation details | | **Validation** | Input validation failures | Clear field-level errors | Full validation details |
| **Business** | Business rule violations | Actionable guidance | Business context + user ID | | **Business** | Business rule violations | Actionable guidance | Business context + user ID |
| **System** | Infrastructure failures | Generic "try again" | Full stack trace + metrics | | **System** | Infrastructure failures | Generic "try again" | Full stack trace + metrics |
@@ -22,12 +21,7 @@
```typescript ```typescript
// Custom Exception Hierarchy // Custom Exception Hierarchy
export class BusinessException extends HttpException { export class BusinessException extends HttpException {
constructor( constructor(message: string, userMessage: string, recoveryAction?: string, errorCode?: string) {
message: string,
userMessage: string,
recoveryAction?: string,
errorCode?: string
) {
super({ message, userMessage, recoveryAction, errorCode }, 400); super({ message, userMessage, recoveryAction, errorCode }, 400);
} }
} }
+13 -8
View File
@@ -3,7 +3,7 @@
## CRITICAL RULES ## CRITICAL RULES
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop) - **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
- **ALWAYS** use ADR-023A 2-model stack (gemma4:e4b Q8_0 + nomic-embed-text) - **ALWAYS** use ADR-034 model stack (typhoon2.5-np-dms:latest + typhoon-np-dms-ocr:latest + nomic-embed-text)
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention - **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
- **NEVER** allow AI direct database/storage access - **NEVER** allow AI direct database/storage access
- **ALWAYS** implement human-in-the-loop validation - **ALWAYS** implement human-in-the-loop validation
@@ -26,8 +26,8 @@ n8n (Migration) → DMS API → BullMQ → Admin Desktop (Ollama) → Backend Va
| ----------------- | ------------------------- | ------------------------------------------------------------------------ | | ----------------- | ------------------------- | ------------------------------------------------------------------------ |
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging | | **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) | | **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
| **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e4b Q8_0 (LLM) + nomic-embed-text (Embedding) | | **Ollama Engine** | Admin Desktop (Desk-5439) | typhoon2.5-np-dms:latest (Main LLM) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) + nomic-embed-text (Embedding) |
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) | | **OCR Engine** | Admin Desktop (Desk-5439) | Tesseract OCR + Typhoon OCR (via Ollama) + PyThaiNLP (Thai/English text extraction) |
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) | | **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
## Backend Implementation (NestJS) ## Backend Implementation (NestJS)
@@ -76,7 +76,7 @@ export class AiService {
async extractMetadata(documentId: string): Promise<AIMetadata> { async extractMetadata(documentId: string): Promise<AIMetadata> {
// 1. Validate permissions // 1. Validate permissions
// 2. Queue job to BullMQ (ai-batch or ai-realtime) // 2. Queue job to BullMQ (ai-batch or ai-realtime)
// 3. Worker sends to Admin Desktop AI (gemma4:e4b Q8_0) // 3. Worker sends to Admin Desktop AI (typhoon2.5-np-dms:latest)
// 4. Validate AI response // 4. Validate AI response
// 5. Log audit trail to ai_audit_logs // 5. Log audit trail to ai_audit_logs
// 6. Return validated results // 6. Return validated results
@@ -113,12 +113,12 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
- **n8n Boundary:** n8n MUST call DMS API → BullMQ, NEVER Ollama/Qdrant directly - **n8n Boundary:** n8n MUST call DMS API → BullMQ, NEVER Ollama/Qdrant directly
- **GPU Overload Prevention:** BullMQ 2-queue (ai-realtime + ai-batch) with concurrency=1 - **GPU Overload Prevention:** BullMQ 2-queue (ai-realtime + ai-batch) with concurrency=1
## ADR-023A Specific Rules ## ADR-034 Model Stack (supersedes ADR-023A §2.1)
- **2-Model Stack:** gemma4:e4b Q8_0 (~4.0GB) + nomic-embed-text (~0.3GB) = ~4.3GB VRAM peak - **3-Model Config:** typhoon2.5-np-dms:latest (Main) + typhoon-np-dms-ocr:latest (OCR, keep_alive:0) + nomic-embed-text (Embedding)
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding) - **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap - **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR - **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else Tesseract OCR (with Typhoon OCR option)
- **Embed Auto-Trigger:** AUTO after commit (parallel), gap covered by DB search - **Embed Auto-Trigger:** AUTO after commit (parallel), gap covered by DB search
- **Threshold Recalibration:** After 100-500 docs, based on ai_audit_logs analysis - **Threshold Recalibration:** After 100-500 docs, based on ai_audit_logs analysis
@@ -129,7 +129,7 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch) - [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
- [ ] QdrantService with projectPublicId enforcement - [ ] QdrantService with projectPublicId enforcement
- [ ] DocumentReviewForm reusable component - [ ] DocumentReviewForm reusable component
- [ ] Admin Desktop Ollama (gemma4:e4b Q8_0 + nomic-embed-text) + PaddleOCR setup - [ ] Admin Desktop Ollama (typhoon2.5-np-dms:latest + typhoon-np-dms-ocr:latest + nomic-embed-text) setup
- [ ] n8n workflow orchestration (Migration Phase only) - [ ] n8n workflow orchestration (Migration Phase only)
- [ ] AI audit logging and monitoring (ai_audit_logs) - [ ] AI audit logging and monitoring (ai_audit_logs)
- [ ] Human-in-the-loop validation workflows - [ ] Human-in-the-loop validation workflows
@@ -138,3 +138,8 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture) - `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current) - `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
- `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` (Pattern→LLM Fallback)
- `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` (Tool Registry)
- `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` (Chat UI)
- `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` (Admin Console)
- `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` (Migration Pipeline)
+33 -11
View File
@@ -4,13 +4,14 @@ Critical rules and guidelines for AI agents working on LCBP3-DMS.
## Version ## Version
- **Current:** v1.9.3 - **Current:** v1.9.6
- **Last Updated:** 2026-05-15 - **Last Updated:** 2026-05-22
- **Synced with:** `AGENTS.md` (v1.9.3) - **Synced with:** `AGENTS.md` (v1.9.6)
## Purpose ## Purpose
This directory contains rule files that define: This directory contains rule files that define:
- Project context and role expectations - Project context and role expectations
- Critical Tier 1 rules (CI blockers) - Critical Tier 1 rules (CI blockers)
- Coding standards and patterns - Coding standards and patterns
@@ -24,6 +25,7 @@ This directory contains rule files that define:
### 🔴 Tier 1 — CRITICAL (CI BLOCKER) ### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
Build fails immediately if violated: Build fails immediately if violated:
- Security (Auth, RBAC, Validation) - Security (Auth, RBAC, Validation)
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID - UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
- Database correctness — verify schema before writing queries - Database correctness — verify schema before writing queries
@@ -35,15 +37,28 @@ Build fails immediately if violated:
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW) ### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
Must fix before merge: Must fix before merge:
- Architecture patterns (thin controller, business logic in service) - Architecture patterns (thin controller, business logic in service)
- Test coverage (80%+ business logic, 70%+ backend overall) - Test coverage (80%+ business logic, 70%+ backend overall)
- Cache invalidation - Cache invalidation
- Naming conventions - Naming conventions
- TypeScript Standards: Missing JSDoc, explicit types, or file headers - TypeScript Standards: Missing JSDoc, explicit types, or file headers
### 🟢 Tier 3 — GUIDELINES ### 🟢 Tier 3 — SPECIALIZED WORK
Requires domain-specific knowledge:
- **ADR-021 Integration:** Workflow Engine & Context implementation
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
- **Complex Business Logic:** Multi-step workflows with state management
- **Performance Optimization:** Database queries, caching strategies, bulk operations
### 🔵 Tier 4 — GUIDELINES
Best practice — follow when possible: Best practice — follow when possible:
- Code style / formatting (Prettier handles) - Code style / formatting (Prettier handles)
- Comment completeness - Comment completeness
- Minor optimizations - Minor optimizations
@@ -53,7 +68,7 @@ Best practice — follow when possible:
### Core Rules (Tier 1 - CRITICAL) ### Core Rules (Tier 1 - CRITICAL)
| File | Purpose | | File | Purpose |
|------|---------| | ----------------------- | ------------------------------------------------------------------------------- |
| `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization | | `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization |
| `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only | | `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only |
| `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries | | `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries |
@@ -61,7 +76,7 @@ Best practice — follow when possible:
### Coding Standards ### Coding Standards
| File | Purpose | | File | Purpose |
|------|---------| | ------------------------- | ------------------------------------------------------- |
| `03-typescript.md` | TypeScript rules, file headers, i18n guidelines | | `03-typescript.md` | TypeScript rules, file headers, i18n guidelines |
| `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns | | `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns |
| `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling | | `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling |
@@ -69,14 +84,14 @@ Best practice — follow when possible:
### Domain & Workflow ### Domain & Workflow
| File | Purpose | | File | Purpose |
|------|---------| | -------------------------- | ------------------------------------------------------------- |
| `04-domain-terminology.md` | DMS glossary, key spec files priority table | | `04-domain-terminology.md` | DMS glossary, key spec files priority table |
| `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) | | `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) |
### Compliance & Architecture ### Compliance & Architecture
| File | Purpose | | File | Purpose |
|------|---------| | ------------------------- | -------------------------------------------------------------- |
| `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling | | `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling |
| `09-commit-checklist.md` | Pre-commit verification, commit message format | | `09-commit-checklist.md` | Pre-commit verification, commit message format |
| `10-error-handling.md` | ADR-007 error handling strategy, layered classification | | `10-error-handling.md` | ADR-007 error handling strategy, layered classification |
@@ -87,13 +102,19 @@ Best practice — follow when possible:
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
| Document | Path | Use When | | Document | Path | Use When |
|----------|------|----------| | ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology | | **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query | | **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules | | **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows | | **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work | | **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work | | **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns | | **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns | | **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals | | **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
@@ -103,10 +124,11 @@ Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > oth
When updating rules: When updating rules:
1. **Check AGENTS.md version** — Ensure rule files are synced 1. **Check AGENTS.md version** — Ensure rule files are synced
2. **Update version numbers** — Bump version in `00-project-context.md` and `03-typescript.md` 2. **Update version numbers** — Bump version in `00-project-context.md` only (03-typescript.md no longer has version)
3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, etc.) 3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, ADR-024~028)
4. **Add new forbidden actions** — When new patterns are identified as violations 4. **Add new forbidden actions** — When new patterns are identified as violations
5. **Update key spec files table** — When new ADRs or guidelines are added 5. **Update key spec files table** — When new ADRs or guidelines are added
6. **Update Tier 3 SPECIALIZED WORK** — When new domain-specific workflows are added
## Related Documents ## Related Documents
+1 -1
View File
@@ -42,7 +42,7 @@ init_agent_registry() {
[qwen]="Qwen Code" [qwen]="Qwen Code"
[opencode]="opencode" [opencode]="opencode"
[codex]="Codex CLI" [codex]="Codex CLI"
[windsurf]="Windsurf" [devin]="Devin"
[kilocode]="Kilo Code" [kilocode]="Kilo Code"
[auggie]="Auggie CLI" [auggie]="Auggie CLI"
[roo]="Roo Code" [roo]="Roo Code"
+6 -6
View File
@@ -30,12 +30,12 @@
# #
# 5. Multi-Agent Support # 5. Multi-Agent Support
# - Handles agent-specific file paths and naming conventions # - Handles agent-specific file paths and naming conventions
# - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, or Amazon Q Developer CLI # - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Devin, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, or Amazon Q Developer CLI
# - Can update single agents or all existing agent files # - Can update single agents or all existing agent files
# - Creates default Claude file if no agent files exist # - Creates default Claude file if no agent files exist
# #
# Usage: ./update-agent-context.sh [agent_type] # Usage: ./update-agent-context.sh [agent_type]
# Agent types: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|shai|q|bob|qoder # Agent types: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|devin|kilocode|auggie|shai|q|bob|qoder
# Leave empty to update all existing agent files # Leave empty to update all existing agent files
set -e set -e
@@ -609,8 +609,8 @@ update_specific_agent() {
codex) codex)
update_agent_file "$AGENTS_FILE" "Codex CLI" update_agent_file "$AGENTS_FILE" "Codex CLI"
;; ;;
windsurf) devin)
update_agent_file "$WINDSURF_FILE" "Windsurf" update_agent_file "$DEVIN_FILE" "Devin"
;; ;;
kilocode) kilocode)
update_agent_file "$KILOCODE_FILE" "Kilo Code" update_agent_file "$KILOCODE_FILE" "Kilo Code"
@@ -681,8 +681,8 @@ update_all_existing_agents() {
found_agent=true found_agent=true
fi fi
if [[ -f "$WINDSURF_FILE" ]]; then if [[ -f "$DEVIN_FILE" ]]; then
update_agent_file "$WINDSURF_FILE" "Windsurf" update_agent_file "$DEVIN_FILE" "Devin"
found_agent=true found_agent=true
fi fi
+10 -11
View File
@@ -1,8 +1,8 @@
# `.agents/skills/` — LCBP3 Agent Skill Pack # `.agents/skills/` — LCBP3 Agent Skill Pack
**Version:** 1.9.0 | **Last Updated:** 2026-05-17 | **Total Skills:** 23 **Version:** 1.9.0 | **Last Updated:** 2026-06-07 | **Total Skills:** 24
Agent skills for AI-assisted development in **Windsurf IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools). Agent skills for AI-assisted development in **Devin IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools).
--- ---
@@ -14,6 +14,7 @@ Agent skills for AI-assisted development in **Windsurf IDE** (and compatible age
├── skills.md # Overview + dependency matrix + health monitoring ├── skills.md # Overview + dependency matrix + health monitoring
├── _LCBP3-CONTEXT.md # Shared LCBP3 context injected into every speckit-* skill ├── _LCBP3-CONTEXT.md # Shared LCBP3 context injected into every speckit-* skill
├── README.md # (this file) ├── README.md # (this file)
├── save-memory/ # Session log & project memory update
├── nestjs-best-practices/ # Backend rules (40 rules across 10 categories) ├── nestjs-best-practices/ # Backend rules (40 rules across 10 categories)
├── next-best-practices/ # Frontend rules (Next.js 15+) ├── next-best-practices/ # Frontend rules (Next.js 15+)
├── e2e-testing/ # Playwright E2E testing patterns (POM, flaky tests, CI/CD) ├── e2e-testing/ # Playwright E2E testing patterns (POM, flaky tests, CI/CD)
@@ -30,12 +31,10 @@ Each skill directory contains:
--- ---
## 🚀 How Windsurf Invokes These Skills ## 🚀 How Devin Invokes These Skills
Windsurf exposes two entry points: 1. **Skill tool** — Devin discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
2. **Slash commands**`.devin/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
1. **Skill tool** — Windsurf discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
2. **Slash commands**`.windsurf/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
Both paths end up executing the same `SKILL.md` instructions. Both paths end up executing the same `SKILL.md` instructions.
@@ -66,13 +65,13 @@ Use `/00-speckit.all` to run specify → clarify → plan → tasks → analyze
From repo root: From repo root:
| Script | Purpose | | Script | Purpose |
| --------------------------------------------------------- | ----------------------------------------------------------- | | ------------------------------------------------------ | ---------------------------------------------------------- |
| `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch | | `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch |
| `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` | | `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` |
| `./.agents/scripts/bash/update-agent-context.sh windsurf` | Append tech entries to `AGENTS.md` | | `./.agents/scripts/bash/update-agent-context.sh devin` | Append tech entries to `AGENTS.md` |
| `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence | | `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence |
| `./.agents/scripts/bash/validate-versions.sh` | Version consistency check | | `./.agents/scripts/bash/validate-versions.sh` | Version consistency check |
| `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.windsurf/workflows/*.md` wrapper | | `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.devin/workflows/*.md` wrapper |
All scripts mirror to `.agents/scripts/powershell/*.ps1` for Windows. All scripts mirror to `.agents/scripts/powershell/*.ps1` for Windows.
@@ -97,7 +96,7 @@ To add a new skill:
1. Create `NAME/SKILL.md` with frontmatter: `name`, `description`, `version: 1.9.0`, `scope`, `depends-on`. 1. Create `NAME/SKILL.md` with frontmatter: `name`, `description`, `version: 1.9.0`, `scope`, `depends-on`.
2. Append an LCBP3 context reference pointing to `_LCBP3-CONTEXT.md`. 2. Append an LCBP3 context reference pointing to `_LCBP3-CONTEXT.md`.
3. Wrap with `.windsurf/workflows/NAME.md` so it becomes a slash command. 3. Wrap with `.devin/workflows/NAME.md` so it becomes a slash command.
4. Update [`skills.md`](./skills.md) dependency matrix. 4. Update [`skills.md`](./skills.md) dependency matrix.
5. Run `./.agents/scripts/bash/audit-skills.sh` → must pass. 5. Run `./.agents/scripts/bash/audit-skills.sh` → must pass.
+11 -4
View File
@@ -5,14 +5,14 @@
**Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System **Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
**Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI) **Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
**Version:** 1.8.9 (2026-04-18) **Version:** 1.9.7 (2026-05-25)
--- ---
## 📌 Canonical Rule Sources (read in this order) ## 📌 Canonical Rule Sources (read in this order)
1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`. 1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`.
2. **`specs/06-Decision-Records/`** — architectural decisions (22 ADRs); ADR priority > Engineering Guidelines. 2. **`specs/06-Decision-Records/`** — architectural decisions (29 ADRs); ADR priority > Engineering Guidelines.
3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns. 3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns.
4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation). 4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation).
5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails). 5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails).
@@ -29,6 +29,7 @@
- **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone. - **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone.
- **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread. - **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread.
- **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023) - **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023)
- **ADR-029 Dynamic Prompt Management:** Prompt templates in DB (`ai_prompts`), never hardcoded in processor; Redis cache `ai:prompt:active:{type}` TTL 60s; `activate()` runs in DB transaction + Redis DEL after commit; `system.manage_all` guard on all mutations.
- **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs. - **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs.
- **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`). - **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`).
- **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`). - **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`).
@@ -54,7 +55,7 @@
## 📁 Key Files for Generating / Validating Artifacts ## 📁 Key Files for Generating / Validating Artifacts
| When you need... | Read | | When you need... | Read |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------- | | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` | | A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` |
| A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs | | A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs |
| Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` | | Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` |
@@ -62,6 +63,12 @@
| Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` | | Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` |
| RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` | | RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` |
| Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` | | Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` |
| ADR-024 Intent Class. | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` |
| ADR-025 AI Tool Layer | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` |
| ADR-026 Chat UI | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` |
| ADR-027 AI Admin Console | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` |
| ADR-028 Migration Refactor | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` |
| ADR-029 Dynamic Prompts | `specs/06-Decision-Records/ADR-029-dynamic-prompt-management.md` |
--- ---
@@ -83,7 +90,7 @@
- [ ] Business comments in Thai, code identifiers in English - [ ] Business comments in Thai, code identifiers in English
- [ ] Schema changes via SQL directly (not migration) - [ ] Schema changes via SQL directly (not migration)
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+) - [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
- [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A for AI work) - [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A/024-029 for AI work)
- [ ] Domain glossary terms used correctly - [ ] Domain glossary terms used correctly
- [ ] Error handling: `Logger` + `HttpException` / `BusinessException` - [ ] Error handling: `Logger` + `HttpException` / `BusinessException`
- [ ] i18n keys used (no hardcode text) - [ ] i18n keys used (no hardcode text)
@@ -6454,7 +6454,7 @@ CREATE TABLE ai_audit_log (
user_id INT NOT NULL, user_id INT NOT NULL,
action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc. action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc.
file_id INT, file_id INT,
model VARCHAR(64), -- 'gemma-4:7b', 'paddleocr-v3' model VARCHAR(64), -- 'gemma-4:7b', 'typhoon-np-dms-ocr', 'tesseract-ocr'
confidence DECIMAL(4,3), confidence DECIMAL(4,3),
input_hash CHAR(64), -- SHA-256 of input for replay detection input_hash CHAR(64), -- SHA-256 of input for replay detection
output_summary JSON, output_summary JSON,
@@ -137,7 +137,7 @@ CREATE TABLE ai_audit_log (
user_id INT NOT NULL, user_id INT NOT NULL,
action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc. action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc.
file_id INT, file_id INT,
model VARCHAR(64), -- 'gemma-4:7b', 'paddleocr-v3' model VARCHAR(64), -- 'gemma-4:7b', 'typhoon-np-dms-ocr', 'tesseract-ocr'
confidence DECIMAL(4,3), confidence DECIMAL(4,3),
input_hash CHAR(64), -- SHA-256 of input for replay detection input_hash CHAR(64), -- SHA-256 of input for replay detection
output_summary JSON, output_summary JSON,
+198
View File
@@ -0,0 +1,198 @@
---
name: save-memory
description: บันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่
version: 1.9.0
scope: project-management
depends-on: []
user-invocable: true
---
# บันทึก Memory (Save Memory)
Skill นี้ใช้สำหรับบันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่ที่ reorganization แล้ว
## โครงสร้าง Memory ใหม่
```
memory/
├── README.md (index + overview)
├── mcp-tools.md (MCP MariaDB + Memory Tools)
└── project-memory-override.md (OS rules, Current Decisions, Environment, Next Session Focus)
specs/88-logs/
├── rollouts.md (Recent rollouts table)
└── session-YYYY-MM-DD-[topic].md (Session logs)
```
## ขั้นตอนการบันทึก Memory
### 1. สร้าง Session Log (ถ้ามีงาน session ใหม่)
เมื่อทำงาน session ใหม่ให้:
1. **สร้างไฟล์ session log ใหม่** ใน `specs/88-logs/`
- ชื่อไฟล์: `session-YYYY-MM-DD-[topic].md`
- ตัวอย่าง: `session-2026-06-07-memory-reorganization.md`
2. **บันทึกเนื้อหาใน session log**:
```markdown
# Session [N] — YYYY-MM-DD ([Topic])
## Summary
[สรุปสิ่งที่ทำใน session นี้]
## ปัญหาที่พบ (Root Cause)
[อธิบายปัญหาและสาเหตุ]
## การแก้ไข (Fix)
| ไฟล์ | การเปลี่ยนแปลง |
| -------------- | ---------------------- |
| [path/to/file] | [อธิบายการเปลี่ยนแปลง] |
## กฎที่ Lock แล้ว
[บันทึก pattern หรือ decision ที่ตกลง]
## Verification
[วิธีตรวจสอบว่างานสำเร็จ]
```
3. **อัปเดต `specs/88-logs/rollouts.md`**
- เพิ่ม entry ใหม่ในตาราง Recent Rollouts
- รูปแบบ: `| วันที่ | Version | รายการ | สถานะ |`
### 2. อัปเดต Project Memory (ถ้ามี decision ใหม่)
เมื่อมีการตัดสินใจสำคัญใหม่ให้:
1. **เปิดไฟล์ `memory/project-memory-override.md`**
2. **อัปเดตตาราง "Current Decisions (Locked)"**
- เพิ่ม entry ใหม่ถ้ามี decision ใหม่
- รูปแบบ: `| ID | Decision | ADR |`
3. **อัปเดต "Next Session Focus"**
- เพิ่มงานใหม่ถ้ามี
- ทำเครื่องหมาย `[ ]` สำหรับงานที่ยังไม่เสร็จ
- ทำเครื่องหมาย `[X]` สำหรับงานที่เสร็จแล้ว
4. **อัปเดต "Environment & Services"** (ถ้ามีการเปลี่ยนแปลง)
- อัปเดต URL, port, หรือ notes ถ้ามีการเปลี่ยน infrastructure
### 3. อัปเดต MCP Tools (ถ้ามี tools ใหม่)
เมื่อมี MCP tools ใหม่ให้:
1. **เปิดไฟล์ `memory/mcp-tools.md`**
2. **เพิ่ม tool ใหม่ในตาราง "Available Tools"**
- รูปแบบ: `| Tool | Purpose | Example Usage |`
3. **เพิ่ม usage example และ warnings** ถ้าจำเป็น
### 4. อัปเดต Root Documentation (ถ้ามีการเปลี่ยนแปลง)
เมื่อมีการเปลี่ยนแปลงที่ส่งผลต่อเอกสารระดับ root ให้:
1. **ARCHITECTURE.md** — อัปเดตเมื่อ:
- เปลี่ยน architecture หลัก
- เพิ่ม/ลบ component สำคัญ
- เปลี่ยน data flow หรือ integration pattern
2. **CHANGELOG.md** — อัปเดตเมื่อ:
- Deploy version ใหม่
- เพิ่ม feature หรือ breaking change สำคัญ
- รูปแบบ: `## [version] (YYYY-MM-DD)``### feat(scope): description`
3. **CONTEXT.md** — อัปเดตเมื่อ:
- เปลี่ยน domain terminology หลัก
- เพิ่ม concept ใหม่ที่ใช้ทั่ว project
- อัปเดต glossary หรือ business rules
4. **CONTRIBUTING.md** — อัปเดตเมื่อ:
- เปลี่ยน workflow การทำงาน
- เพิ่ม/เปลี่ยน coding standards
- อัปเดต CI/CD process
5. **README.md** — อัปเดตเมื่อ:
- เปลี่ยน project structure
- เพิ่ม/เปลี่ยน installation steps
- อัปเดต feature overview หรือ tech stack
## Template สำหรับ Session Log
```markdown
# Session [N] — YYYY-MM-DD ([Topic])
## Summary
[สรุปสิ่งที่ทำใน session นี้ใน 1-2 ประโยค]
## ปัญหาที่พบ (Root Cause)
[อธิบายปัญหาและสาเหตุหลัก]
## การแก้ไข (Fix)
| ไฟล์ | การเปลี่ยนแปลง |
| -------------- | ---------------------- |
| `path/to/file` | [อธิบายการเปลี่ยนแปลง] |
## กฎที่ Lock แล้ว
[บันทึก pattern หรือ decision ที่ตกลงและไม่ควรเปลี่ยน]
## Verification
- [ ] [check 1]
- [ ] [check 2]
```
## ข้อควรระวัง
- **ห้าม** บันทึก rules ที่ซ้ำกับ specs/ (ADRs, glossary, guidelines)
- **ห้าม** บันทึก commands ที่ซ้ำกับ specs/05-Engineering-Guidelines/
- **ห้าม** บันทึก environment ที่ซ้ำกับ specs/04-Infrastructure-OPS/
- **ใช้** `specs/88-logs/` สำหรับ session history และ rollouts
- **ใช้** `memory/project-memory-override.md` สำหรับ OS rules, decisions, environment ที่ไม่มีใน specs
- **ใช้** `memory/mcp-tools.md` สำหรับ MCP tools documentation
- **อัปเดต Root Documentation** (ARCHITECTURE.md, CHANGELOG.md, CONTEXT.md, CONTRIBUTING.md, README.md) เฉพาะเมื่อมีการเปลี่ยนแปลงที่ส่งผลต่อ project architecture, version, terminology, workflow หรือ structure
## ตัวอย่างการใช้งาน
### กรณีที่ 1: ทำงาน session ใหม่
```
1. สร้างไฟล์ specs/88-logs/session-2026-06-07-bug-fix.md
2. บันทึกปัญหา, การแก้ไข, verification
3. อัปเดต specs/88-logs/rollouts.md
```
### กรณีที่ 2: มี decision ใหม่
```
1. เปิด memory/project-memory-override.md
2. เพิ่ม entry ใหม่ในตาราง Current Decisions
3. อัปเดต Next Session Focus
```
### กรณีที่ 3: เปลี่ยน infrastructure
```
1. เปิด memory/project-memory-override.md
2. อัปเดตตาราง Environment & Services
3. อัปเดต Key Environment Variables ถ้าจำเป็น
```
### กรณีที่ 4: อัปเดต Root Documentation
```
1. ตรวจสอบว่ามีการเปลี่ยนแปลงที่ส่งผลต่อ ARCHITECTURE.md, CHANGELOG.md, CONTEXT.md, CONTRIBUTING.md, หรือ README.md
2. อัปเดตไฟล์ที่เกี่ยวข้องตามรูปแบบที่กำหนด
3. ตรวจสอบว่าการเปลี่ยนแปลงสอดคล้องกับ specs/ และ ADRs
```
+3 -2
View File
@@ -2,7 +2,7 @@
ไฟล์นี้กำหนดทักษะและความสามารถเฉพาะทางของ Document Intelligence Engine สำหรับโครงการ LCBP3 v1.9.0 เพื่อรักษามาตรฐานสูงสุดด้าน Security และ Data Integrity ไฟล์นี้กำหนดทักษะและความสามารถเฉพาะทางของ Document Intelligence Engine สำหรับโครงการ LCBP3 v1.9.0 เพื่อรักษามาตรฐานสูงสุดด้าน Security และ Data Integrity
**Status**: Production Ready | **Last Updated**: 2026-05-17 | **Total Skills**: 23 **Status**: Production Ready | **Last Updated**: 2026-06-07 | **Total Skills**: 24
> 📌 Shared context for all speckit-\* skills: see [`_LCBP3-CONTEXT.md`](./_LCBP3-CONTEXT.md). > 📌 Shared context for all speckit-\* skills: see [`_LCBP3-CONTEXT.md`](./_LCBP3-CONTEXT.md).
@@ -76,6 +76,7 @@
| **speckit-status** | None | None | Progress tracking | | **speckit-status** | None | None | Progress tracking |
| **speckit-taskstoissues** | speckit-tasks | None | Issue sync | | **speckit-taskstoissues** | speckit-tasks | None | Issue sync |
| **speckit-checklist** | speckit-plan | None | Requirements validation | | **speckit-checklist** | speckit-plan | None | Requirements validation |
| **save-memory** | None | None | Session log & memory update |
| **nestjs-best-practices** | None | speckit-implement | Backend patterns | | **nestjs-best-practices** | None | speckit-implement | Backend patterns |
| **next-best-practices** | None | speckit-implement | Frontend patterns | | **next-best-practices** | None | speckit-implement | Frontend patterns |
| **speckit-security-audit** | None | speckit-reviewer | Security validation | | **speckit-security-audit** | None | speckit-reviewer | Security validation |
@@ -99,7 +100,7 @@
### Health Metrics ### Health Metrics
- **Total Skills**: 23 implemented - **Total Skills**: 24 implemented
- **Version Alignment**: v1.9.0 across all skills - **Version Alignment**: v1.9.0 across all skills
- **Template Coverage**: 100% for skills requiring templates - **Template Coverage**: 100% for skills requiring templates
- **Documentation**: Complete front matter + shared `_LCBP3-CONTEXT.md` appendix - **Documentation**: Complete front matter + shared `_LCBP3-CONTEXT.md` appendix
+46 -17
View File
@@ -19,7 +19,7 @@ class SkillTestSuite {
this.results = { this.results = {
passed: 0, passed: 0,
failed: 0, failed: 0,
errors: [] errors: [],
}; };
} }
@@ -29,7 +29,7 @@ class SkillTestSuite {
pass: '\x1b[32m', // Green pass: '\x1b[32m', // Green
fail: '\x1b[31m', // Red fail: '\x1b[31m', // Red
warn: '\x1b[33m', // Yellow warn: '\x1b[33m', // Yellow
reset: '\x1b[0m' reset: '\x1b[0m',
}; };
const color = colors[type] || colors.info; const color = colors[type] || colors.info;
@@ -119,11 +119,20 @@ function runAllTests() {
// Test 3: Script Files // Test 3: Script Files
testSuite.log('Test 3: Validation Scripts', 'info'); testSuite.log('Test 3: Validation Scripts', 'info');
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'validate-versions.sh'), 'bash validate-versions.sh'); testSuite.testFileExists(
path.join(AGENTS_DIR, 'scripts', 'bash', 'validate-versions.sh'),
'bash validate-versions.sh'
);
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'audit-skills.sh'), 'bash audit-skills.sh'); testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'audit-skills.sh'), 'bash audit-skills.sh');
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'sync-workflows.sh'), 'bash sync-workflows.sh'); testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'bash', 'sync-workflows.sh'), 'bash sync-workflows.sh');
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'powershell', 'validate-versions.ps1'), 'powershell validate-versions.ps1'); testSuite.testFileExists(
testSuite.testFileExists(path.join(AGENTS_DIR, 'scripts', 'powershell', 'audit-skills.ps1'), 'powershell audit-skills.ps1'); path.join(AGENTS_DIR, 'scripts', 'powershell', 'validate-versions.ps1'),
'powershell validate-versions.ps1'
);
testSuite.testFileExists(
path.join(AGENTS_DIR, 'scripts', 'powershell', 'audit-skills.ps1'),
'powershell audit-skills.ps1'
);
testSuite.log(''); testSuite.log('');
// Test 4: Version Consistency // Test 4: Version Consistency
@@ -131,21 +140,29 @@ function runAllTests() {
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /v1\.8\.6/, 'README.md version'); testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /v1\.8\.6/, 'README.md version');
testSuite.testFileContent(path.join(SKILLS_DIR, 'VERSION'), /version: 1\.8\.6/, 'skills VERSION file'); testSuite.testFileContent(path.join(SKILLS_DIR, 'VERSION'), /version: 1\.8\.6/, 'skills VERSION file');
testSuite.testFileContent(path.join(SKILLS_DIR, 'skills.md'), /v1\.8\.6/, 'skills.md version'); testSuite.testFileContent(path.join(SKILLS_DIR, 'skills.md'), /v1\.8\.6/, 'skills.md version');
testSuite.testFileContent(path.join(AGENTS_DIR, 'rules', '00-project-context.md'), /v1\.8\.6/, 'project context version'); testSuite.testFileContent(
path.join(AGENTS_DIR, 'rules', '00-project-context.md'),
/v1\.8\.6/,
'project context version'
);
testSuite.log(''); testSuite.log('');
// Test 5: Skills Structure // Test 5: Skills Structure
testSuite.log('Test 5: Skills Structure', 'info'); testSuite.log('Test 5: Skills Structure', 'info');
const skillDirs = fs.readdirSync(SKILLS_DIR).filter(item => { const skillDirs = fs.readdirSync(SKILLS_DIR).filter((item) => {
const itemPath = path.join(SKILLS_DIR, item); const itemPath = path.join(SKILLS_DIR, item);
return fs.statSync(itemPath).isDirectory() && item.startsWith('speckit-') || item === 'nestjs-best-practices' || item === 'next-best-practices'; return (
(fs.statSync(itemPath).isDirectory() && item.startsWith('speckit-')) ||
item === 'nestjs-best-practices' ||
item === 'next-best-practices'
);
}); });
testSuite.assert(skillDirs.length >= 20, `Found at least 20 skill directories (found ${skillDirs.length})`); testSuite.assert(skillDirs.length >= 20, `Found at least 20 skill directories (found ${skillDirs.length})`);
// Test a few key skills // Test a few key skills
const keySkills = ['speckit-plan', 'speckit-implement', 'speckit-specify', 'speckit-validate']; const keySkills = ['speckit-plan', 'speckit-implement', 'speckit-specify', 'speckit-validate'];
keySkills.forEach(skill => { keySkills.forEach((skill) => {
const skillPath = path.join(SKILLS_DIR, skill); const skillPath = path.join(SKILLS_DIR, skill);
const skillMdPath = path.join(skillPath, 'SKILL.md'); const skillMdPath = path.join(skillPath, 'SKILL.md');
testSuite.testDirectoryExists(skillPath, `${skill} directory`); testSuite.testDirectoryExists(skillPath, `${skill} directory`);
@@ -163,12 +180,12 @@ function runAllTests() {
// Test 6: Workflows Structure // Test 6: Workflows Structure
testSuite.log('Test 6: Workflows Structure', 'info'); testSuite.log('Test 6: Workflows Structure', 'info');
const workflowFiles = fs.readdirSync(WORKFLOWS_DIR).filter(item => item.endsWith('.md')); const workflowFiles = fs.readdirSync(WORKFLOWS_DIR).filter((item) => item.endsWith('.md'));
testSuite.assert(workflowFiles.length >= 20, `Found at least 20 workflow files (found ${workflowFiles.length})`); testSuite.assert(workflowFiles.length >= 20, `Found at least 20 workflow files (found ${workflowFiles.length})`);
// Test key workflows // Test key workflows
const keyWorkflows = ['00-speckit.all.md', '02-speckit.specify.md', '04-speckit.plan.md', '07-speckit.implement.md']; const keyWorkflows = ['00-speckit.all.md', '02-speckit.specify.md', '04-speckit.plan.md', '07-speckit.implement.md'];
keyWorkflows.forEach(workflow => { keyWorkflows.forEach((workflow) => {
const workflowPath = path.join(WORKFLOWS_DIR, workflow); const workflowPath = path.join(WORKFLOWS_DIR, workflow);
testSuite.testFileExists(workflowPath, `${workflow} file`); testSuite.testFileExists(workflowPath, `${workflow} file`);
}); });
@@ -177,12 +194,12 @@ function runAllTests() {
// Test 7: Rules Structure // Test 7: Rules Structure
testSuite.log('Test 7: Rules Structure', 'info'); testSuite.log('Test 7: Rules Structure', 'info');
const rulesDir = path.join(AGENTS_DIR, 'rules'); const rulesDir = path.join(AGENTS_DIR, 'rules');
const ruleFiles = fs.readdirSync(rulesDir).filter(item => item.endsWith('.md')); const ruleFiles = fs.readdirSync(rulesDir).filter((item) => item.endsWith('.md'));
testSuite.assert(ruleFiles.length >= 10, `Found at least 10 rule files (found ${ruleFiles.length})`); testSuite.assert(ruleFiles.length >= 10, `Found at least 10 rule files (found ${ruleFiles.length})`);
// Test key rules // Test key rules
const keyRules = ['00-project-context.md', '01-adr-019-uuid.md', '02-security.md']; const keyRules = ['00-project-context.md', '01-adr-019-uuid.md', '02-security.md'];
keyRules.forEach(rule => { keyRules.forEach((rule) => {
const rulePath = path.join(rulesDir, rule); const rulePath = path.join(rulesDir, rule);
testSuite.testFileExists(rulePath, `${rule} file`); testSuite.testFileExists(rulePath, `${rule} file`);
}); });
@@ -209,9 +226,21 @@ function runAllTests() {
// Test 9: Documentation Quality // Test 9: Documentation Quality
testSuite.log('Test 9: Documentation Quality', 'info'); testSuite.log('Test 9: Documentation Quality', 'info');
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /## Troubleshooting/, 'README.md has troubleshooting section'); testSuite.testFileContent(
testSuite.testFileContent(path.join(SKILLS_DIR, 'skills.md'), /## Skill Dependency Matrix/, 'skills.md has dependency matrix'); path.join(AGENTS_DIR, 'README.md'),
testSuite.testFileContent(path.join(AGENTS_DIR, 'README.md'), /## Architecture/, 'README.md has architecture section'); /## Troubleshooting/,
'README.md has troubleshooting section'
);
testSuite.testFileContent(
path.join(SKILLS_DIR, 'skills.md'),
/## Skill Dependency Matrix/,
'skills.md has dependency matrix'
);
testSuite.testFileContent(
path.join(AGENTS_DIR, 'README.md'),
/## Architecture/,
'README.md has architecture section'
);
testSuite.log(''); testSuite.log('');
// Results Summary // Results Summary
@@ -221,7 +250,7 @@ function runAllTests() {
if (testSuite.results.errors.length > 0) { if (testSuite.results.errors.length > 0) {
testSuite.log('Errors:', 'fail'); testSuite.log('Errors:', 'fail');
testSuite.results.errors.forEach(error => { testSuite.results.errors.forEach((error) => {
testSuite.log(` - ${error}`, 'fail'); testSuite.log(` - ${error}`, 'fail');
}); });
} }
+10 -8
View File
@@ -17,7 +17,7 @@ class WorkflowTestSuite {
this.results = { this.results = {
passed: 0, passed: 0,
failed: 0, failed: 0,
errors: [] errors: [],
}; };
} }
@@ -27,7 +27,7 @@ class WorkflowTestSuite {
pass: '\x1b[32m', // Green pass: '\x1b[32m', // Green
fail: '\x1b[31m', // Red fail: '\x1b[31m', // Red
warn: '\x1b[33m', // Yellow warn: '\x1b[33m', // Yellow
reset: '\x1b[0m' reset: '\x1b[0m',
}; };
const color = colors[type] || colors.info; const color = colors[type] || colors.info;
@@ -67,7 +67,7 @@ class WorkflowTestSuite {
// Check for proper markdown formatting // Check for proper markdown formatting
const lines = content.split('\n'); const lines = content.split('\n');
const nonEmptyLines = lines.filter(line => line.trim().length > 0); const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
this.assert(nonEmptyLines.length >= 5, `${expectedName} has sufficient content`); this.assert(nonEmptyLines.length >= 5, `${expectedName} has sufficient content`);
return true; return true;
@@ -121,7 +121,7 @@ const expectedWorkflows = {
'util-speckit.migrate.md': 'Migration utility', 'util-speckit.migrate.md': 'Migration utility',
'util-speckit.quizme.md': 'Quiz utility', 'util-speckit.quizme.md': 'Quiz utility',
'util-speckit.status.md': 'Status utility', 'util-speckit.status.md': 'Status utility',
'util-speckit.taskstoissues.md': 'Task to issues utility' 'util-speckit.taskstoissues.md': 'Task to issues utility',
}; };
// Test suite implementation // Test suite implementation
@@ -169,7 +169,6 @@ function runWorkflowTests() {
// Validate skill dependencies // Validate skill dependencies
workflowTestSuite.validateWorkflowDependency(filename, content); workflowTestSuite.validateWorkflowDependency(filename, content);
} catch (error) { } catch (error) {
workflowTestSuite.assert(false, `${filename} - content validation error: ${error.message}`); workflowTestSuite.assert(false, `${filename} - content validation error: ${error.message}`);
} }
@@ -179,7 +178,7 @@ function runWorkflowTests() {
// Test 4: Workflow naming consistency // Test 4: Workflow naming consistency
workflowTestSuite.log('Test 4: Naming Consistency', 'info'); workflowTestSuite.log('Test 4: Naming Consistency', 'info');
const actualFiles = fs.readdirSync(WORKFLOWS_DIR).filter(file => file.endsWith('.md')); const actualFiles = fs.readdirSync(WORKFLOWS_DIR).filter((file) => file.endsWith('.md'));
for (const actualFile of actualFiles) { for (const actualFile of actualFiles) {
if (!expectedWorkflows[actualFile]) { if (!expectedWorkflows[actualFile]) {
@@ -211,11 +210,14 @@ function runWorkflowTests() {
// Results Summary // Results Summary
workflowTestSuite.log('=== Workflow Test Results Summary ===', 'info'); workflowTestSuite.log('=== Workflow Test Results Summary ===', 'info');
workflowTestSuite.log(`Passed: ${workflowTestSuite.results.passed}`, 'pass'); workflowTestSuite.log(`Passed: ${workflowTestSuite.results.passed}`, 'pass');
workflowTestSuite.log(`Failed: ${workflowTestSuite.results.failed}`, workflowTestSuite.results.failed > 0 ? 'fail' : 'pass'); workflowTestSuite.log(
`Failed: ${workflowTestSuite.results.failed}`,
workflowTestSuite.results.failed > 0 ? 'fail' : 'pass'
);
if (workflowTestSuite.results.errors.length > 0) { if (workflowTestSuite.results.errors.length > 0) {
workflowTestSuite.log('Errors:', 'fail'); workflowTestSuite.log('Errors:', 'fail');
workflowTestSuite.results.errors.forEach(error => { workflowTestSuite.results.errors.forEach((error) => {
workflowTestSuite.log(` - ${error}`, 'fail'); workflowTestSuite.log(` - ${error}`, 'fail');
}); });
} }
+11
View File
@@ -0,0 +1,11 @@
---
description: บันทึก session log และอัปเดต project memory
---
# บันทึก Memory
ใช้ skill `save-memory` เพื่อบันทึก session log และอัปเดต project memory ตามโครงสร้างใหม่
```bash
skill save-memory
```
+168
View File
@@ -0,0 +1,168 @@
---
trigger: always_on
---
# NAP-DMS Project Context & Rules
- For: Devin Cascade (and compatible: Codex CLI, opencode, Amp, Antigravity, AGENTS.md tools)
- Version: 1.9.10 | Last synced from repo: 2026-06-06
- Repo: [https://git.np-dms.work/np-dms/lcbp3](https://git.np-dms.work/np-dms/lcbp3)
- Skill pack: `.agents/skills/` (v1.9.0, 21 skills) — see [`skills/README.md`](./.agents/skills/README.md) + [`skills/_LCBP3-CONTEXT.md`](./.agents/skills/_LCBP3-CONTEXT.md)
## 🧠 Role & Persona
Act as **Senior Full Stack Developer** specialized in NestJS, Next.js, TypeScript, DMS. Focus: Data Integrity, Security, Maintainability, Performance.
You are a **Document Intelligence Engine** — not a general chatbot. Every response must be **precise**, **spec-compliant**, and **production-ready**.
---
## 🧩 Thought & Planning Protocol (Powered by Everything-Claude-Code)
Before writing any code or taking any action in Tier 1 and Tier 2, the AI must demonstrate the following thinking process:
### 1. Analysis Phase (Explore & Analyze)
Problem Understanding: Restate what the user wants in clear, unambiguous terms.
Context Search: Identify the relevant Spec files or ADRs from the "Key Spec Files" table that must be read before starting.
Constraints Identification: Identify key constraints (e.g. Security rules, UUID patterns, or Domain terminology).
### 2. Planning Phase (Plan)
Alternative Exploration: Present at least 2 solution approaches (where possible) with pros/cons analysis.
Step-by-Step Roadmap: Write a file-by-file plan of changes before executing.
Verification Plan: Specify how to verify the work is complete (e.g. "which unit tests to write" or "which file to check the schema in").
### 3. Execution & Refinement (Execute & Refine)
Follow the plan step by step, and pause to ask if any uncertainty arises.
If significant logic changes are made, summarize what was done for the user after completion.
---
## ⚙️ DMS Workflow Engine Protocol
กฎนี้ใช้คุม Logic การไหลของเอกสาร (RFA, Transmittal, Correspondence) เพื่อป้องกัน Race Condition และรักษาความถูกต้องของสถานะ:
- **State Management:** ตรวจสอบสถานะปัจจุบันจาก DB ก่อนเสมอ เพื่อป้องกันการอนุมัติซ้ำซ้อน (ดู `05-06-code-snippets.md` `[workflow-transition]`)
- **Concurrency Control:** การจอนเลขที่เอกสารต้องใช้ **Redis Redlock** หรือ **TypeORM `@VersionColumn`** เท่านั้น (ADR-002)
- **Background Jobs:** งานนานหรือการแจ้งเตือนต้องส่งไปทำที่ **BullMQ** ห้ามเขียนแบบ Inline (ADR-008)
- **Term Consistency:** ห้ามใช้ "Approval Flow" ให้ใช้ **"Workflow Engine"** และห้ามใช้ "Letter" ให้ใช้ **"Correspondence"** (หมายเหตุ: "จดหมาย" ในคอมเมนต์ภาษาไทย = Correspondence ที่ครอบคลุมทุกประเภท)
---
## 🛡️ Security & Integrity Audit Protocol
กฎนี้ให้ AI เป็น Gatekeeper ก่อน Commit โดยเน้น **Tier 1 — CRITICAL**:
- **UUID Validation:** ตรวจสอบว่าเป็น **UUIDv7** และห้ามใช้ `parseInt()` บน UUID (ADR-019)
- **RBAC Check:** API ใหม่ต้องมี **CASL Guard** และตรวจสอบ 4-Level RBAC Matrix (ADR-016)
- **Data Isolation:** AI ต้องรันผ่าน **Ollama บน Admin Desktop** เท่านั้น ห้ามเข้าถึง DB/storage โดยตรง (ADR-023)
- **Input Sanitization:** ไฟล์อัปโหลดต้องผ่าน **Two-Phase** (Temp → Commit) และสแกนด้วย **ClamAV** (ADR-016)
---
## 🧭 Rule Enforcement Tiers
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
Build fails หากละเมิด:
- Security (Auth, RBAC, Validation)
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
- Database correctness — verify schema before writing queries
- File upload security (ClamAV + whitelist)
- AI validation boundary (ADR-023)
- Error handling strategy (ADR-007)
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
Must fix ก่อน merge:
- Architecture patterns (thin controller, business logic in service)
- Test coverage (80%+ business logic, 70%+ backend overall)
- Cache invalidation
- Naming conventions
- **TypeScript Standards:** Missing JSDoc, explicit types, or file headers
### 🟢 Tier 3 — SPECIALIZED WORK
Requires domain-specific knowledge:
- **ADR-021 Integration:** Workflow Engine & Context implementation
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
- **Complex Business Logic:** Multi-step workflows with state management
- **Performance Optimization:** Database queries, caching strategies, bulk operations
### 🔵 Tier 4 — GUIDELINES
Best practice — follow when possible:
- Code style / formatting (Prettier handles)
- Comment completeness
- Minor optimizations
---
## 📐 TypeScript Rules & Coding Standards
### 📝 Core Standards
- **Strict Mode** — all strict checks enforced.
- **ZERO `any` types** — use proper types or `unknown` + narrowing.
- **ZERO `console.log`** — use NestJS `Logger` (backend) or remove (frontend).
- **English for Code** — use English for all code identifiers, variables, and logic.
- **Thai for Comments** — use Thai for comments, documentation, and JSDoc.
- **Explicit Typing** — explicitly define types for all variables, parameters, and return values.
- **JSDoc** — use JSDoc for all public classes and methods.
### 🏗️ File & Function Structure
- **File Headers** — every file MUST start with `// File: path/filename` on the first line.
- **Change Log** — include `// Change Log` at the top of the file to track modifications.
- **Single Export** — export **only one main symbol** per file.
- **Function Style** — avoid unnecessary blank lines inside functions.
---
## 🚫 Forbidden Actions
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
---
## 🚧 Out of Scope — Never Do Without Explicit Approval
| ❌ Never Do Autonomously | ⚠️ Why Approval Is Required |
| --------------------------------------------------------------- | ---------------------------------------------------------------- |
| `DROP` or `RENAME` a column / table | Irreversible data loss — requires DBA + PM sign-off |
| Push directly to `main` / `master` branch | Bypasses CI, code review, and release gates |
| Generate or insert seed data into production database | May corrupt live data or violate business state invariants |
| Delete files from permanent storage | Files may be referenced in active documents or audit trails |
| Modify RBAC permission matrix without security team approval | Defines access control for all users — security boundary change |
| Upgrade major library versions (NestJS, Next.js, TypeORM, etc.) | Breaking changes require full regression test cycle |
| Disable or modify authentication / authorization guards | Creates unguarded endpoints — immediate security risk |
| Change Redis lock TTL or disable Redlock | Risk of document number race condition (ADR-002) |
| Create or supersede an ADR unilaterally | Architecture decisions require team consensus and review process |
| Add new columns to production tables without schema review | Must update Data Dictionary + downstream queries simultaneously |
@@ -13,9 +13,9 @@ trigger: always_on
5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days 5. **Password:** bcrypt 12 salt rounds, min 8 chars, rotate every 90 days
6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints 6. **Rate Limiting:** `ThrottlerGuard` on all auth endpoints
7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan 7. **File Upload:** Whitelist PDF/DWG/DOCX/XLSX/ZIP, max 50MB, ClamAV scan
8. **AI Isolation (ADR-018):** Ollama on Admin Desktop ONLY — NO direct DB/storage access 8. **AI Isolation (ADR-023/023A):** Ollama on Admin Desktop ONLY — NO direct DB/storage access; 2-model stack `gemma4:e4b Q8_0` + `nomic-embed-text`; all inference via BullMQ (`ai-realtime` / `ai-batch`)
9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages 9. **Error Handling (ADR-007):** Use layered error classification with user-friendly messages
10. **AI Integration (ADR-020):** RFA-First approach with unified pipeline architecture 10. **AI Integration (ADR-023/023A):** RFA-First approach; n8n orchestrates Migration Phase only via DMS API — never calls Ollama directly; `QdrantService.search()` requires `projectPublicId` as mandatory param
11. **AI Audit Trail:** Log all AI interactions and human validations 11. **AI Audit Trail:** Log all AI interactions and human validations
12. **Rate Limiting:** Apply to AI endpoints to prevent abuse 12. **Rate Limiting:** Apply to AI endpoints to prevent abuse
@@ -30,7 +30,7 @@ trigger: always_on
- [ ] No SQL injection vulnerabilities - [ ] No SQL injection vulnerabilities
- [ ] File upload validation (whitelist + ClamAV) - [ ] File upload validation (whitelist + ClamAV)
- [ ] Rate limiting applied to auth endpoints - [ ] Rate limiting applied to auth endpoints
- [ ] AI boundary enforcement (ADR-023) - no direct DB/storage access - [ ] AI boundary enforcement (ADR-023/023A) - no direct DB/storage access
- [ ] AI audit logging implemented for AI interactions - [ ] AI audit logging implemented for AI interactions
- [ ] AI outputs validated before use (human-in-the-loop) - [ ] AI outputs validated before use (human-in-the-loop)
- [ ] Error handling follows ADR-007 layered classification - [ ] Error handling follows ADR-007 layered classification
@@ -1,4 +1,8 @@
# TypeScript Rules (v1.9.3) ---
trigger: always_on
---
# TypeScript Rules
## Core Standards ## Core Standards
+45
View File
@@ -0,0 +1,45 @@
---
trigger: always_on
---
# Domain Terminology
## DMS Glossary
| ✅ Use | ❌ Don't Use | คำอธิบายเพิ่มเติม |
| ------------------ | ------------------------------------- | ------------------------------------------------ |
| Correspondence | Letter, Communication, Document | ครอบคลุมทุกประเภท: Letter, RFA, Memo, ฯลฯ |
| RFA | Approval Request, Submit for Approval | เอกสารขออนุมัติ (ชนิดหนึ่งของ Correspondence) |
| Transmittal | Delivery Note, Cover Letter | เอกสารนำส่ง (ชนิดหนึ่งของ Correspondence) |
| Circulation | Distribution, Routing | ใบเวียนเอกสารภายใน (ชนิดหนึ่งของ Correspondence) |
| Shop Drawing | Construction Drawing | แบบก่อสร้าง |
| Contract Drawing | Design Drawing, Blueprint | แบบคู่สัญญา |
| Workflow Engine | Approval Flow, Process Engine | เครื่องมือจัดการลำดับงาน |
| Document Numbering | Document ID, Auto Number | ระบบจัดการเลขที่เอกสาร |
| RBAC | Permission System (generic) | การควบคุมสิทธิ์ตามบทบาท |
## Full Glossary
`specs/00-overview/00-02-glossary.md`
## Key Spec Files Priority
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
| Document | Path | Use When |
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
+43
View File
@@ -0,0 +1,43 @@
---
trigger: always_on
---
# Forbidden Actions
## ❌ Never Do This
| ❌ Forbidden | ✅ Correct Approach | ⚠️ Why |
| ----------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| SQL Triggers for business logic | NestJS Service methods | Untestable; bypasses audit log |
| `.env` files in production | `docker-compose.yml` environment section | Secrets exposed in version control |
| TypeORM migration files | Edit schema SQL directly (ADR-009) | Migration drift risk; schema managed via SQL delta |
| Inventing table/column names | Verify against `schema-02-tables.sql` | Schema mismatch causes silent runtime errors |
| `any` TypeScript type | Proper types / generics | Defeats strict mode; hides runtime type errors |
| `console.log` in committed code | NestJS Logger (backend) / remove (frontend) | Log flooding in production; risk of data leakage |
| `req: any` in controllers | `RequestWithUser` typed interface | Type safety lost; auth context unreachable |
| `parseInt()` on UUID values | Use UUID string directly (ADR-019) | `"0195…"` parsed to integer `19` — silently wrong |
| Exposing INT PK in API responses | UUIDv7 `publicId` (ADR-019) | Leaks row count; enables DB enumeration attacks |
| AI accessing DB/storage directly | AI → DMS API → DB (ADR-023/023A) | Bypasses RBAC, audit trail, and validation layer |
| Direct file operations bypassing StorageService | `StorageService` for all file moves | Orphaned files; broken ClamAV scan; no audit trail |
| Inline email/notification sending | BullMQ queue job (ADR-008) | Blocks request thread; no retry on transient failure |
| Deploying without Release Gates | Complete `04-08-release-management-policy.md` | Unverified deploy risks data loss in production |
| AI direct cloud API calls | On-premises Ollama only (ADR-023/023A) | Data privacy violation; no audit control |
| AI outputs without human validation | Human-in-the-loop validation required (ADR-023/023A) | Unvalidated AI metadata corrupts document records |
| n8n calling Ollama/Qdrant directly | n8n → DMS API → BullMQ → Ollama (ADR-023A) | Bypasses audit log, RBAC, and error handling layer |
| Qdrant query without `projectPublicId` filter | `QdrantService.search(projectPublicId, ...)` (ADR-023A) | Cross-project data leak via vector search |
## Schema Changes (ADR-009)
- **NO TypeORM migrations** — edit SQL schema directly
- Always check `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` before writing queries
- Update Data Dictionary when changing fields
## UUID Handling
See `01-adr-019-uuid.md` for complete UUID rules.
Quick reminder:
- ❌ `parseInt(uuid)` → NEVER
- ❌ `Number(uuid)` → NEVER
- ✅ Use UUID string directly
+214
View File
@@ -0,0 +1,214 @@
---
trigger: always_on
---
# Development Flow
## 🔴 Critical Work — DB / API / Security / Workflow Engine
**MUST complete all steps:**
1. **Glossary check** — verify domain terms in `00-02-glossary.md`
2. **Read the spec** — select from Key Spec Files table
3. **Check schema** — verify table/column in `lcbp3-v1.9.0-schema-02-tables.sql`
4. **Check data dictionary** — confirm field meanings + business rules
5. **Scan edge cases**`01-06-edge-cases-and-rules.md`
6. **Check ADRs** — verify decisions align (ADR-009, ADR-019, ADR-023)
7. **Write code** — TypeScript strict, no `any`, no `console.log`
## 🟡 Normal Work — UI / Feature / Integration
- Follow existing patterns in codebase.
- Check spec for relevant module only.
- **Hybrid Specs Organization:**
- Place new Infrastructure tasks in `specs/100-Infrastructures/`
- Place new Feature/Workflow tasks in `specs/200-fullstacks/`
- Place Documentation/Research in `specs/300-others/`
- Ensure no forbidden patterns (`any`, `console.log`, UUID misuse) are introduced.
## 🟢 Quick Fix — Bug Fix / Typo / Style
- Fix directly
- Add minimal test if logic changed
- Check forbidden patterns before commit
### 🟢 Specialized Work — ADR-021, AI Runtime Layer, Complex Logic
**MUST complete:**
1. **Domain Knowledge Check** - Read relevant ADRs (ADR-021, ADR-023/023A, ADR-024~028)
2. **Pattern Verification** - Check existing implementations in codebase
3. **Specialized Requirements** - Follow domain-specific patterns
4. **Complex Logic Testing** - Multi-scenario test coverage
5. **Performance Validation** - Load testing if applicable
**For ADR-021 Integration:**
- Read ADR-021 - Integrated workflow & step attachments
- Check ADR-001 - Unified workflow engine patterns
- Verify WorkflowEngineService - Polymorphic instance handling
- Add workflow fields - Expose workflowInstanceId, workflowState, availableActions
- Include IntegratedBanner - Frontend workflow lifecycle display
- Test workflow transitions - State changes and action validation
**For AI Infrastructure (ADR-023/023A):**
- Verify AI boundary enforcement - No direct DB/storage access
- Check BullMQ 2-queue setup - ai-realtime + ai-batch
- Validate Qdrant multi-tenancy - projectPublicId filter required
- Test human-in-the-loop validation workflows
- Audit AI interaction logging to ai_audit_logs
**For AI Runtime Layer (ADR-024/025/026/027):**
- ADR-024: Pattern Layer first (ai_intent_patterns DB + Redis cache 5 min) → LLM Fallback (gemma4:e4b, semaphore max=3)
- ADR-025: Tool Registry dispatch — AI Gateway → Tool → Business Service; ToolResult DTO must use publicId only
- ADR-026: useAiChat() hook + side-panel UI; streaming response via SSE; TanStack Query cache
- ADR-027: Admin Console — dynamic model/prompt/intent control; CASL-guarded admin-only endpoints
**For Migration Pipeline (ADR-028):**
- Use Staging Queue pattern — never write directly to production tables
- Post-migration cleanup process required after each batch
- Migration Validation Gates must pass before promoting to production
**Expected output:**
- Backend services expose specialized context fields
- Frontend components use domain-specific patterns
- Complex state management with proper validation
- Performance metrics within acceptable thresholds
- Comprehensive test coverage for edge cases
---
## Context-Aware Triggers
| Request | Files to Check | Expected Response |
| --------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| "สร้าง API ใหม่" | `05-02-backend-guidelines.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | NestJS Controller + Service + DTO + CASL Guard |
| "แก้ฟอร์ม frontend" | `05-03-frontend-guidelines.md`, `01-06-edge-cases-and-rules.md` | RHF+Zod + TanStack Query + Thai comments |
| "เพิ่ม field ใหม่" | `ADR-009`, `03-01-data-dictionary.md`, `lcbp3-v1.9.0-schema-02-tables.sql` | Edit SQL directly + update Data Dictionary + Entity |
| "ตรวจสอบ UUID" | `ADR-019`, `05-07-hybrid-uuid-implementation-plan.md` | UUIDv7 MariaDB native UUID + TransformInterceptor |
| "สร้าง migration" | `ADR-009`, `03-06-migration-business-scope.md` | Edit SQL schema directly + n8n workflow |
| "ตรวจสอบ permission" | `lcbp3-v1.9.0-seed-permissions.sql`, `ADR-016` | CASL 4-Level RBAC matrix |
| "deploy production" | `04-08-release-management-policy.md`, `ADR-015` | Release Gates + Blue-Green strategy |
| "เพิ่ม test" | `05-04-testing-strategy.md` | Coverage goals + test patterns |
| "AI integration" | `ADR-023`, `ADR-023A`, `ADR-024`, `ADR-025` | AI boundary + 2-model stack + BullMQ queue policy + Intent/Tool Layer |
| "Error handling" | `ADR-007` | Layered error classification + recovery |
| "File upload" | `ADR-016`, `05-02-backend-guidelines.md`, `03-Data-and-Storage/03-03-file-storage.md` | Two-phase upload → temp → commit; ClamAV + whitelist |
| "Notifications / Queue" | `ADR-008`, `05-02-backend-guidelines.md` | BullMQ job — never inline; check retry + dead-letter |
| "Add i18n / translate" | `05-08-i18n-guidelines.md` | i18n keys only — no hardcoded text |
| "Workflow / DSL" | `ADR-001`, `01-03-modules/01-03-06-unified-workflow.md` | DSL state machine + WorkflowEngineService |
| "Document numbering" | `ADR-002`, `01-02-business-rules/01-02-02-doc-numbering-rules.md` | Redis Redlock + DB optimistic lock (double-lock) |
| "ตรวจสอบ Workflow" | `01-06-edge-cases-and-rules.md`, `05-02-backend-guidelines.md`, `ADR-001`, `ADR-002` | เช็คการเปลี่ยน State, คิว BullMQ และการล็อกเลขที่เอกสาร |
| "Transmittal submit" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | submit() with EC-RFA-004 validation |
| "Circulation reassign" | `ADR-021`, `specs/200-fullstacks/201-transmittals-circulation/` | reassignRouting() with EC-CIRC-001 |
| "สร้าง workflow ใหม่" | `ADR-001`, `ADR-021`, `specs/200-fullstacks/203-unified-workflow-engine/` | DSL workflow definition + WorkflowEngineService setup |
| "ตรวจสอบ AI boundary" | `ADR-023`, `ADR-023A` | Verify Ollama isolation + BullMQ queues + Qdrant projectPublicId filter |
| "Intent classification" | `ADR-024`, `specs/200-fullstacks/224-intent-classification/` | Pattern Layer → LLM Fallback; ai_intent_patterns; Redis cache 5 min |
| "AI Tool Layer" | `ADR-025`, `specs/200-fullstacks/225-ai-tool-layer-architecture/` | Tool Registry; CASL-guarded dispatch; ToolResult publicId only |
| "Document Chat UI" | `ADR-026`, `specs/200-fullstacks/226-document-chat-ui-pattern/` | Side-panel; useAiChat() hook; streaming SSE; TanStack Query cache |
| "AI Admin Console" | `ADR-027`, `specs/200-fullstacks/227-ai-admin-console/` | Dynamic model/prompt/intent control; admin-only CASL endpoints |
| "Migration refactor" | `ADR-028`, `specs/200-fullstacks/228-migration-arch-refactor/` | Staging Queue; post-migration cleanup; validation gates |
| "จัดการ document numbering" | `ADR-002`, `specs/03-Data-and-Storage/03-04-document-numbering.md` | Redis Redlock + template system + preview/override workflows |
| "Audit ความปลอดภัย" | `ADR-016`, `ADR-019`, `ADR-023`, `ADR-023A` | ตรวจสอบ UUID pattern, CASL Guard, AI Boundary และ Qdrant multi-tenancy |
| "แก้ bug / bugfix" | `.agents/workflows/bugfix.md`, `error-catalog.md` | ใช้ bugfix workflow สำหรับเคสที่สาเหตุชัดเจน |
| "ตรวจแอปจริง" | `.windsurf/workflows/check-real-app.md` | ตรวจ endpoint/UI/console หลัง build pass — No Fake Evidence |
| "งานค้าง / resume" | `.windsurf/workflows/resume-pending-work.md` | อ่าน checkpoint เดิม → ตรวจ build → วางแผนต่อโดยไม่ทำงานซ้ำ |
---
## 🔌 MCP MariaDB Tools
MCP MariaDB server ให้เครื่องมือสำหรับตรวจสอบและจัดการ database โดยตรง ใช้สำหรับ:
- ตรวจสอบ schema กับ spec file `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
- Debug ปัญหา database โดยไม่ต้องเข้า MySQL client
- ตรวจสอบ data ใน production/staging
- Validate การเปลี่ยนแปลง schema ก่อน deploy
### Available Tools
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|------|----------|------------------|
| `mcp1_mysql_test_connection` | ทดสอบ connection กับ database | ตรวจสอบว่า MCP server เชื่อมต่อได้ |
| `mcp1_mysql_show_databases` | แสดง databases ทั้งหมด | ดูว่ามี database อะไรบ้าง |
| `mcp1_mysql_show_tables` | แสดง tables ทั้งหมดใน database | ดูรายชื่อ tables ใน `lcbp3` |
| `mcp1_mysql_describe_table` | ดู structure/columns ของ table | ตรวจสอบ columns, types, keys ของ `correspondences` |
| `mcp1_mysql_query` | รัน SELECT query | ดู data ใน table หรือ join query |
| `mcp1_mysql_insert` | INSERT data | เพิ่ม seed data หรือ test data |
| `mcp1_mysql_update` | UPDATE data | แก้ไข data ใน table |
| `mcp1_mysql_delete` | DELETE data | ลบ data ใน table |
### การใช้งานร่วมกับ Development Flow
**เมื่อเขียน query ใหม่:**
1. ใช้ `mcp1_mysql_describe_table` เพื่อตรวจสอบ columns และ types
2. เปรียบเทียบกับ `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql`
3. ใช้ `mcp1_mysql_query` เพื่อทดสอบ query ก่อน implement
**เมื่อเปลี่ยน schema (ADR-009):**
1. ใช้ `mcp1_mysql_describe_table` เพื่อดู structure ปัจจุบัน
2. สร้าง SQL delta ใน `specs/03-Data-and-Storage/deltas/`
3. ใช้ `mcp1_mysql_query` เพื่อตรวจสอบผลลัพธ์หลัง apply delta
**เมื่อ debug ปัญหา database:**
1. ใช้ `mcp1_mysql_query` เพื่อดู data จริง
2. เปรียบเทียบกับ spec และ data dictionary
3. ตรวจสอบ foreign keys และ constraints
### ข้อควรระวัง
- **❌ ห้ามใช้ MCP MariaDB สำหรับ DDL operations** (CREATE/ALTER/DROP) โดยตรง — ต้องใช้ SQL delta ตาม ADR-009
- **✅ ใช้สำหรับ DQL/DML operations** (SELECT/INSERT/UPDATE/DELETE) เพื่อ debug และ test เท่านั้น
- **⚠️ ระวัง DELETE operations** — อาจทำให้เสีย data ใน production
- **✅ ตรวจสอบ schema กับ spec file เสมอ** ก่อนเขียน query
---
## 🧠 MCP Memory Tools
MCP Memory server ให้เครื่องมือสำหรับจัดการ Knowledge Graph และ Long-term Memory ใช้สำหรับ:
- จัดเก็บความรู้และ context ของโปรเจกต์ในรูปแบบ Graph (Entities + Relations + Observations)
- ค้นหาและดึงข้อมูล context จาก memory ที่บันทึกไว้ใน session ก่อนหน้า
- สร้าง/แก้ไข/ลบ entities, relations, และ observations ใน knowledge graph
### Available Tools
| Tool | หน้าที่ | ตัวอย่างการใช้งาน |
|------|----------|------------------|
| `mcp3_create_entities` | สร้าง entities ใหม่หลายตัวพร้อม observations | สร้าง entity ใหม่เช่น Project, User, Task |
| `mcp3_create_relations` | สร้าง relations ระหว่าง entities | สร้าง relation: Project → has → User |
| `mcp3_add_observations` | เพิ่ม observations ให้ entity ที่มีอยู่แล้ว | เพิ่ม context เพิ่มเติมให้ entity |
| `mcp3_delete_entities` | ลบ entities และ relations ที่เกี่ยวข้อง | ลบ entity ที่ไม่ใช้แล้ว |
| `mcp3_delete_relations` | ลบ relations ระหว่าง entities | ลบ relation ที่ผิดหรือไม่ใช้แล้ว |
| `mcp3_delete_observations` | ลบ observations จาก entity | ลบ context ที่ผิดหรือล้าสุด |
| `mcp3_open_nodes` | ดึงข้อมูล entities ตามชื่อ | ดึง entity ที่ระบุชื่อ |
| `mcp3_read_graph` | อ่าน knowledge graph ทั้งหมด | ดูทั้ง graph structure |
| `mcp3_search_nodes` | ค้นหา entities ตาม query | ค้นหา entity จากชื่อ, type, หรือ observation |
### การใช้งานร่วมกับ Development Flow
**เมื่อบันทึก context ใหม่:**
1. ใช้ `mcp3_create_entities` เพื่อสร้าง entities ใหม่ (ถ้ายังไม่มี)
2. ใช้ `mcp3_create_relations` เพื่อเชื่อมโยง entities
3. ใช้ `mcp3_add_observations` เพื่อเพิ่ม context/observations
**เมื่อค้นหา context:**
1. ใช้ `mcp3_search_nodes` เพื่อค้นหา entities ที่เกี่ยวข้อง
2. ใช้ `mcp3_open_nodes` เพื่อดึงข้อมูล entities ที่ต้องการ
3. ใช้ `mcp3_read_graph` เพื่อดู relations ระหว่าง entities
**เมื่อแก้ไข context:**
1. ใช้ `mcp3_add_observations` เพื่อเพิ่ม observations ใหม่
2. ใช้ `mcp3_delete_observations` เพื่อลบ observations ที่ผิด
3. ใช้ `mcp3_create_relations` หรือ `mcp3_delete_relations` เพื่อปรับ relations
### ข้อควรระวัง
- **✅ ใช้สำหรับบันทึก context ที่ต้องใช้ร่วมกันหลาย session** — เช่น การตัดสินใจสำคัญ, architecture decisions, rollout history
- **⚠️ ระวังการลบ entities** — อาจทำให้เสีย context ที่ยังใช้งานอยู่
- **✅ ตรวจสอบว่า entity มีอยู่แล้วก่อนสร้าง** — ใช้ `mcp3_search_nodes` หรือ `mcp3_open_nodes` ก่อน
- **✅ ใช้ชื่อ entity ที่ชัดเจนและไม่ซ้ำกัน** — เพื่อป้องกันความสับสน
@@ -7,7 +7,7 @@ trigger: always_on
## CRITICAL RULES ## CRITICAL RULES
- **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop) - **ALWAYS** follow ADR-023 AI boundary policy (isolation on Admin Desktop)
- **ALWAYS** use ADR-023A 2-model stack (gemma4:e4b Q8_0 + nomic-embed-text) - **ALWAYS** use ADR-023A 2-model stack (gemma4:e2b + nomic-embed-text)
- **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention - **ALWAYS** use BullMQ 2-queue (ai-realtime + ai-batch) for GPU overload prevention
- **NEVER** allow AI direct database/storage access - **NEVER** allow AI direct database/storage access
- **ALWAYS** implement human-in-the-loop validation - **ALWAYS** implement human-in-the-loop validation
@@ -30,7 +30,7 @@ n8n (Migration) → DMS API → BullMQ → Admin Desktop (Ollama) → Backend Va
| ----------------- | ------------------------- | ------------------------------------------------------------------------ | | ----------------- | ------------------------- | ------------------------------------------------------------------------ |
| **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging | | **AI Gateway** | Backend (NestJS) | API endpoints, validation, audit logging |
| **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) | | **BullMQ Queues** | Backend (NestJS) | ai-realtime (RAG/Suggest), ai-batch (OCR/Extract/Embed) |
| **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e4b Q8_0 (LLM) + nomic-embed-text (Embedding) | | **Ollama Engine** | Admin Desktop (Desk-5439) | gemma4:e2b (LLM) + nomic-embed-text (Embedding) |
| **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) | | **OCR Engine** | Admin Desktop (Desk-5439) | PaddleOCR + PyThaiNLP (Thai/English text extraction) |
| **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) | | **Orchestrator** | QNAP NAS (n8n) | Migration Phase orchestrator only (calls DMS API, never Ollama directly) |
@@ -80,7 +80,7 @@ export class AiService {
async extractMetadata(documentId: string): Promise<AIMetadata> { async extractMetadata(documentId: string): Promise<AIMetadata> {
// 1. Validate permissions // 1. Validate permissions
// 2. Queue job to BullMQ (ai-batch or ai-realtime) // 2. Queue job to BullMQ (ai-batch or ai-realtime)
// 3. Worker sends to Admin Desktop AI (gemma4:e4b Q8_0) // 3. Worker sends to Admin Desktop AI (gemma4:e2b)
// 4. Validate AI response // 4. Validate AI response
// 5. Log audit trail to ai_audit_logs // 5. Log audit trail to ai_audit_logs
// 6. Return validated results // 6. Return validated results
@@ -119,7 +119,7 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
## ADR-023A Specific Rules ## ADR-023A Specific Rules
- **2-Model Stack:** gemma4:e4b Q8_0 (~4.0GB) + nomic-embed-text (~0.3GB) = ~4.3GB VRAM peak - **2-Model Stack:** gemma4:e2b + nomic-embed-text
- **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding) - **PDF 3-Page Limit:** Classification/Tagging uses first 3 pages only (NOT RAG embedding)
- **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap - **RAG Embedding:** Full document chunked at 512 tokens/64 tokens overlap
- **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR - **OCR Auto-Detect:** PyMuPDF chars > 100 → Fast path, else PaddleOCR
@@ -133,7 +133,7 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
- [ ] BullMQ 2-queue setup (ai-realtime + ai-batch) - [ ] BullMQ 2-queue setup (ai-realtime + ai-batch)
- [ ] QdrantService with projectPublicId enforcement - [ ] QdrantService with projectPublicId enforcement
- [ ] DocumentReviewForm reusable component - [ ] DocumentReviewForm reusable component
- [ ] Admin Desktop Ollama (gemma4:e4b Q8_0 + nomic-embed-text) + PaddleOCR setup - [ ] Admin Desktop Ollama (gemma4:e2b + nomic-embed-text) + PaddleOCR setup
- [ ] n8n workflow orchestration (Migration Phase only) - [ ] n8n workflow orchestration (Migration Phase only)
- [ ] AI audit logging and monitoring (ai_audit_logs) - [ ] AI audit logging and monitoring (ai_audit_logs)
- [ ] Human-in-the-loop validation workflows - [ ] Human-in-the-loop validation workflows
@@ -142,3 +142,8 @@ const DocumentReviewForm = ({ document, aiSuggestions }) => {
- `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture) - `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` (Base architecture)
- `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current) - `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` (Model revision - current)
- `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` (Pattern→LLM Fallback)
- `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` (Tool Registry)
- `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` (Chat UI)
- `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` (Admin Console)
- `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` (Migration Pipeline)
+141
View File
@@ -0,0 +1,141 @@
---
trigger: always_on
---
# LCBP3 Agent Rules
Critical rules and guidelines for AI agents working on LCBP3-DMS.
## Version
- **Current:** v1.9.6
- **Last Updated:** 2026-05-22
- **Synced with:** `AGENTS.md` (v1.9.6)
## Purpose
This directory contains rule files that define:
- Project context and role expectations
- Critical Tier 1 rules (CI blockers)
- Coding standards and patterns
- Domain terminology and glossary
- Development workflows
- Security requirements
- AI integration architecture (ADR-023/023A)
## Rule Enforcement Tiers
### 🔴 Tier 1 — CRITICAL (CI BLOCKER)
Build fails immediately if violated:
- Security (Auth, RBAC, Validation)
- UUID Strategy (ADR-019) — no `parseInt` / `Number` / `+` on UUID
- Database correctness — verify schema before writing queries
- File upload security (ClamAV + whitelist)
- AI validation boundary (ADR-023)
- Error handling strategy (ADR-007)
- Forbidden patterns: `any`, `console.log`, UUID misuse, `id ?? ''` fallback
### 🟡 Tier 2 — IMPORTANT (CODE REVIEW)
Must fix before merge:
- Architecture patterns (thin controller, business logic in service)
- Test coverage (80%+ business logic, 70%+ backend overall)
- Cache invalidation
- Naming conventions
- TypeScript Standards: Missing JSDoc, explicit types, or file headers
### 🟢 Tier 3 — SPECIALIZED WORK
Requires domain-specific knowledge:
- **ADR-021 Integration:** Workflow Engine & Context implementation
- **AI Infrastructure:** ADR-023/023A boundary enforcement and pipeline usage
- **AI Runtime Layer:** ADR-024 Intent Classification, ADR-025 Tool Layer, ADR-026 Chat UI, ADR-027 Admin Console
- **Migration Pipeline:** ADR-028 Staging Queue & post-migration cleanup
- **Complex Business Logic:** Multi-step workflows with state management
- **Performance Optimization:** Database queries, caching strategies, bulk operations
### 🔵 Tier 4 — GUIDELINES
Best practice — follow when possible:
- Code style / formatting (Prettier handles)
- Comment completeness
- Minor optimizations
## Rule Files
### Core Rules (Tier 1 - CRITICAL)
| File | Purpose |
| ----------------------- | ------------------------------------------------------------------------------- |
| `00-project-context.md` | Project context, role & persona, tier classification, specs folder organization |
| `01-adr-019-uuid.md` | UUID handling strategy — no parseInt, use publicId only |
| `02-security.md` | Security requirements, checklist, ADR-023/023A AI boundaries |
### Coding Standards
| File | Purpose |
| ------------------------- | ------------------------------------------------------- |
| `03-typescript.md` | TypeScript rules, file headers, i18n guidelines |
| `06-backend-patterns.md` | NestJS patterns, UUID resolution, API response patterns |
| `07-frontend-patterns.md` | Next.js patterns, RHF+Zod+TanStack Query, UUID handling |
### Domain & Workflow
| File | Purpose |
| -------------------------- | ------------------------------------------------------------- |
| `04-domain-terminology.md` | DMS glossary, key spec files priority table |
| `08-development-flow.md` | Development workflow by work type (Critical/Normal/Quick Fix) |
### Compliance & Architecture
| File | Purpose |
| ------------------------- | -------------------------------------------------------------- |
| `05-forbidden-actions.md` | Actions that must never be done, schema changes, UUID handling |
| `09-commit-checklist.md` | Pre-commit verification, commit message format |
| `10-error-handling.md` | ADR-007 error handling strategy, layered classification |
| `11-ai-integration.md` | ADR-023/023A AI architecture, 2-model stack, BullMQ 2-queue |
## Key Spec Files Priority
Spec priority: **`06-Decision-Records`** > **`05-Engineering-Guidelines`** > others
| Document | Path | Use When |
| ------------------------------ | --------------------------------------------------------------------------- | --------------------------------- |
| **Glossary** | `specs/00-overview/00-02-glossary.md` | Verify domain terminology |
| **Schema Tables** | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` | Before writing any query |
| **Data Dictionary** | `specs/03-Data-and-Storage/03-01-data-dictionary.md` | Field meanings + business rules |
| **Edge Cases** | `specs/01-Requirements/01-06-edge-cases-and-rules.md` | Prevent bugs in flows |
| **ADR-019 UUID** | `specs/06-Decision-Records/ADR-019-hybrid-identifier-strategy.md` | UUID-related work |
| **ADR-023 AI** | `specs/06-Decision-Records/ADR-023-unified-ai-architecture.md` | AI integration work |
| **ADR-023A AI Model** | `specs/06-Decision-Records/ADR-023A-unified-ai-architecture.md` | 2-model stack, BullMQ 2-queue |
| **ADR-024 Intent Class.** | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` | Pattern→LLM Fallback; Redis cache |
| **ADR-025 AI Tool Layer** | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` | Tool Registry; CASL-guarded |
| **ADR-026 Chat UI** | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` | Side-panel; streaming SSE |
| **ADR-027 AI Admin Console** | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` | Dynamic control; admin-only |
| **ADR-028 Migration Refactor** | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` | Staging Queue; cleanup |
| **Backend Guidelines** | `specs/05-Engineering-Guidelines/05-02-backend-guidelines.md` | NestJS patterns |
| **Frontend Guidelines** | `specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md` | Next.js patterns |
| **Testing Strategy** | `specs/05-Engineering-Guidelines/05-04-testing-strategy.md` | Coverage goals |
## Maintenance
When updating rules:
1. **Check AGENTS.md version** — Ensure rule files are synced
2. **Update version numbers** — Bump version in `00-project-context.md` only (03-typescript.md no longer has version)
3. **Review ADR references** — Ensure all ADR references are current (ADR-023, ADR-023A, ADR-024~028)
4. **Add new forbidden actions** — When new patterns are identified as violations
5. **Update key spec files table** — When new ADRs or guidelines are added
6. **Update Tier 3 SPECIALIZED WORK** — When new domain-specific workflows are added
## Related Documents
- `AGENTS.md` — Master agent configuration and context
- `specs/06-Decision-Records/` — All Architecture Decision Records
- `specs/05-Engineering-Guidelines/` — Backend, frontend, and testing guidelines
+30
View File
@@ -0,0 +1,30 @@
# lcbp3 Development Guidelines
Auto-generated from all feature plans. Last updated: 2026-05-30
## Active Technologies
- TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar) + Ollama (AI runtime), BullMQ (job queues), TypeORM (ORM), Redis (caching/locks), MariaDB 11.8 (database) (232-typhoon-ocr-integration)
## Project Structure
```text
backend/
frontend/
tests/
```
## Commands
cd src [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] pytest [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] ruff check .
## Code Style
TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar) : Follow standard conventions
## Recent Changes
- 232-typhoon-ocr-integration: Added TypeScript 5.x (NestJS 11 backend, Next.js 16 frontend), Python 3.11 (OCR sidecar) + Ollama (AI runtime), BullMQ (job queues), TypeORM (ORM), Redis (caching/locks), MariaDB 11.8 (database)
<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->
@@ -1,8 +1,8 @@
# `.agents/skills/` — LCBP3 Agent Skill Pack # `.agents/skills/` — LCBP3 Agent Skill Pack
**Version:** 1.9.0 | **Last Updated:** 2026-05-17 | **Total Skills:** 23 **Version:** 1.9.0 | **Last Updated:** 2026-06-07 | **Total Skills:** 24
Agent skills for AI-assisted development in **Windsurf IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools). Agent skills for AI-assisted development in **Devin IDE** (and compatible agents: Codex CLI, opencode, Amp, Antigravity, AGENTS.md-aware tools).
--- ---
@@ -14,6 +14,7 @@ Agent skills for AI-assisted development in **Windsurf IDE** (and compatible age
├── skills.md # Overview + dependency matrix + health monitoring ├── skills.md # Overview + dependency matrix + health monitoring
├── _LCBP3-CONTEXT.md # Shared LCBP3 context injected into every speckit-* skill ├── _LCBP3-CONTEXT.md # Shared LCBP3 context injected into every speckit-* skill
├── README.md # (this file) ├── README.md # (this file)
├── save-memory/ # Session log & project memory update
├── nestjs-best-practices/ # Backend rules (40 rules across 10 categories) ├── nestjs-best-practices/ # Backend rules (40 rules across 10 categories)
├── next-best-practices/ # Frontend rules (Next.js 15+) ├── next-best-practices/ # Frontend rules (Next.js 15+)
├── e2e-testing/ # Playwright E2E testing patterns (POM, flaky tests, CI/CD) ├── e2e-testing/ # Playwright E2E testing patterns (POM, flaky tests, CI/CD)
@@ -30,12 +31,10 @@ Each skill directory contains:
--- ---
## 🚀 How Windsurf Invokes These Skills ## 🚀 How Devin Invokes These Skills
Windsurf exposes two entry points: 1. **Skill tool** — Devin discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
2. **Slash commands**`.devin/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
1. **Skill tool** — Windsurf discovers skills by scanning `.agents/skills/*/SKILL.md` frontmatter. Skills marked `user-invocable: false` are used silently by Cascade.
2. **Slash commands**`.windsurf/workflows/*.md` wraps each skill as a slash command (e.g. `/04-speckit.plan`). The workflow file is short; the heavy lifting is delegated to the skill via `skill` tool.
Both paths end up executing the same `SKILL.md` instructions. Both paths end up executing the same `SKILL.md` instructions.
@@ -66,13 +65,13 @@ Use `/00-speckit.all` to run specify → clarify → plan → tasks → analyze
From repo root: From repo root:
| Script | Purpose | | Script | Purpose |
| --------------------------------------------------------- | ----------------------------------------------------------- | | ------------------------------------------------------ | ---------------------------------------------------------- |
| `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch | | `./.agents/scripts/bash/check-prerequisites.sh --json` | Emit `FEATURE_DIR` + `AVAILABLE_DOCS` for a feature branch |
| `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` | | `./.agents/scripts/bash/setup-plan.sh --json` | Emit `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, `BRANCH` |
| `./.agents/scripts/bash/update-agent-context.sh windsurf` | Append tech entries to `AGENTS.md` | | `./.agents/scripts/bash/update-agent-context.sh devin` | Append tech entries to `AGENTS.md` |
| `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence | | `./.agents/scripts/bash/audit-skills.sh` | Validate all `SKILL.md` frontmatter + presence |
| `./.agents/scripts/bash/validate-versions.sh` | Version consistency check | | `./.agents/scripts/bash/validate-versions.sh` | Version consistency check |
| `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.windsurf/workflows/*.md` wrapper | | `./.agents/scripts/bash/sync-workflows.sh` | Verify every skill has a `.devin/workflows/*.md` wrapper |
All scripts mirror to `.agents/scripts/powershell/*.ps1` for Windows. All scripts mirror to `.agents/scripts/powershell/*.ps1` for Windows.
@@ -97,7 +96,7 @@ To add a new skill:
1. Create `NAME/SKILL.md` with frontmatter: `name`, `description`, `version: 1.9.0`, `scope`, `depends-on`. 1. Create `NAME/SKILL.md` with frontmatter: `name`, `description`, `version: 1.9.0`, `scope`, `depends-on`.
2. Append an LCBP3 context reference pointing to `_LCBP3-CONTEXT.md`. 2. Append an LCBP3 context reference pointing to `_LCBP3-CONTEXT.md`.
3. Wrap with `.windsurf/workflows/NAME.md` so it becomes a slash command. 3. Wrap with `.devin/workflows/NAME.md` so it becomes a slash command.
4. Update [`skills.md`](./skills.md) dependency matrix. 4. Update [`skills.md`](./skills.md) dependency matrix.
5. Run `./.agents/scripts/bash/audit-skills.sh` → must pass. 5. Run `./.agents/scripts/bash/audit-skills.sh` → must pass.
@@ -5,14 +5,14 @@
**Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System **Project:** NAP-DMS (LCBP3) — Laem Chabang Port Phase 3 Document Management System
**Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI) **Stack:** NestJS 11 + Next.js 16 + TypeScript + MariaDB 11.8 + Redis + BullMQ + Elasticsearch + Ollama (on-prem AI)
**Version:** 1.8.9 (2026-04-18) **Version:** 1.9.7 (2026-05-25)
--- ---
## 📌 Canonical Rule Sources (read in this order) ## 📌 Canonical Rule Sources (read in this order)
1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`. 1. **`AGENTS.md`** (repo root) — primary rule file for AI agents; supersedes legacy `GEMINI.md`.
2. **`specs/06-Decision-Records/`** — architectural decisions (22 ADRs); ADR priority > Engineering Guidelines. 2. **`specs/06-Decision-Records/`** — architectural decisions (29 ADRs); ADR priority > Engineering Guidelines.
3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns. 3. **`specs/05-Engineering-Guidelines/`** — backend/frontend/testing/i18n/git patterns.
4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation). 4. **`specs/00-Overview/00-02-glossary.md`** — domain terminology (Correspondence / RFA / Transmittal / Circulation).
5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails). 5. **`specs/00-Overview/00-03-product-vision.md`** — project constitution (Vision, Strategic Pillars, Guardrails).
@@ -29,6 +29,7 @@
- **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone. - **ADR-002 Document Numbering:** Redis Redlock + TypeORM `@VersionColumn` (double-lock). Never use application-side counter alone.
- **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread. - **ADR-008 Notifications:** BullMQ queue — never inline email/notification in a request thread.
- **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023) - **ADR-023/023A AI Boundary:** Ollama on Admin Desktop only; AI → DMS API → DB (never direct DB/storage). 2-model stack: `gemma4:e4b Q8_0` + `nomic-embed-text`. BullMQ `ai-realtime` / `ai-batch` queues. Human-in-the-loop validation required. (ADR-018 superseded by ADR-023)
- **ADR-029 Dynamic Prompt Management:** Prompt templates in DB (`ai_prompts`), never hardcoded in processor; Redis cache `ai:prompt:active:{type}` TTL 60s; `activate()` runs in DB transaction + Redis DEL after commit; `system.manage_all` guard on all mutations.
- **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs. - **ADR-007 Error Handling:** Layered (Validation / Business / System); `BusinessException` hierarchy; user-friendly `userMessage` + `recoveryAction`; technical stack only in logs.
- **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`). - **TypeScript Strict:** Zero `any`, zero `console.log` (use NestJS `Logger`).
- **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`). - **i18n:** No hardcoded Thai/English strings in components — use i18n keys (see `05-08-i18n-guidelines.md`).
@@ -54,7 +55,7 @@
## 📁 Key Files for Generating / Validating Artifacts ## 📁 Key Files for Generating / Validating Artifacts
| When you need... | Read | | When you need... | Read |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------- | | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` | | A new feature spec | `.agents/skills/speckit-specify/templates/spec-template.md` + `specs/01-Requirements/01-06-edge-cases-and-rules.md` |
| A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs | | A plan | `.agents/skills/speckit-plan/templates/plan-template.md` + relevant ADRs |
| Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` | | Task breakdown | `.agents/skills/speckit-tasks/templates/tasks-template.md` + existing patterns in `specs/08-Tasks/` |
@@ -62,6 +63,12 @@
| Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` | | Schema / table definition | `specs/03-Data-and-Storage/lcbp3-v1.9.0-schema-02-tables.sql` + `03-01-data-dictionary.md` |
| RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` | | RBAC / permissions | `specs/03-Data-and-Storage/lcbp3-v1.8.0-seed-permissions.sql` + `01-02-01-rbac-matrix.md` |
| Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` | | Release / hotfix | `specs/04-Infrastructure-OPS/04-08-release-management-policy.md` |
| ADR-024 Intent Class. | `specs/06-Decision-Records/ADR-024-intent-classification-strategy.md` |
| ADR-025 AI Tool Layer | `specs/06-Decision-Records/ADR-025-ai-tool-layer-architecture.md` |
| ADR-026 Chat UI | `specs/06-Decision-Records/ADR-026-document-chat-ui-pattern.md` |
| ADR-027 AI Admin Console | `specs/06-Decision-Records/ADR-027-ai-admin-console-and-dynamic-control.md` |
| ADR-028 Migration Refactor | `specs/06-Decision-Records/ADR-028-migration-architecture-refactor.md` |
| ADR-029 Dynamic Prompts | `specs/06-Decision-Records/ADR-029-dynamic-prompt-management.md` |
--- ---
@@ -83,7 +90,7 @@
- [ ] Business comments in Thai, code identifiers in English - [ ] Business comments in Thai, code identifiers in English
- [ ] Schema changes via SQL directly (not migration) - [ ] Schema changes via SQL directly (not migration)
- [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+) - [ ] Test coverage meets targets (Backend 70%+, Business Logic 80%+)
- [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A for AI work) - [ ] Relevant ADRs referenced (007/008/009/016/019/021/023/023A/024-029 for AI work)
- [ ] Domain glossary terms used correctly - [ ] Domain glossary terms used correctly
- [ ] Error handling: `Logger` + `HttpException` / `BusinessException` - [ ] Error handling: `Logger` + `HttpException` / `BusinessException`
- [ ] i18n keys used (no hardcode text) - [ ] i18n keys used (no hardcode text)
@@ -6454,7 +6454,7 @@ CREATE TABLE ai_audit_log (
user_id INT NOT NULL, user_id INT NOT NULL,
action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc. action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc.
file_id INT, file_id INT,
model VARCHAR(64), -- 'gemma-4:7b', 'paddleocr-v3' model VARCHAR(64), -- 'gemma-4:7b', 'typhoon-np-dms-ocr', 'tesseract-ocr'
confidence DECIMAL(4,3), confidence DECIMAL(4,3),
input_hash CHAR(64), -- SHA-256 of input for replay detection input_hash CHAR(64), -- SHA-256 of input for replay detection
output_summary JSON, output_summary JSON,
@@ -137,7 +137,7 @@ CREATE TABLE ai_audit_log (
user_id INT NOT NULL, user_id INT NOT NULL,
action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc. action VARCHAR(64) NOT NULL, -- 'ai.extract_metadata', 'ai.classify', etc.
file_id INT, file_id INT,
model VARCHAR(64), -- 'gemma-4:7b', 'paddleocr-v3' model VARCHAR(64), -- 'gemma-4:7b', 'typhoon-np-dms-ocr', 'tesseract-ocr'
confidence DECIMAL(4,3), confidence DECIMAL(4,3),
input_hash CHAR(64), -- SHA-256 of input for replay detection input_hash CHAR(64), -- SHA-256 of input for replay detection
output_summary JSON, output_summary JSON,

Some files were not shown because too many files have changed in this diff Show More