Files
2026-05-27 23:29:53 +01:00

4.4 KiB

Tasks: enterprise-react-rule-builder

Change ID: enterprise-react-rule-builder Package: @suaveplan/react-rule-builder Target path: react/forms/react-rule-builder Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/react-dnd, @suaveplan/react-translate, @suaveplan/react-ui


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal layout.
  • Write package.json at 0.1.0 with "sideEffects": false, exports map.
  • Dependencies: @suaveplan/error workspace:^, @suaveplan/react-dnd workspace:^, @suaveplan/react-translate workspace:^, @suaveplan/react-ui workspace:^, zod catalog:forms, @opentelemetry/api catalog:observability, tslib catalog:build.
  • Write tsconfig.json, vitest.config.ts, scripts.
  • Confirm src/mocks/ directory is NOT created — no mocks under any circumstance.

2. Error codes and types

  • Define RuleBuilderError extending SuaveplanError; codes: RULE_BUILDER_INVALID_PATH, RULE_BUILDER_INVALID_RULE.
  • Define FieldDefinition, OperatorOption, SelectOption, RuleBuilderProps, LogicGroupProps, ConditionRowProps, OnRuleChange.
  • Define DEFAULT_OPERATORS constant.
  • Write RuleSchema Zod schema for the rule AST.

3. Utils (src/utils/rule-helpers/)

  • Implement createEmptyCondition(fieldDefs), createEmptyGroup().
  • Implement getApplicableOperators(field, fieldDefs), getRuleAtPath(rule, path), insertRuleAtPath(rule, path, item), removeRuleAtPath(rule, path), updateRuleAtPath(rule, path, updates).
  • Validate paths in get/insert/remove/update — throw RuleBuilderError(RULE_BUILDER_INVALID_PATH) on invalid path.
  • Write rule-helpers.test.ts (≤500 lines): each helper, nested paths, invalid path throws. { timeout: 5000 }.
  • Write rule-helpers.md.

4. Hook — useRuleBuilder

  • Manages rule state; exposes addCondition(path), addGroup(path), removeItem(path), updateCondition(path, updates), toggleLogic(path), moveItem(from, to).
  • Validates rule via RuleSchema before calling onRuleChange; on failure throws RuleBuilderError(RULE_BUILDER_INVALID_RULE).
  • Write use-rule-builder.test.ts: add, remove, update, move — all using real useRuleBuilder. { timeout: 5000 }.
  • Write use-rule-builder.md.

5. Components

ConditionRow

  • Field selector (from FieldDefinition[]), operator selector (from getApplicableOperators), value input. Uses @suaveplan/react-ui Select + Input.
  • Write test (real @suaveplan/react-ui provider), stories (default, all-operators, playground), md.

LogicGroup

  • AND/OR/NOT toggle (uses @suaveplan/react-ui ToggleGroup); renders children recursively; add-condition + add-group buttons; drag handle wired to @suaveplan/react-dnd Draggable.
  • Write test (nested groups, drag reorder triggers moveItem), stories (default, nested, drag-reorder, playground), md.

RuleBuilder

  • Top-level: renders root LogicGroup; wraps useRuleBuilder; wires DndProvider from @suaveplan/react-dnd.
  • Write test (full render with real deps), stories (default, with-field-definitions, nested-groups, drag-reorder, playground), md.

6. E2E

  • e2e/rule-builder.spec.ts — Playwright:
    • Add a condition, set field + operator + value, verify AST.
    • Add nested group, verify nesting.
    • Drag condition to reorder, verify moveItem reflected in AST.

7. Verify and publish

  • bunx turbo lint typecheck test --filter=@suaveplan/react-rule-builder — green.
  • bunx turbo test:coverage --filter=@suaveplan/react-rule-builder — 100%.
  • bun scripts/publish.ts --package @suaveplan/react-rule-builder.
  • Archive change folder.