mAi
9940dd8216
feat(deadline-system): P2 — condition_expr write-validator ( m/paliad#149 )
...
Phase 2 P2 (design §4.1). Locks the condition_expr grammar to:
CondExpr := { "flag": "<known_flag>" }
| { "op": "and"|"or", "args": [<CondExpr>, ...] }
Where <known_flag> must exist in paliad.scenario_flag_catalog (today:
with_ccr / with_amend / with_cci; editorial adds via the catalog
table as needed).
Wire-time validation in RuleEditorService.Create and UpdateDraft —
the rule editor surfaces a 400 with a friendly message before the row
hits the DB. Empty / JSON null inputs pass through (the "no gate"
shape; stored as NULL column).
The validator:
* walks the JSON tree once, collecting every leaf flag name
* rejects mutually-exclusive shapes (leaf + composite in one node)
* rejects empty args, bad op values, empty flag strings
* does ONE batch lookup of the collected leaf names against the
catalog (regardless of expression depth)
Tests:
* 9 shape-only unit tests covering every reject path (no DB needed)
* TestValidateConditionExpr_LiveCatalog covers 6 good shapes + 2
unknown-flag cases against the live catalog
* TestConditionExpr_AllLiveRowsValidate runs the validator over
every active+published condition_expr in paliad.sequencing_rules
to enforce the §4.1 invariant on every deploy (today's 18 rows
all conform — verified via Supabase MCP pre-flight)
Live-DB tests skip cleanly when TEST_DATABASE_URL is unset (same
posture as sibling live tests in this package).
Design: docs/design-deadline-system-revision-2026-05-27.md §4.1
(grammar formalisation). t-paliad-331.
2026-05-27 15:22:53 +02:00
..
2026-05-06 16:05:00 +02:00
2026-05-22 15:17:24 +02:00
2026-05-26 19:24:41 +02:00
2026-05-21 21:21:32 +02:00
2026-05-22 15:17:24 +02:00
2026-05-20 13:05:27 +02:00
2026-05-20 14:46:36 +02:00
2026-05-20 14:46:36 +02:00
2026-05-25 15:49:39 +02:00
2026-04-30 16:46:31 +02:00
2026-05-19 12:51:52 +02:00
2026-05-26 18:19:55 +02:00
2026-05-26 18:17:21 +02:00
2026-05-25 15:28:37 +02:00
2026-05-20 13:05:27 +02:00
2026-05-07 20:58:57 +02:00
2026-05-07 20:58:57 +02:00
2026-05-07 20:58:57 +02:00
2026-05-20 13:26:23 +02:00
2026-04-17 11:59:49 +02:00
2026-05-13 00:11:14 +02:00
2026-05-13 00:11:14 +02:00
2026-05-20 13:26:23 +02:00
2026-04-30 16:46:31 +02:00
2026-05-07 22:41:18 +02:00
2026-05-07 22:41:18 +02:00
2026-05-20 15:50:21 +02:00
2026-05-20 15:50:21 +02:00
2026-05-20 15:38:30 +02:00
2026-05-20 15:38:30 +02:00
2026-05-20 15:38:30 +02:00
2026-05-20 15:38:30 +02:00
2026-05-20 15:50:21 +02:00
2026-05-27 15:22:53 +02:00
2026-05-27 15:22:53 +02:00
2026-05-06 12:47:12 +02:00
2026-05-20 13:55:56 +02:00
2026-05-20 19:15:32 +02:00
2026-05-22 15:53:19 +02:00
2026-05-22 15:53:19 +02:00
2026-05-20 13:55:56 +02:00
2026-05-20 19:15:32 +02:00
2026-05-04 12:03:56 +02:00
2026-05-25 16:06:35 +02:00
2026-05-25 16:06:35 +02:00
2026-05-15 17:53:44 +02:00
2026-05-26 20:07:48 +02:00
2026-05-25 15:36:08 +02:00
2026-05-26 13:01:07 +02:00
2026-04-30 16:46:31 +02:00
2026-05-26 19:53:24 +02:00
2026-05-06 17:16:17 +02:00
2026-05-22 15:48:47 +02:00
2026-05-26 19:53:24 +02:00
2026-05-26 19:53:24 +02:00
2026-05-19 13:05:54 +02:00
2026-05-20 15:19:48 +02:00
2026-04-29 22:09:39 +02:00
2026-05-20 15:19:48 +02:00
2026-05-20 15:19:48 +02:00
2026-05-05 13:29:47 +02:00
2026-05-18 12:13:24 +02:00
2026-05-25 16:45:07 +02:00
2026-05-25 16:45:07 +02:00
2026-05-16 01:17:23 +02:00
2026-05-26 17:59:58 +02:00
2026-05-04 19:49:37 +02:00
2026-05-25 14:54:51 +02:00
2026-05-15 01:09:31 +02:00
2026-05-18 15:06:04 +02:00
2026-04-30 16:46:31 +02:00
2026-05-20 13:03:57 +02:00
2026-05-20 13:03:57 +02:00
2026-05-26 18:17:21 +02:00
2026-05-25 17:46:58 +02:00
2026-05-25 17:46:58 +02:00
2026-05-25 17:46:58 +02:00
2026-05-20 19:15:32 +02:00
2026-05-20 19:15:32 +02:00
2026-05-26 22:01:10 +02:00
2026-05-27 15:07:01 +02:00
2026-05-27 10:14:37 +02:00
2026-05-27 15:07:01 +02:00
2026-05-26 11:21:29 +02:00
2026-05-26 11:19:01 +02:00
2026-05-27 10:14:37 +02:00
2026-05-06 12:47:12 +02:00
2026-05-26 13:01:07 +02:00
2026-04-20 12:34:38 +02:00
2026-04-29 22:09:39 +02:00
2026-05-07 22:41:18 +02:00
2026-05-07 22:41:18 +02:00
2026-04-30 03:18:03 +02:00
2026-05-27 15:11:48 +02:00
2026-05-20 15:19:48 +02:00
2026-05-07 20:58:57 +02:00
2026-05-07 20:58:57 +02:00
2026-05-03 18:39:06 +02:00
2026-05-15 03:03:12 +02:00
2026-05-08 12:42:57 +02:00
2026-05-08 21:48:08 +02:00
2026-05-22 15:17:24 +02:00
2026-05-08 21:48:08 +02:00
2026-05-08 21:48:08 +02:00
2026-05-06 16:41:41 +02:00
2026-05-26 09:41:07 +02:00
2026-05-07 22:29:39 +02:00
2026-05-07 22:21:45 +02:00
2026-05-18 12:13:24 +02:00
2026-05-20 14:53:22 +02:00
2026-05-26 13:01:07 +02:00
2026-05-20 14:55:55 +02:00
2026-05-21 14:52:50 +02:00
2026-05-07 22:58:44 +02:00
2026-05-04 19:30:37 +02:00
2026-05-27 10:09:33 +02:00
2026-05-27 10:09:33 +02:00
2026-05-22 23:43:15 +02:00
2026-05-26 09:56:15 +02:00
2026-05-18 12:13:24 +02:00
2026-05-09 18:52:01 +02:00
2026-05-18 15:06:04 +02:00
2026-05-20 14:55:55 +02:00
2026-05-26 19:53:24 +02:00
2026-04-30 16:46:31 +02:00
2026-05-07 21:50:31 +02:00
2026-05-15 00:06:37 +02:00
2026-05-25 15:49:39 +02:00
2026-05-26 19:53:24 +02:00
2026-05-18 15:06:04 +02:00
2026-05-27 15:22:53 +02:00
2026-05-27 15:02:01 +02:00
2026-05-26 17:48:56 +02:00
2026-05-26 19:23:40 +02:00
2026-05-26 19:23:40 +02:00
2026-05-26 20:04:40 +02:00
2026-05-26 20:04:40 +02:00
2026-05-18 16:52:38 +02:00
2026-05-26 20:21:12 +02:00
2026-05-26 20:15:28 +02:00
2026-05-25 17:03:34 +02:00
2026-05-26 19:23:40 +02:00
2026-05-26 20:15:28 +02:00
2026-05-26 20:15:28 +02:00
2026-05-25 16:32:45 +02:00
2026-05-25 15:12:10 +02:00
2026-05-21 15:23:24 +02:00
2026-05-21 15:23:24 +02:00
2026-05-26 19:23:40 +02:00
2026-05-26 20:26:53 +02:00
2026-05-26 20:26:53 +02:00
2026-05-25 16:03:03 +02:00
2026-05-25 16:51:35 +02:00
2026-05-26 19:53:24 +02:00
2026-05-20 15:19:48 +02:00
2026-05-20 15:19:48 +02:00
2026-05-20 15:24:06 +02:00
2026-05-25 17:46:58 +02:00
2026-05-25 17:46:58 +02:00
2026-05-20 13:05:27 +02:00
2026-05-20 14:46:36 +02:00
2026-04-30 16:46:31 +02:00
2026-05-20 15:19:48 +02:00
2026-05-07 12:51:37 +02:00
2026-05-07 12:51:37 +02:00
2026-05-25 15:37:00 +02:00
2026-05-25 17:46:58 +02:00
2026-05-25 17:46:58 +02:00
2026-05-04 12:03:56 +02:00
2026-05-04 18:57:06 +02:00
2026-05-21 09:54:23 +02:00