SKILL.md
Validation Architecture
Layer Responsibilities
core/ → SSOT: constraints + schemas (ArkType, Standard Schema)
api/ → Gatekeeper: reject invalid requests (sValidator)
front/ → UX: phase-based feedback (withValidationErrorMessages)
Design Decisions
Why constraints separate from schemas?
- Constraints are plain values (reusable in messages, tests, etc.)
- Schemas are validation logic (may change libraries)
- Types derived from constraints (SSOT)
Why Standard Schema?
- Library-agnostic interface (
@standard-schema/spec) - ArkType today, can swap to Zod/Valibot later
- Both api (sValidator) and front use same interface
Why phase-based validation in front?
onChange: lenient (no required checks) → no red during typingonDraftSubmit: intermediateonConfirmedSubmit: strict (all rules) → block invalid submit
Core schema is for "final correctness". Front needs UX timing control.
Why validate twice (front + api)?
- Front validation: UX improvement (optional, can fail)
- API validation: security boundary (required, never trust client)
Key Files
core/src/model/*/constraints.ts- constraint valuescore/src/model/*/schema.ts- ArkType schemasapi/src/model/*/index.ts- sValidator usagefront/src/model/common/lib/validation.ts- phase-based utilitiesfront/src/model//detail/form/inputs//validation.ts- field validation