feat: harden CRUD resource contract checks (AEG-V16-020)
Reject incomplete permission, version, concurrency, idempotency, and sensitive-column contracts. Preserve runtime regression evidence; status remains IN_PROGRESS pending predecessor acceptance.
This commit is contained in:
@@ -17,6 +17,13 @@ export interface CrudResourceDefinition<TQuery, TRow, TForm> {
|
||||
}
|
||||
export function assertCrudResourceDefinition(definition: CrudResourceDefinition<unknown, unknown, unknown>): void {
|
||||
if (!definition.resourceId.trim()) throw new Error('resourceId is required')
|
||||
if (!definition.querySchemaVersion.trim() || !definition.responseSchemaVersion.trim()) throw new Error('schema versions are required')
|
||||
if (!definition.permissionPolicy.trim()) throw new Error('permissionPolicy is required')
|
||||
if (definition.concurrencyMode !== 'NONE' && definition.concurrencyMode !== 'ETAG_IF_MATCH') throw new Error('invalid concurrencyMode')
|
||||
if (definition.idempotencyMode !== 'NONE' && definition.idempotencyMode !== 'IDEMPOTENCY_KEY') throw new Error('invalid idempotencyMode')
|
||||
const fields = new Set(definition.columns.map(x => x.field))
|
||||
for (const sensitive of definition.sensitiveFields) if (!fields.has(sensitive)) throw new Error(`Sensitive field '${sensitive}' has no grid column contract`)
|
||||
for (const sensitive of definition.sensitiveFields) {
|
||||
const column = definition.columns.find(x => x.field === sensitive)
|
||||
if (!fields.has(sensitive) || !column?.sensitive) throw new Error(`Sensitive field '${sensitive}' has no sensitive grid column contract`)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user