Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
# 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.