Skip to content

Commit b57c077

Browse files
committed
feat: Enhance BaseValidationSchema with additional properties for governance and control
1 parent 87292f9 commit b57c077

File tree

1 file changed

+53
-18
lines changed

1 file changed

+53
-18
lines changed

packages/spec/src/data/validation.zod.ts

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,28 @@ import { z } from 'zod';
4949
* Base Validation Rule
5050
*
5151
* All validation rules extend from this base schema with common properties.
52+
*
53+
* ## Industry Standard Enhancements
54+
* - **Label/Description**: Essential for governance in large systems with thousands of rules.
55+
* - **Events**: granular control over triggering (Context-aware validation).
56+
* - **Tags**: categorization for reporting and management.
5257
*/
5358
const BaseValidationSchema = z.object({
54-
name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Unique rule name'),
59+
// Identification
60+
name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Unique rule name (snake_case)'),
61+
label: z.string().optional().describe('Human-readable label for the rule listing'),
62+
description: z.string().optional().describe('Administrative notes explaining the business reason'),
63+
64+
// Execution Control
5565
active: z.boolean().default(true),
66+
events: z.array(z.enum(['insert', 'update', 'delete'])).default(['insert', 'update']).describe('Trigger contexts'),
67+
68+
// Classification
69+
tags: z.array(z.string()).optional().describe('Categorization tags (e.g., "compliance", "billing")'),
70+
71+
// Feedback
5672
severity: z.enum(['error', 'warning', 'info']).default('error'),
57-
message: z.string().describe('Error message to display'),
73+
message: z.string().describe('Error message to display to the user'),
5874
});
5975

6076
/**
@@ -168,7 +184,22 @@ export const CrossFieldValidationSchema = BaseValidationSchema.extend({
168184
});
169185

170186
/**
171-
* 6. Async Validation
187+
* 6. JSON Structure Validation
188+
* Validates JSON fields against a JSON Schema.
189+
*
190+
* ## Use Cases
191+
* - Validating configuration objects stored in JSON fields
192+
* - Enforcing API payload structures
193+
* - Complex nested data validation
194+
*/
195+
export const JSONValidationSchema = BaseValidationSchema.extend({
196+
type: z.literal('json_schema'),
197+
field: z.string().describe('JSON field to validate'),
198+
schema: z.record(z.any()).describe('JSON Schema object definition'),
199+
});
200+
201+
/**
202+
* 7. Async Validation
172203
* Remote validation via API call or database query.
173204
*
174205
* ## Use Cases
@@ -278,14 +309,16 @@ export const CrossFieldValidationSchema = BaseValidationSchema.extend({
278309
* checkExpiration: true,
279310
* checkUsageLimit: true,
280311
* userId: '{{current_user_id}}'
281-
* }
282-
* }
283-
* ```
284-
*
285-
* ## Best Practices
286-
* - Always set a reasonable `timeout` (default is 5000ms)
287-
* - Use `debounce` for fields that are typed (300-500ms recommended)
288-
* - Implement proper error handling on the server side
312+
*method: z.enum(['GET', 'POST']).default('GET').describe('HTTP method for external call'),
313+
headers: z.record(z.string()).optional().describe('Custom headers for the request'),
314+
validatorFunction: z.string().optional().describe('Reference to custom validator function'),
315+
timeout: z.number().optional().default(5000).describe('Timeout in milliseconds'),
316+
debounce: z.number().optional().describe('Debounce delay in milliseconds'),
317+
params: z.record(z.any()).optional().describe('Additional parameters to pass to validator'),
318+
});
319+
320+
/**
321+
* 8 Implement proper error handling on the server side
289322
* - Cache validation results when appropriate
290323
* - Consider rate limiting for external API calls
291324
*/
@@ -303,14 +336,15 @@ export const AsyncValidationSchema = BaseValidationSchema.extend({
303336
* 7. Custom Validator Function
304337
* User-defined validation logic with code reference.
305338
*/
306-
export const CustomValidatorSchema = BaseValidationSchema.extend({
307-
type: z.literal('custom'),
308-
field: z.string().optional().describe('Field to validate (optional for record-level validation)'),
309-
validatorFunction: z.string().describe('Function name or reference to custom validator'),
310-
params: z.record(z.any()).optional().describe('Additional parameters for the validator'),
311-
});
339+
expoJSONValidationSchema,
340+
AsyncValidationSchema,
341+
CustomValidatorSchema,
342+
ConditionalValidationSchema,
343+
])
344+
);
312345

313346
/**
347+
* 9
314348
* Master Validation Rule Schema (forward declared for circular reference)
315349
*/
316350
export const ValidationRuleSchema: z.ZodType<any> = z.lazy(() =>
@@ -497,7 +531,8 @@ export const ValidationRuleSchema: z.ZodType<any> = z.lazy(() =>
497531
* type: 'cross_field',
498532
* name: 'amount_approval',
499533
* condition: 'amount > 100000 AND approval = null',
500-
* fields: ['amount', 'approval']
534+
* fieldJSONValidation = z.infer<typeof JSONValidationSchema>;
535+
export type s: ['amount', 'approval']
501536
* }
502537
* }
503538
* ```

0 commit comments

Comments
 (0)