76 lines
4.3 KiB
Markdown
76 lines
4.3 KiB
Markdown
# Proposal: Enterprise migration of `@suaveplan/form-builder`
|
|
|
|
- **Status**: PROPOSED
|
|
- **Package**: `@suaveplan/form-builder`
|
|
- **Category / plugin**: `ui` / `forms`
|
|
- **Tier**: universal (zero browser, zero React, zero Node)
|
|
- **Design**: ./design.md
|
|
- **Spec delta**: ./specs/form-builder/spec.md
|
|
|
|
## Why
|
|
|
|
`@suaveplan/form-builder` is the canonical universal-tier schema engine for dynamic forms in the
|
|
Suaveplan monorepo. The upstream copy at `../suaveplan/packages/universal/form-builder` ships only
|
|
ten field types, a thin synchronous validation surface (eight built-in rules), a single conditional
|
|
operator family (`eq` / `neq` / `in`), no dependency graph, no undo/redo, no submission pipeline,
|
|
no Zod schema generator, and no OpenTelemetry instrumentation. The renderer-agnostic schema engine
|
|
is expected to drive every form surface in the monorepo (admin panels, marketing onboarding flows,
|
|
the internal vault wizard), and the current surface is too thin to serve them. This migration ports
|
|
the package onto `genesis` at enterprise quality: full field-type registry, async validation,
|
|
cross-field validators, dependency-graph driven re-evaluation, undo/redo, JSON serialisation
|
|
round-trip, Zod schema generation, OTel instruments, and a stable error-code namespace.
|
|
|
|
## What changes
|
|
|
|
- New package `packages/ui/forms/form-builder/` at `0.1.0`.
|
|
- Zod-validated public schema (`FormSchema`, `FieldDefinition`, `FormSection`, `ValidationRule`,
|
|
`ConditionalRule`).
|
|
- Extensible `FieldRegistry` with 17 built-in field types: `text`, `number`, `email`, `url`,
|
|
`tel`, `password`, `select`, `multiselect`, `checkbox`, `radio`, `textarea`, `date`, `file`,
|
|
`range`, `hidden`, `group`, `array`.
|
|
- Sync + async validation pipeline with `AbortSignal` propagation and 11 built-in rule kinds
|
|
(`required`, `minLength`, `maxLength`, `min`, `max`, `pattern`, `email`, `url`, `oneOf`,
|
|
`equalsField`, `custom`).
|
|
- Conditional logic with 9 operators (`eq`, `neq`, `in`, `notIn`, `gt`, `lt`, `gte`, `lte`,
|
|
`contains`) and boolean composition (`and`, `or`, `not`).
|
|
- Field-level dependency graph with topological evaluation and cycle detection.
|
|
- Undo / redo on schema-mutation operations.
|
|
- Form-state machine emitting typed events through `EventBus<FormEventMap>` from
|
|
`@suaveplan/events`.
|
|
- JSON serialise / deserialise round-trip with versioned wire format.
|
|
- Zod schema generator: `toZodSchema(form)`.
|
|
- Submission pipeline: `prepare → validate → transform → submit` with injectable `Submitter`.
|
|
- Six stable `FORM_BUILDER.*` error codes via `defineCodes`.
|
|
- OTel instruments: three counters + two histograms.
|
|
|
|
## Parity Checklist
|
|
|
|
| Capability | Upstream | Migrated | Notes |
|
|
|---|---|---|---|
|
|
| `FormBuilder` class | ✅ | ✅ | Public API preserved. |
|
|
| Field types | ✅ (10) | ⬆️ (17) | Added `url`, `tel`, `password`, `multiselect`, `range`, `group`, `array`. |
|
|
| Validation rules | ✅ (8) | ⬆️ (11) | Added `url`, `oneOf`, `equalsField`. Async + cross-field validators added. |
|
|
| Conditional operators | ✅ (3) | ⬆️ (9 + boolean) | Added `notIn`, `gt`, `lt`, `gte`, `lte`, `contains`, plus `and` / `or` / `not`. |
|
|
| Sections | ✅ | ✅ | Plus `removeSection`. |
|
|
| Event bus | ✅ | ✅ | Migrated from `EventEmitter` to `EventBus<FormEventMap>` from `@suaveplan/events`. |
|
|
| Error codes | ✅ | ⬆️ | Migrated from `BaseError` to `defineCodes("FORM_BUILDER", …)`. |
|
|
| Dependency graph + topo eval | 🚫 | ⬆️ | New: required for chained conditional fields. |
|
|
| Undo / redo | 🚫 | ⬆️ | New: bounded mutation-history stack. |
|
|
| JSON round-trip | partial | ⬆️ | `serialiseForm` / `deserialiseForm` with Zod validation. |
|
|
| Zod schema generator | 🚫 | ⬆️ | New: `toZodSchema(form)` for `react-hook-form` consumers. |
|
|
| Submission pipeline | 🚫 | ⬆️ | New: pluggable `Submitter` with hooks. |
|
|
| OTel instrumentation | 🚫 | ⬆️ | New: 3 counters + 2 histograms. |
|
|
| Field registry (extensibility) | 🚫 | ⬆️ | New: downstream packages can contribute field types. |
|
|
|
|
## Impact
|
|
|
|
### Affected dependents
|
|
|
|
None on `genesis` (form-builder is a leaf at migration time). Downstream integration with
|
|
`@suaveplan/react-forms` is a follow-up change. Upstream main-branch consumers remain on the
|
|
unmigrated copy until their own migration land.
|
|
|
|
### Risk
|
|
|
|
Low. New package in a leaf position. Public API behaviour is exercised at 100% coverage.
|