Skip to content

[finding] Ten declared RestServerConfig keys are normalized by RestServer and read by nothing — routes.* entirely, crud.patterns / objectParamStyle, metadata.cacheTtl / endpoints.schema, batch.defaultAtomic / operations.upsertMany (ADR-0049 enforce-or-remove candidates) #14369

Description

@os-trump

Observation from #11984, which made RestServer.normalizeConfig parse and consume crud / metadata / batch / routes against the schemas that declare them. Executing the declared contract settles accept/reject; it does not make a key LIVE. While measuring which keys the method reads (the consume decision), the other half of the census came out: which normalized keys anything then reads.

What was measured

On origin/main @ 08e49496f, packages/rest/src non-test sources, every read site outside NormalizedRestServerConfig's type declaration and normalizeConfig itself (grep per key, comments excluded; the overrides hits are a request body and a test builder, not the config):

Read by the runtimecrud.operations.create|read|update|delete|list (route registration), crud.dataPrefix, metadata.prefix, metadata.enableCache, metadata.maskObjectFields, metadata.endpoints.types|items|item, batch.maxBatchSize, batch.enableBatchEndpoint, batch.operations.createMany|updateMany|deleteMany.

Normalized and never read (0 sites each) — ten declared keys:

sub-object key declared as
routes includeObjects z.array(z.string()).optional()
routes excludeObjects z.array(z.string()).optional()
routes nameTransform enum none / plural / kebab-case / camelCase, default none
routes overrides per-object enabled / basePath / operations record
crud patterns enum-keyed record of CrudEndpointPattern
crud objectParamStyle enum path / query, default path
metadata cacheTtl z.number().int().default(3600)
metadata endpoints.schema z.boolean().default(true)
batch defaultAtomic z.boolean().default(true)
batch operations.upsertMany z.boolean().default(true)

No other package reads them off the REST config either (repo-wide grep for nameTransform / objectParamStyle / defaultAtomic outside packages/spec and this file: 0). None of the four schemas has an entry in packages/spec/liveness/api.json.

So, for example, routes.nameTransform: 'plural' is accepted, validated, normalized — and every route still mounts under the object's raw name; routes.excludeObjects: ['sys_log'] excludes nothing; metadata.cacheTtl: 60 changes no header; batch.defaultAtomic: false changes no batch. Declared-but-unenforced is the ADR-0049 class; the spec seat's own RestServerConfigSchema @example advertises routes: { excludeObjects: ['system_log'] }, so the docs promise a capability the runtime does not deliver (Prime Directive #10).

Not prejudged

Each key wants its own enforce-or-remove call — routes.* reads like a designed-but-never-wired feature (enforce would be real work in route generation), metadata.cacheTtl like a knob that lost its consumer (if kept, it also wants a lower bound: the schema declares .int() only, so a negative TTL is accepted — #11984 pins -1 as accepted because that is what the contract says), and endpoints.schema / upsertMany / defaultAtomic like switches whose routes were never built. The spec-property-retirement playbook covers the remove route; the enforce route is a feature per key. Related: #14365 (the patterns / overrides.*.operations record declarations) and #14366 (consume the parsed api output).

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions