Skip to content

Validation

Specification > Engineering

This chapter defines how public methods validate their inputs: one dedicated validation method per public method, one concern per request, a strict check order, and a uniform bulk-check pattern. It is conditional and applies to the JavaScript sources covered by the stack chapter.


Each public method MUST have exactly one dedicated validation method, and a single validation request MUST address a single concern. You MUST NOT widen a validator’s scope beyond the method it guards.

A validator MUST run its checks in a strict order and stop at the first failure:

StepCheck
1Existence — the required value is present.
2Early break — return immediately once a required value is missing.
3Detail — type, shape, and membership checks on the values that exist.

When a method validates many fields, you MUST express each field as a [ key, value, type, list ] tuple and check the set uniformly. Errors raised for array members MUST carry the offending index:

const checks = [
[ 'id', id, 'string', [] ],
[ 'role', role, 'string', [ 'admin', 'user' ] ],
[ 'tags', tags, 'array', [] ]
]
const errors = []
checks.forEach( ( [ key, value, type, list ], index ) => {
if( type !== 'array' && typeof value !== type ) {
errors.push( `[${ index }] ${ key }: expected ${ type }` )
}
if( list.length > 0 && !list.includes( value ) ) {
errors.push( `[${ index }] ${ key }: not in allowed list` )
}
} )

In each tuple, key names the field, value is the candidate, type is the expected type, and list is the optional set of allowed values; an empty list means there is no membership constraint.

A validator MUST return a structured result (for example { status, errors }) rather than a bare boolean, so a caller can read both the verdict and the per-field reasons.