Skip to content

Commit 31c2fca

Browse files
Copilothotlong
andcommitted
Address code review feedback - improve validation and documentation
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 2882d58 commit 31c2fca

File tree

5 files changed

+28
-18
lines changed

5 files changed

+28
-18
lines changed

content/docs/references/system/AuditConfig.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: AuditConfig Schema Reference
77

88
| Property | Type | Required | Description |
99
| :--- | :--- | :--- | :--- |
10-
| **name** | `string` || Configuration name (snake_case) |
10+
| **name** | `string` || Configuration name (snake_case, max 64 chars) |
1111
| **label** | `string` || Display label |
1212
| **enabled** | `boolean` | optional | Enable audit logging |
1313
| **eventTypes** | `Enum<'data.create' \| 'data.read' \| 'data.update' \| 'data.delete' \| 'data.export' \| 'data.import' \| 'data.bulk_update' \| 'data.bulk_delete' \| 'auth.login' \| 'auth.login_failed' \| 'auth.logout' \| 'auth.session_created' \| 'auth.session_expired' \| 'auth.password_reset' \| 'auth.password_changed' \| 'auth.email_verified' \| 'auth.mfa_enabled' \| 'auth.mfa_disabled' \| 'auth.account_locked' \| 'auth.account_unlocked' \| 'authz.permission_granted' \| 'authz.permission_revoked' \| 'authz.role_assigned' \| 'authz.role_removed' \| 'authz.role_created' \| 'authz.role_updated' \| 'authz.role_deleted' \| 'authz.policy_created' \| 'authz.policy_updated' \| 'authz.policy_deleted' \| 'system.config_changed' \| 'system.plugin_installed' \| 'system.plugin_uninstalled' \| 'system.backup_created' \| 'system.backup_restored' \| 'system.integration_added' \| 'system.integration_removed' \| 'security.access_denied' \| 'security.suspicious_activity' \| 'security.data_breach' \| 'security.api_key_created' \| 'security.api_key_revoked'>[]` | optional | Event types to audit |
@@ -21,5 +21,5 @@ description: AuditConfig Schema Reference
2121
| **logReads** | `boolean` | optional | Log read operations |
2222
| **readSamplingRate** | `number` | optional | Read sampling rate |
2323
| **logSystemEvents** | `boolean` | optional | Log system events |
24-
| **customHandlers** | `object[]` | optional | Custom event handlers |
24+
| **customHandlers** | `object[]` | optional | Custom event handler references |
2525
| **compliance** | `object` | optional | Compliance configuration |

packages/spec/json-schema/AuditConfig.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"name": {
88
"type": "string",
99
"pattern": "^[a-z_][a-z0-9_]*$",
10-
"description": "Configuration name (snake_case)"
10+
"maxLength": 64,
11+
"description": "Configuration name (snake_case, max 64 chars)"
1112
},
1213
"label": {
1314
"type": "string",
@@ -195,7 +196,7 @@
195196
"properties": {
196197
"retentionDays": {
197198
"type": "integer",
198-
"exclusiveMinimum": 0,
199+
"minimum": 1,
199200
"default": 180,
200201
"description": "Retention period in days"
201202
},
@@ -523,14 +524,19 @@
523524
"security.api_key_revoked"
524525
],
525526
"description": "Event type to handle"
527+
},
528+
"handlerId": {
529+
"type": "string",
530+
"description": "Unique identifier for the handler"
526531
}
527532
},
528533
"required": [
529-
"eventType"
534+
"eventType",
535+
"handlerId"
530536
],
531537
"additionalProperties": false
532538
},
533-
"description": "Custom event handlers"
539+
"description": "Custom event handler references"
534540
},
535541
"compliance": {
536542
"type": "object",

packages/spec/json-schema/AuditRetentionPolicy.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"properties": {
77
"retentionDays": {
88
"type": "integer",
9-
"exclusiveMinimum": 0,
9+
"minimum": 1,
1010
"default": 180,
1111
"description": "Retention period in days"
1212
},

packages/spec/src/system/audit.zod.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ export const AuditRetentionPolicySchema = z.object({
271271
* Retention period in days
272272
* Default: 180 days (GDPR 6-month requirement)
273273
*/
274-
retentionDays: z.number().int().positive().default(180).describe('Retention period in days'),
274+
retentionDays: z.number().int().min(1).default(180).describe('Retention period in days'),
275275

276276
/**
277277
* Whether to archive logs after retention period
@@ -510,10 +510,13 @@ export type AuditEventFilter = z.infer<typeof AuditEventFilterSchema>;
510510
export const AuditConfigSchema = z.object({
511511
/**
512512
* Unique identifier for this audit configuration
513+
* Must be in snake_case following ObjectStack conventions
514+
* Maximum length: 64 characters
513515
*/
514516
name: z.string()
515517
.regex(/^[a-z_][a-z0-9_]*$/)
516-
.describe('Configuration name (snake_case)'),
518+
.max(64)
519+
.describe('Configuration name (snake_case, max 64 chars)'),
517520

518521
/**
519522
* Human-readable label
@@ -595,14 +598,12 @@ export const AuditConfigSchema = z.object({
595598

596599
/**
597600
* Custom audit event handlers
601+
* Note: Function handlers are for runtime configuration only and will not be serialized to JSON Schema
598602
*/
599603
customHandlers: z.array(z.object({
600604
eventType: AuditEventType.describe('Event type to handle'),
601-
handler: z.function()
602-
.args(AuditEventSchema)
603-
.returns(z.promise(z.void()))
604-
.describe('Handler function'),
605-
})).optional().describe('Custom event handlers'),
605+
handlerId: z.string().describe('Unique identifier for the handler'),
606+
})).optional().describe('Custom event handler references'),
606607

607608
/**
608609
* Compliance mode configuration

packages/spec/src/system/tenant.zod.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,11 @@ export type Tenant = z.infer<typeof TenantSchema>;
125125
*
126126
* EXAMPLE RLS POLICY (PostgreSQL):
127127
* ```sql
128-
* CREATE POLICY tenant_isolation ON customers
128+
* -- Example: Apply RLS policy to a table (e.g., "app_data")
129+
* CREATE POLICY tenant_isolation ON app_data
129130
* USING (tenant_id = current_setting('app.current_tenant')::text);
130131
*
131-
* ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
132+
* ALTER TABLE app_data ENABLE ROW LEVEL SECURITY;
132133
* ```
133134
*/
134135
export const RowLevelIsolationStrategySchema = z.object({
@@ -240,7 +241,8 @@ export const SchemaLevelIsolationStrategySchema = z.object({
240241
schema: z.object({
241242
/**
242243
* Schema naming pattern
243-
* Use {tenant_id} as placeholder
244+
* Use {tenant_id} as placeholder (must contain only alphanumeric and underscores)
245+
* The tenant_id will be sanitized before substitution to prevent SQL injection
244246
*/
245247
namingPattern: z.string().default('tenant_{tenant_id}').describe('Schema naming pattern'),
246248

@@ -359,7 +361,8 @@ export const DatabaseLevelIsolationStrategySchema = z.object({
359361
database: z.object({
360362
/**
361363
* Database naming pattern
362-
* Use {tenant_id} as placeholder
364+
* Use {tenant_id} as placeholder (must contain only alphanumeric and underscores)
365+
* The tenant_id will be sanitized before substitution to prevent SQL injection
363366
*/
364367
namingPattern: z.string().default('tenant_{tenant_id}').describe('Database naming pattern'),
365368

0 commit comments

Comments
 (0)