# OpenSpec Change: enterprise-react-rule-builder - **Change ID**: enterprise-react-rule-builder - **Package**: `@suaveplan/react-rule-builder` - **Category**: react - **Target path**: `react/forms/react-rule-builder` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/react-rule-builder.md` --- ## Summary Deliver `@suaveplan/react-rule-builder` on genesis from scratch at enterprise quality. A visual rule-builder UI that reads/writes a Rule AST: `RuleBuilder`, `LogicGroup` (AND/OR/NOT), `ConditionRow`, `useRuleBuilder` hook, drag-and-drop reordering via `@suaveplan/react-dnd`, and AST path utilities. Genesis deletes the `src/mocks/` directory entirely, adds Storybook stories, Playwright E2E for drag-drop reorder, Zod schema validation at the rule-build boundary, and 100% test coverage using real workspace deps. --- ## Current-state audit (genesis) Package does not exist on genesis — fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | `RuleBuilderError` | | `@suaveplan/react-dnd` (`workspace:^`) | Drag-drop reordering | | `@suaveplan/react-translate` (`workspace:^`) | i18n | | `@suaveplan/react-ui` (`workspace:^`) | UI primitives | | `zod` (`catalog:forms`) | Rule AST validation | External: `tslib catalog:build`. React 18 peer. --- ## Preserved public API surface ```ts RuleBuilder, LogicGroup, ConditionRow useRuleBuilder // Helpers createEmptyCondition, createEmptyGroup getApplicableOperators, getRuleAtPath, insertRuleAtPath, removeRuleAtPath, updateRuleAtPath DEFAULT_OPERATORS // Types ConditionRowProps, FieldDefinition, LogicGroupProps, OnRuleChange, OperatorOption, RuleBuilderProps, SelectOption ``` --- ## New additions for genesis 1. **No mocks** — all tests use real `@suaveplan/react-dnd`, `@suaveplan/react-translate`, `@suaveplan/react-ui`. 2. **`RuleBuilderError`** — codes: `RULE_BUILDER_INVALID_PATH`, `RULE_BUILDER_INVALID_RULE`. 3. **Zod `RuleSchema`** — validates the built rule before firing `onRuleChange`; invalid rule throws `RuleBuilderError(RULE_BUILDER_INVALID_RULE)`. 4. **Stories** — `RuleBuilder` default, nested-groups, drag-reorder, playground. 5. **Playwright E2E** — add condition, drag to reorder, verify AST shape. --- ## File layout ```text react/forms/react-rule-builder/ package.json tsconfig.json vitest.config.ts src/ index.ts components/ rule-builder/ (tsx + types + md + test + stories + index) logic-group/ (tsx + types + md + test + stories + index) condition-row/ (tsx + types + md + test + stories + index) hooks/ use-rule-builder/ (ts + types + md + test + index) types/ rule-builder.types.ts utils/ rule-helpers/ (ts + md + test + index) e2e/ rule-builder.spec.ts ```