5.7 KiB
OpenSpec Change: enterprise-validation
- Change ID: enterprise-validation
- Package:
@suaveplan/validation - Category: universal
- Target path:
packages/universal/validation - Status: IN PROGRESS
- Date: 2026-04-18
- Reference spec:
/mnt/s/web/suaveplan/enterprise/validation.md
Summary
Greenfield implementation of @suaveplan/validation for the genesis branch. The existing main-branch validation package provides the baseline public-API surface to preserve; this change delivers a runtime schema-validation library with a Zod-compatible API surface, exhaustive schema types (string, number, boolean, date, array, object, union, intersection, literal, enum, nullable, optional, record, tuple, coerce), async refinements, hooks, structured errors, property-based tests, and benchmarks. The library is entirely self-contained — it does NOT depend on Zod; it is its own parser, used alongside Zod at the monorepo level for other packages.
Current-state audit (genesis)
The package does not exist on genesis yet — this is a fresh build.
Available workspace deps on genesis
| Package | Available |
|---|---|
@suaveplan/error |
✅ |
@suaveplan/types |
✅ |
@suaveplan/events |
✅ |
@suaveplan/opentelemetry |
❌ not yet built — use @opentelemetry/api directly |
@suaveplan/feature-flags |
❌ not yet built — skip |
@suaveplan/schema-registry |
❌ not yet built — skip |
External deps (via catalog):
@opentelemetry/api→catalog:observabilitytslib→catalog:build
Dev deps (via catalog):
vitest,@vitest/coverage-istanbul→catalog:testingfast-check→catalog:testingmitata→catalog:testing
Preserved public API surface (from main branch)
Core
BaseSchema<TInput, TOutput>— abstract base class with.parse(input),.safeParse(input),.parseAsync(input),.safeParseAsync(input),.refine(fn, msg?),.transform(fn),.optional(),.nullable(),.describe(description)
Types
AnySchema,SchemaInput<S>,SchemaOutput<S>— utility type extractorsInfer<S>,InferInput<S>— schema type inference helpersParseResult<T>—ParseSuccess<T> | ParseFailureParseSuccess<T>—{ success: true; data: T }ParseFailure—{ success: false; error: ValidationError }ParseContext— internal traversal contextValidationIssue—{ code: ValidationCode; path: (string | number)[]; message: string; input?: unknown }ValidationCode— string union of all built-in issue codesFlattenedErrors—{ formErrors: string[]; fieldErrors: Record<string, string[]> }RefineFn<T>,AsyncRefineFn<T>,TransformFn<T, U>,CustomRule<T>StringRuleOptions,NumberRuleOptions,ObjectShape
Errors
ValidationErrorextendsSuaveplanError—.flatten(),.issuesgetter,.format()ValidationErrorOptions— constructor optionsFlattenedErrors— return type of.flatten()
Schema factories
string()→StringSchema—.min(n),.max(n),.length(n),.regex(r),.email(),.url(),.uuid(),.startsWith(s),.endsWith(s),.includes(s),.trim(),.toLowerCase(),.toUpperCase()number()→NumberSchema—.min(n),.max(n),.int(),.positive(),.negative(),.multipleOf(n),.finite()boolean()→BooleanSchemadate()→DateSchema—.min(d),.max(d)array(schema)→ArraySchema—.min(n),.max(n),.length(n),.nonempty()object(shape)→ObjectSchema—.strict(),.passthrough(),.strip(),.pick(keys),.omit(keys),.partial(),.required(),.extend(shape),.merge(other)union(schemas)→UnionSchemaintersection(a, b)→IntersectionSchemaliteral(value)→LiteralSchemaenumeration(values)→EnumSchemanullable(schema)→NullableSchemaoptional(schema)→OptionalSchemarecord(schema)→RecordSchematuple(schemas)→TupleSchema
Coerce utilities
coerce(schema)→CoercedSchema— wraps any schema with string→type coercioncoerceString(input)→stringcoerceNumber(input)→numbercoerceBoolean(input)→booleancoerceDate(input)→DateCoercedSchema<T>(type)
Compose utilities
mergeResults(results)— merges multipleParseResultarrays into onepipe(schema, ...transforms)— sequential schema pipeline
Hook types
ValidationHookMap— lifecycle hooks:beforeValidate,afterValidate,onErrorValidationHookData<T>— data passed to each hookValidationValidatingHandler— handler signature
New additions for genesis
Structured errors
ValidationErrorextendsSuaveplanErrorwith codes underVALIDATION.*namespace- Codes:
VALIDATION.STRING.*,VALIDATION.NUMBER.*,VALIDATION.ARRAY.*,VALIDATION.OBJECT.*,VALIDATION.UNION.NO_MATCH,VALIDATION.CUSTOM.REFINEMENT
OTel instrumentation
- Counters:
validation.parse.success,validation.parse.failure - Histogram:
validation.parse.duration_ms(per schema type label)
Property-based tests (fast-check)
- Round-trip:
schema.parse(schema.parse(x)) === schema.parse(x)(idempotency) - Error propagation: any invalid input to
.parse()always returnsParseFailure(never throws) - Union exhaustiveness: input matching none of the union arms always fails
Benchmarks (mitata)
object(shape).parse(data)for 10-field object — 100k iterationsarray(string()).parse(arr)for 1 000-element arrayunionwith 10 arms — best-case and worst-case branch
Impact
- Adds one new package:
packages/universal/validation - Adds one new spec capability:
validation - No existing package consumers on genesis yet