From 21860688db3896230430bdbce85465216d0d96c9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 31 Jan 2026 10:15:03 +0000
Subject: [PATCH 1/4] Initial plan
From 6c0dabbfc73acb6e5aa76878ef9f282398b07690 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 31 Jan 2026 10:18:40 +0000
Subject: [PATCH 2/4] Initial plan for creating a patch release
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
---
.../docs/references/automation/connector.mdx | 6 +-
content/docs/references/data/driver-mongo.mdx | 147 -----
.../docs/references/data/driver-postgres.mdx | 133 -----
content/docs/references/data/meta.json | 2 -
.../integration/connector-file-storage.mdx | 381 ------------
content/docs/references/integration/meta.json | 3 +-
content/docs/references/system/events.mdx | 187 +++++-
content/docs/references/system/index.mdx | 1 +
content/docs/references/system/meta.json | 3 +-
.../references/system/metadata-loader.mdx | 384 ++++--------
.../system/plugin-lifecycle-events.mdx | 316 ++++------
.../references/system/plugin-validator.mdx | 281 +--------
.../references/system/service-registry.mdx | 431 ++------------
.../system/startup-orchestrator.mdx | 280 +--------
.../json-schema/system/BatchProgress.json | 72 +++
.../spec/json-schema/system/BatchTask.json | 63 ++
.../system/DeadLetterQueueEntry.json | 137 +++++
packages/spec/json-schema/system/Event.json | 24 +
.../json-schema/system/EventBusConfig.json | 552 ++++++++++++++++++
.../spec/json-schema/system/EventHandler.json | 34 ++
.../json-schema/system/EventLogEntry.json | 153 +++++
.../system/EventMessageQueueConfig.json | 79 +++
.../json-schema/system/EventMetadata.json | 20 +
.../json-schema/system/EventPersistence.json | 11 +
.../json-schema/system/EventPriority.json | 16 +
.../json-schema/system/EventQueueConfig.json | 67 +++
.../json-schema/system/EventReplayConfig.json | 50 ++
.../system/EventSourcingConfig.json | 65 +++
.../system/EventTypeDefinition.json | 45 ++
.../system/EventWebhookConfig.json | 119 ++++
.../spec/json-schema/system/QueueConfig.json | 133 +++++
.../system/RealTimeNotificationConfig.json | 85 +++
packages/spec/json-schema/system/Task.json | 145 +++++
.../system/TaskExecutionResult.json | 85 +++
.../spec/json-schema/system/TaskPriority.json | 16 +
.../json-schema/system/TaskRetryPolicy.json | 46 ++
.../spec/json-schema/system/TaskStatus.json | 19 +
.../spec/json-schema/system/WorkerConfig.json | 188 ++++++
.../spec/json-schema/system/WorkerStats.json | 90 +++
39 files changed, 2843 insertions(+), 2026 deletions(-)
delete mode 100644 content/docs/references/data/driver-mongo.mdx
delete mode 100644 content/docs/references/data/driver-postgres.mdx
delete mode 100644 content/docs/references/integration/connector-file-storage.mdx
create mode 100644 packages/spec/json-schema/system/BatchProgress.json
create mode 100644 packages/spec/json-schema/system/BatchTask.json
create mode 100644 packages/spec/json-schema/system/DeadLetterQueueEntry.json
create mode 100644 packages/spec/json-schema/system/EventBusConfig.json
create mode 100644 packages/spec/json-schema/system/EventLogEntry.json
create mode 100644 packages/spec/json-schema/system/EventMessageQueueConfig.json
create mode 100644 packages/spec/json-schema/system/EventPriority.json
create mode 100644 packages/spec/json-schema/system/EventQueueConfig.json
create mode 100644 packages/spec/json-schema/system/EventReplayConfig.json
create mode 100644 packages/spec/json-schema/system/EventSourcingConfig.json
create mode 100644 packages/spec/json-schema/system/EventTypeDefinition.json
create mode 100644 packages/spec/json-schema/system/EventWebhookConfig.json
create mode 100644 packages/spec/json-schema/system/QueueConfig.json
create mode 100644 packages/spec/json-schema/system/RealTimeNotificationConfig.json
create mode 100644 packages/spec/json-schema/system/Task.json
create mode 100644 packages/spec/json-schema/system/TaskExecutionResult.json
create mode 100644 packages/spec/json-schema/system/TaskPriority.json
create mode 100644 packages/spec/json-schema/system/TaskRetryPolicy.json
create mode 100644 packages/spec/json-schema/system/TaskStatus.json
create mode 100644 packages/spec/json-schema/system/WorkerConfig.json
create mode 100644 packages/spec/json-schema/system/WorkerStats.json
diff --git a/content/docs/references/automation/connector.mdx b/content/docs/references/automation/connector.mdx
index 0bfe1b0ef..ad2b8c0ce 100644
--- a/content/docs/references/automation/connector.mdx
+++ b/content/docs/references/automation/connector.mdx
@@ -6,14 +6,14 @@ description: Connector protocol schemas
# Connector
-**Source:** `packages/spec/src/integration/connector.zod.ts`
+**Source:** `packages/spec/src/automation/connector.zod.ts`
## TypeScript Usage
```typescript
-import { AuthenticationSchema, ConflictResolutionSchema, ConnectorSchema, DataSyncConfigSchema } from '@objectstack/spec/integration';
-import type { Authentication, ConflictResolution, Connector, DataSyncConfig } from '@objectstack/spec/integration';
+import { AuthenticationSchema, ConflictResolutionSchema, ConnectorSchema, DataSyncConfigSchema } from '@objectstack/spec/automation';
+import type { Authentication, ConflictResolution, Connector, DataSyncConfig } from '@objectstack/spec/automation';
// Validate data
const result = AuthenticationSchema.parse(data);
diff --git a/content/docs/references/data/driver-mongo.mdx b/content/docs/references/data/driver-mongo.mdx
deleted file mode 100644
index 811afe48c..000000000
--- a/content/docs/references/data/driver-mongo.mdx
+++ /dev/null
@@ -1,147 +0,0 @@
----
-title: MongoDB Driver
-description: MongoDB driver configuration schema
----
-
-# MongoDB Driver
-
-
-**Source:** `packages/spec/src/data/driver/mongo.zod.ts`
-
-
-## Overview
-
-MongoDB driver configuration schema defines connection settings and capabilities specific to MongoDB databases.
-
-## TypeScript Usage
-
-```typescript
-import { MongoConfigSchema, MongoDriverSpec } from '@objectstack/spec/data/driver/mongo';
-import type { MongoConfig } from '@objectstack/spec/data/driver/mongo';
-
-// Validate MongoDB configuration
-const config: MongoConfig = MongoConfigSchema.parse({
- database: 'myapp',
- host: '127.0.0.1',
- port: 27017,
- username: 'admin',
- password: 'secret',
-});
-```
-
----
-
-## MongoConfig
-
-MongoDB connection configuration schema.
-
-### Properties
-
-| Property | Type | Required | Description |
-| :--- | :--- | :--- | :--- |
-| **url** | `string` | optional | Connection URI. Format: mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]] |
-| **database** | `string` | ✅ | Database name (required) |
-| **host** | `string` | optional | Hostname (default: '127.0.0.1') |
-| **port** | `number` | optional | Port number (default: 27017) |
-| **username** | `string` | optional | Username for authentication |
-| **password** | `string` | optional | Password for authentication |
-| **authSource** | `string` | optional | Authentication database (defaults to admin or database name) |
-| **options** | `Record` | optional | Extra driver options (ssl, poolSize, etc) |
-
----
-
-## MongoDriverSpec
-
-The static definition of MongoDB driver capabilities.
-
-### Capabilities
-
-| Capability | Supported | Description |
-| :--- | :--- | :--- |
-| **transactions** | ✅ | ACID transactions |
-| **fullTextSearch** | ✅ | Full-text search indexes |
-| **geoSpatial** | ✅ | Geospatial queries |
-| **aggregation** | ✅ | Aggregation pipeline |
-| **mutableSchema** | ✅ | Dynamic schema changes |
-| **jsonField** | ✅ | Native JSON/BSON storage |
-| **crossObjectJoin** | ✅ | $lookup aggregation |
-
----
-
-## Examples
-
-### Basic Configuration
-
-```typescript
-const config: MongoConfig = {
- database: 'crm',
- host: '127.0.0.1',
- port: 27017,
- username: 'app_user',
- password: 'secure_password',
-};
-```
-
-### Connection URI
-
-```typescript
-const config: MongoConfig = {
- url: 'mongodb://user:password@localhost:27017/mydb',
- database: 'mydb', // Still required
-};
-```
-
-### Replica Set Configuration
-
-```typescript
-const config: MongoConfig = {
- url: 'mongodb://node1:27017,node2:27017,node3:27017/mydb?replicaSet=rs0',
- database: 'mydb',
- options: {
- replicaSet: 'rs0',
- readPreference: 'secondaryPreferred',
- },
-};
-```
-
-### SSL Configuration
-
-```typescript
-const config: MongoConfig = {
- database: 'production',
- host: 'mongodb.example.com',
- port: 27017,
- username: 'app_user',
- password: 'secure_password',
- authSource: 'admin',
- options: {
- ssl: true,
- sslValidate: true,
- sslCA: '/path/to/ca.pem',
- },
-};
-```
-
-### Connection Pool Options
-
-```typescript
-const config: MongoConfig = {
- database: 'myapp',
- host: 'localhost',
- port: 27017,
- options: {
- poolSize: 20,
- socketTimeoutMS: 30000,
- connectTimeoutMS: 10000,
- serverSelectionTimeoutMS: 5000,
- },
-};
-```
-
----
-
-## Related
-
-- [Driver](/docs/references/data/driver) - Base driver protocol
-- [Driver NoSQL](/docs/references/data/driver-nosql) - NoSQL driver interface
-- [Datasource](/docs/references/system/datasource) - Datasource configuration
diff --git a/content/docs/references/data/driver-postgres.mdx b/content/docs/references/data/driver-postgres.mdx
deleted file mode 100644
index a35c21af2..000000000
--- a/content/docs/references/data/driver-postgres.mdx
+++ /dev/null
@@ -1,133 +0,0 @@
----
-title: PostgreSQL Driver
-description: PostgreSQL driver configuration schema
----
-
-# PostgreSQL Driver
-
-
-**Source:** `packages/spec/src/data/driver/postgres.zod.ts`
-
-
-## Overview
-
-PostgreSQL driver configuration schema defines connection settings and options specific to PostgreSQL databases.
-
-## TypeScript Usage
-
-```typescript
-import { PostgresConfigSchema } from '@objectstack/spec/data/driver/postgres';
-import type { PostgresConfig } from '@objectstack/spec/data/driver/postgres';
-
-// Validate PostgreSQL configuration
-const config: PostgresConfig = PostgresConfigSchema.parse({
- database: 'myapp',
- host: 'localhost',
- port: 5432,
- username: 'postgres',
- password: 'secret',
- ssl: false,
-});
-```
-
----
-
-## PostgresConfig
-
-PostgreSQL connection configuration schema.
-
-### Properties
-
-| Property | Type | Required | Description |
-| :--- | :--- | :--- | :--- |
-| **url** | `string` | optional | Connection URI. Format: postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...] |
-| **database** | `string` | ✅ | Database name |
-| **host** | `string` | optional | Hostname or IP address (default: 'localhost') |
-| **port** | `number` | optional | Port number (default: 5432) |
-| **username** | `string` | optional | Authentication username |
-| **password** | `string` | optional | Authentication password |
-| **schema** | `string` | optional | Default schema for tables (default: 'public') |
-| **ssl** | `boolean \| object` | optional | Enable SSL/TLS connection |
-| **applicationName** | `string` | optional | Sets the application_name configuration parameter |
-| **max** | `number` | optional | Maximum number of clients in pool (default: 10) |
-| **min** | `number` | optional | Minimum number of clients in pool (default: 0) |
-| **idleTimeoutMillis** | `number` | optional | Idle timeout in milliseconds |
-| **connectionTimeoutMillis** | `number` | optional | Connection timeout in milliseconds |
-| **statementTimeout** | `number` | optional | Statement timeout in milliseconds |
-
-### SSL Configuration
-
-When `ssl` is an object, it can contain:
-
-| Property | Type | Description |
-| :--- | :--- | :--- |
-| **rejectUnauthorized** | `boolean` | Whether to reject unauthorized certificates |
-| **ca** | `string` | CA certificate |
-| **key** | `string` | Client key |
-| **cert** | `string` | Client certificate |
-
----
-
-## Examples
-
-### Basic Configuration
-
-```typescript
-const config: PostgresConfig = {
- database: 'crm',
- host: 'localhost',
- port: 5432,
- username: 'app_user',
- password: 'secure_password',
-};
-```
-
-### Connection URI
-
-```typescript
-const config: PostgresConfig = {
- url: 'postgresql://user:password@localhost:5432/mydb',
- database: 'mydb', // Required even with URL
-};
-```
-
-### SSL Configuration
-
-```typescript
-const config: PostgresConfig = {
- database: 'production',
- host: 'db.example.com',
- port: 5432,
- username: 'app_user',
- password: 'secure_password',
- ssl: {
- rejectUnauthorized: true,
- ca: '-----BEGIN CERTIFICATE-----\n...',
- },
-};
-```
-
-### Connection Pool Configuration
-
-```typescript
-const config: PostgresConfig = {
- database: 'myapp',
- host: 'localhost',
- port: 5432,
- username: 'postgres',
- password: 'secret',
- max: 20, // Max 20 connections
- min: 5, // Keep at least 5 connections
- idleTimeoutMillis: 30000, // Close idle connections after 30s
- connectionTimeoutMillis: 2000, // Timeout connection attempts after 2s
- statementTimeout: 5000, // Abort slow queries after 5s
-};
-```
-
----
-
-## Related
-
-- [Driver](/docs/references/data/driver) - Base driver protocol
-- [Driver SQL](/docs/references/data/driver-sql) - SQL driver interface
-- [Datasource](/docs/references/system/datasource) - Datasource configuration
diff --git a/content/docs/references/data/meta.json b/content/docs/references/data/meta.json
index 154d3d2c8..3e5f65882 100644
--- a/content/docs/references/data/meta.json
+++ b/content/docs/references/data/meta.json
@@ -5,9 +5,7 @@
"dataset",
"document",
"driver",
- "driver-mongo",
"driver-nosql",
- "driver-postgres",
"driver-sql",
"external-lookup",
"field",
diff --git a/content/docs/references/integration/connector-file-storage.mdx b/content/docs/references/integration/connector-file-storage.mdx
deleted file mode 100644
index 8f3201047..000000000
--- a/content/docs/references/integration/connector-file-storage.mdx
+++ /dev/null
@@ -1,381 +0,0 @@
----
-title: File Storage Connector
-description: File storage system connector protocol
----
-
-# File Storage Connector
-
-
-**Source:** `packages/spec/src/integration/connector/file-storage.zod.ts`
-
-
-## Overview
-
-File Storage Connector protocol defines a specialized connector for file storage systems (S3, Azure Blob, Google Cloud Storage, etc.). It extends the base connector with file-specific features like multipart uploads, versioning, and metadata extraction.
-
-## TypeScript Usage
-
-```typescript
-import {
- FileStorageConnectorSchema,
- FileStorageProviderSchema,
- StorageBucketSchema,
- FileMetadataConfigSchema,
- MultipartUploadConfigSchema
-} from '@objectstack/spec/integration/connector/file-storage';
-
-import type {
- FileStorageConnector,
- FileStorageProvider,
- StorageBucket,
- FileMetadataConfig
-} from '@objectstack/spec/integration/connector/file-storage';
-```
-
----
-
-## Schemas
-
-### FileStorageProvider
-
-Supported file storage providers.
-
-**Values:**
-- `s3` - Amazon S3
-- `azure_blob` - Azure Blob Storage
-- `gcs` - Google Cloud Storage
-- `dropbox` - Dropbox
-- `box` - Box
-- `onedrive` - Microsoft OneDrive
-- `google_drive` - Google Drive
-- `sharepoint` - SharePoint
-- `ftp` - FTP/SFTP
-- `local` - Local file system
-- `custom` - Custom file storage
-
----
-
-### FileAccessPattern
-
-File access control patterns.
-
-**Values:**
-- `public_read` - Public read access
-- `private` - Private access
-- `authenticated_read` - Requires authentication
-- `bucket_owner_read` - Bucket owner has read access
-- `bucket_owner_full` - Bucket owner has full control
-
----
-
-### StorageBucket
-
-Bucket/container configuration for file storage.
-
-#### Properties
-
-| Property | Type | Required | Description |
-| :--- | :--- | :--- | :--- |
-| **name** | `string` | ✅ | Bucket identifier in ObjectStack (snake_case) |
-| **label** | `string` | ✅ | Display label |
-| **bucketName** | `string` | ✅ | Actual bucket/container name in storage system |
-| **region** | `string` | optional | Storage region |
-| **enabled** | `boolean` | optional | Enable sync for this bucket (default: true) |
-| **prefix** | `string` | optional | Prefix/path within bucket |
-| **accessPattern** | `FileAccessPattern` | optional | Access pattern |
-| **fileFilters** | `FileFilterConfig` | optional | File filter configuration |
-
----
-
-### FileMetadataConfig
-
-File metadata extraction configuration.
-
-#### Properties
-
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **extractMetadata** | `boolean` | optional | true | Extract file metadata |
-| **metadataFields** | `string[]` | optional | - | Metadata fields to extract |
-| **customMetadata** | `Record` | optional | - | Custom metadata key-value pairs |
-
-**Metadata Fields:**
-- `content_type` - MIME type
-- `file_size` - File size in bytes
-- `last_modified` - Last modification date
-- `etag` - Entity tag
-- `checksum` - File checksum
-- `creator` - File creator
-- `created_at` - Creation date
-- `custom` - Custom metadata
-
----
-
-### MultipartUploadConfig
-
-Multipart upload configuration for large files.
-
-#### Properties
-
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **enabled** | `boolean` | optional | true | Enable multipart uploads |
-| **partSize** | `number` | optional | 5MB | Part size in bytes (min 5MB) |
-| **maxConcurrentParts** | `number` | optional | 5 | Maximum concurrent part uploads |
-| **threshold** | `number` | optional | 100MB | File size threshold for multipart upload |
-
----
-
-### FileVersioningConfig
-
-File versioning configuration.
-
-#### Properties
-
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **enabled** | `boolean` | optional | false | Enable file versioning |
-| **maxVersions** | `number` | optional | - | Maximum versions to retain (1-100) |
-| **retentionDays** | `number` | optional | - | Version retention period in days |
-
----
-
-## FileStorageConnector
-
-Complete file storage connector configuration.
-
-### Additional Properties
-
-| Property | Type | Required | Description |
-| :--- | :--- | :--- | :--- |
-| **type** | `'file_storage'` | ✅ | Connector type |
-| **provider** | `FileStorageProvider` | ✅ | File storage provider |
-| **buckets** | `StorageBucket[]` | ✅ | Buckets/containers to sync |
-| **storageConfig** | `object` | optional | Storage configuration |
-| **metadataConfig** | `FileMetadataConfig` | optional | Metadata extraction |
-| **multipartConfig** | `MultipartUploadConfig` | optional | Multipart upload |
-| **versioningConfig** | `FileVersioningConfig` | optional | File versioning |
-| **encryption** | `object` | optional | Server-side encryption |
-| **lifecyclePolicy** | `object` | optional | File lifecycle policy |
-| **contentProcessing** | `object` | optional | Content processing |
-
----
-
-## Examples
-
-### Amazon S3 Connector
-
-```typescript
-const s3Connector: FileStorageConnector = {
- name: 's3_documents',
- label: 'S3 Document Storage',
- type: 'file_storage',
- provider: 's3',
- enabled: true,
-
- storageConfig: {
- region: 'us-east-1',
- },
-
- buckets: [
- {
- name: 'customer_documents',
- label: 'Customer Documents',
- bucketName: 'myapp-customer-docs',
- region: 'us-east-1',
- enabled: true,
- prefix: 'documents/',
- accessPattern: 'private',
- }
- ],
-
- metadataConfig: {
- extractMetadata: true,
- metadataFields: ['content_type', 'file_size', 'last_modified'],
- },
-
- multipartConfig: {
- enabled: true,
- partSize: 10 * 1024 * 1024, // 10MB
- maxConcurrentParts: 5,
- threshold: 100 * 1024 * 1024, // 100MB
- },
-
- encryption: {
- enabled: true,
- algorithm: 'aws:kms',
- kmsKeyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012',
- },
-};
-```
-
-### Azure Blob Storage
-
-```typescript
-const azureConnector: FileStorageConnector = {
- name: 'azure_files',
- label: 'Azure File Storage',
- type: 'file_storage',
- provider: 'azure_blob',
- enabled: true,
-
- buckets: [
- {
- name: 'attachments',
- label: 'Email Attachments',
- bucketName: 'email-attachments',
- enabled: true,
- accessPattern: 'private',
- }
- ],
-
- versioningConfig: {
- enabled: true,
- maxVersions: 10,
- retentionDays: 90,
- },
-};
-```
-
-### Google Cloud Storage
-
-```typescript
-const gcsConnector: FileStorageConnector = {
- name: 'gcs_media',
- label: 'GCS Media Storage',
- type: 'file_storage',
- provider: 'gcs',
- enabled: true,
-
- buckets: [
- {
- name: 'user_uploads',
- label: 'User Uploads',
- bucketName: 'myapp-user-uploads',
- enabled: true,
- accessPattern: 'authenticated_read',
- fileFilters: {
- allowedExtensions: ['.jpg', '.png', '.pdf'],
- maxFileSize: 50 * 1024 * 1024, // 50MB
- },
- }
- ],
-
- contentProcessing: {
- generateThumbnails: true,
- thumbnailSizes: [
- { width: 150, height: 150 },
- { width: 300, height: 300 },
- ],
- virusScan: true,
- },
-};
-```
-
-### With File Filters
-
-```typescript
-const filteredConnector: FileStorageConnector = {
- name: 'filtered_storage',
- label: 'Filtered Storage',
- type: 'file_storage',
- provider: 's3',
- enabled: true,
-
- buckets: [
- {
- name: 'documents',
- label: 'Documents',
- bucketName: 'my-docs',
- enabled: true,
- fileFilters: {
- includePatterns: ['*.pdf', '*.docx', '*.xlsx'],
- excludePatterns: ['temp/*', '*/draft/*'],
- minFileSize: 1024, // 1KB
- maxFileSize: 100 * 1024 * 1024, // 100MB
- allowedExtensions: ['.pdf', '.docx', '.xlsx'],
- blockedExtensions: ['.exe', '.bat', '.sh'],
- },
- }
- ],
-};
-```
-
-### With Lifecycle Policy
-
-```typescript
-const lifecycleConnector: FileStorageConnector = {
- name: 'archive_storage',
- label: 'Archive Storage',
- type: 'file_storage',
- provider: 's3',
- enabled: true,
-
- buckets: [
- {
- name: 'logs',
- label: 'Application Logs',
- bucketName: 'app-logs',
- enabled: true,
- }
- ],
-
- lifecyclePolicy: {
- enabled: true,
- archiveAfterDays: 30,
- deleteAfterDays: 365,
- },
-};
-```
-
----
-
-## Best Practices
-
-### 1. Enable Multipart for Large Files
-
-```typescript
-multipartConfig: {
- enabled: true,
- partSize: 10 * 1024 * 1024, // 10MB parts
- threshold: 50 * 1024 * 1024, // Use multipart for files > 50MB
-}
-```
-
-### 2. Use File Filters
-
-```typescript
-fileFilters: {
- allowedExtensions: ['.pdf', '.jpg', '.png'],
- maxFileSize: 100 * 1024 * 1024, // 100MB limit
- excludePatterns: ['temp/*', '*/cache/*'],
-}
-```
-
-### 3. Enable Encryption
-
-```typescript
-encryption: {
- enabled: true,
- algorithm: 'aws:kms', // Use KMS for better security
- kmsKeyId: 'your-kms-key-id',
-}
-```
-
-### 4. Configure Versioning Carefully
-
-```typescript
-versioningConfig: {
- enabled: true,
- maxVersions: 5, // Keep only recent versions
- retentionDays: 30, // Auto-delete old versions
-}
-```
-
----
-
-## Related
-
-- [Connector](/docs/references/integration/connector) - Base connector protocol
-- [Object Storage](/docs/references/integration/object-storage) - Object storage integration
-- [Datasource](/docs/references/system/datasource) - Datasource configuration
diff --git a/content/docs/references/integration/meta.json b/content/docs/references/integration/meta.json
index 90f5b0b97..c07e1f0e2 100644
--- a/content/docs/references/integration/meta.json
+++ b/content/docs/references/integration/meta.json
@@ -1,7 +1,6 @@
{
"title": "Integration Protocol",
"pages": [
- "connector",
- "connector-file-storage"
+ "connector"
]
}
\ No newline at end of file
diff --git a/content/docs/references/system/events.mdx b/content/docs/references/system/events.mdx
index a977a90a7..daf3ee98c 100644
--- a/content/docs/references/system/events.mdx
+++ b/content/docs/references/system/events.mdx
@@ -12,36 +12,108 @@ description: Events protocol schemas
## TypeScript Usage
```typescript
-import { EventSchema, EventHandlerSchema, EventMetadataSchema, EventPersistenceSchema, EventRouteSchema } from '@objectstack/spec/system';
-import type { Event, EventHandler, EventMetadata, EventPersistence, EventRoute } from '@objectstack/spec/system';
+import { DeadLetterQueueEntrySchema, EventSchema, EventBusConfigSchema, EventHandlerSchema, EventLogEntrySchema, EventMessageQueueConfigSchema, EventMetadataSchema, EventPersistenceSchema, EventPrioritySchema, EventQueueConfigSchema, EventReplayConfigSchema, EventRouteSchema, EventSourcingConfigSchema, EventTypeDefinitionSchema, EventWebhookConfigSchema, RealTimeNotificationConfigSchema } from '@objectstack/spec/system';
+import type { DeadLetterQueueEntry, Event, EventBusConfig, EventHandler, EventLogEntry, EventMessageQueueConfig, EventMetadata, EventPersistence, EventPriority, EventQueueConfig, EventReplayConfig, EventRoute, EventSourcingConfig, EventTypeDefinition, EventWebhookConfig, RealTimeNotificationConfig } from '@objectstack/spec/system';
// Validate data
-const result = EventSchema.parse(data);
+const result = DeadLetterQueueEntrySchema.parse(data);
```
---
+## DeadLetterQueueEntry
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **id** | `string` | ✅ | Unique entry identifier |
+| **event** | `object` | ✅ | Original event |
+| **error** | `object` | ✅ | Failure details |
+| **retries** | `integer` | ✅ | Number of retry attempts |
+| **firstFailedAt** | `string` | ✅ | When event first failed |
+| **lastFailedAt** | `string` | ✅ | When event last failed |
+| **failedHandler** | `string` | optional | Handler ID that failed |
+
+---
+
## Event
### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
+| **id** | `string` | optional | Unique event identifier |
| **name** | `string` | ✅ | Event name (lowercase with dots, e.g., user.created, order.paid) |
| **payload** | `any` | optional | Event payload schema |
| **metadata** | `object` | ✅ | Event metadata |
---
+## EventBusConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **persistence** | `object` | optional | Event persistence configuration |
+| **queue** | `object` | optional | Event queue configuration |
+| **eventSourcing** | `object` | optional | Event sourcing configuration |
+| **replay** | `object` | optional | Event replay configuration |
+| **webhooks** | `object[]` | optional | Webhook configurations |
+| **messageQueue** | `object` | optional | Message queue integration |
+| **realtime** | `object` | optional | Real-time notification configuration |
+| **eventTypes** | `object[]` | optional | Event type definitions |
+| **handlers** | `object[]` | optional | Global event handlers |
+
+---
+
## EventHandler
### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
+| **id** | `string` | optional | Unique handler identifier |
| **eventName** | `string` | ✅ | Name of event to handle (supports wildcards like user.*) |
| **priority** | `integer` | optional | Execution priority (lower numbers execute first) |
| **async** | `boolean` | optional | Execute in background (true) or block (false) |
+| **retry** | `object` | optional | Retry policy for failed handlers |
+| **timeoutMs** | `integer` | optional | Handler timeout in milliseconds |
+
+---
+
+## EventLogEntry
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **id** | `string` | ✅ | Unique log entry identifier |
+| **event** | `object` | ✅ | The event |
+| **status** | `Enum<'pending' \| 'processing' \| 'completed' \| 'failed'>` | ✅ | Processing status |
+| **handlersExecuted** | `object[]` | optional | Handlers that processed this event |
+| **receivedAt** | `string` | ✅ | When event was received |
+| **processedAt** | `string` | optional | When event was processed |
+| **totalDurationMs** | `integer` | optional | Total processing time |
+
+---
+
+## EventMessageQueueConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **provider** | `Enum<'kafka' \| 'rabbitmq' \| 'aws-sqs' \| 'redis-pubsub' \| 'google-pubsub' \| 'azure-service-bus'>` | ✅ | Message queue provider |
+| **topic** | `string` | ✅ | Topic or queue name |
+| **eventPattern** | `string` | optional | Event name pattern to publish (supports wildcards) |
+| **partitionKey** | `string` | optional | JSON path for partition key (e.g., "metadata.tenantId") |
+| **format** | `Enum<'json' \| 'avro' \| 'protobuf'>` | optional | Message serialization format |
+| **includeMetadata** | `boolean` | optional | Include event metadata in message |
+| **compression** | `Enum<'none' \| 'gzip' \| 'snappy' \| 'lz4'>` | optional | Message compression |
+| **batchSize** | `integer` | optional | Batch size for publishing |
+| **flushIntervalMs** | `integer` | optional | Flush interval for batching |
---
@@ -55,6 +127,9 @@ const result = EventSchema.parse(data);
| **timestamp** | `string` | ✅ | ISO 8601 datetime when event was created |
| **userId** | `string` | optional | User who triggered the event |
| **tenantId** | `string` | optional | Tenant identifier for multi-tenant systems |
+| **correlationId** | `string` | optional | Correlation ID for event tracing |
+| **causationId** | `string` | optional | ID of the event that caused this event |
+| **priority** | `Enum<'critical' \| 'high' \| 'normal' \| 'low' \| 'background'>` | optional | Event priority |
---
@@ -66,6 +141,48 @@ const result = EventSchema.parse(data);
| :--- | :--- | :--- | :--- |
| **enabled** | `boolean` | optional | Enable event persistence |
| **retention** | `integer` | ✅ | Days to retain persisted events |
+| **storage** | `Enum<'database' \| 'file' \| 's3' \| 'custom'>` | optional | Storage backend for persisted events |
+
+---
+
+## EventPriority
+
+### Allowed Values
+
+* `critical`
+* `high`
+* `normal`
+* `low`
+* `background`
+
+---
+
+## EventQueueConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **name** | `string` | optional | Event queue name |
+| **concurrency** | `integer` | optional | Max concurrent event handlers |
+| **retryPolicy** | `object` | optional | Default retry policy for events |
+| **deadLetterQueue** | `string` | optional | Dead letter queue name for failed events |
+| **priorityEnabled** | `boolean` | optional | Process events based on priority |
+
+---
+
+## EventReplayConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **fromTimestamp** | `string` | ✅ | Start timestamp for replay (ISO 8601) |
+| **toTimestamp** | `string` | optional | End timestamp for replay (ISO 8601) |
+| **eventTypes** | `string[]` | optional | Event types to replay (empty = all) |
+| **filters** | `Record` | optional | Additional filters for event selection |
+| **speed** | `number` | optional | Replay speed multiplier (1 = real-time) |
+| **targetHandlers** | `string[]` | optional | Handler IDs to execute (empty = all) |
---
@@ -78,3 +195,67 @@ const result = EventSchema.parse(data);
| **from** | `string` | ✅ | Source event pattern (supports wildcards, e.g., user.* or *.created) |
| **to** | `string[]` | ✅ | Target event names to route to |
+---
+
+## EventSourcingConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **enabled** | `boolean` | optional | Enable event sourcing |
+| **snapshotInterval** | `integer` | optional | Create snapshot every N events |
+| **snapshotRetention** | `integer` | optional | Number of snapshots to retain |
+| **retention** | `integer` | optional | Days to retain events |
+| **aggregateTypes** | `string[]` | optional | Aggregate types to enable event sourcing for |
+| **storage** | `object` | optional | Event store configuration |
+
+---
+
+## EventTypeDefinition
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **name** | `string` | ✅ | Event type name (lowercase with dots) |
+| **version** | `string` | optional | Event schema version |
+| **schema** | `any` | optional | JSON Schema for event payload validation |
+| **description** | `string` | optional | Event type description |
+| **deprecated** | `boolean` | optional | Whether this event type is deprecated |
+| **tags** | `string[]` | optional | Event type tags |
+
+---
+
+## EventWebhookConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **id** | `string` | optional | Unique webhook identifier |
+| **eventPattern** | `string` | ✅ | Event name pattern (supports wildcards) |
+| **url** | `string` | ✅ | Webhook endpoint URL |
+| **method** | `Enum<'GET' \| 'POST' \| 'PUT' \| 'PATCH'>` | optional | HTTP method |
+| **headers** | `Record` | optional | HTTP headers |
+| **authentication** | `object` | optional | Authentication configuration |
+| **retryPolicy** | `object` | optional | Retry policy |
+| **timeoutMs** | `integer` | optional | Request timeout in milliseconds |
+| **enabled** | `boolean` | optional | Whether webhook is enabled |
+
+---
+
+## RealTimeNotificationConfig
+
+### Properties
+
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **enabled** | `boolean` | optional | Enable real-time notifications |
+| **protocol** | `Enum<'websocket' \| 'sse' \| 'long-polling'>` | optional | Real-time protocol |
+| **eventPattern** | `string` | optional | Event pattern to broadcast |
+| **userFilter** | `boolean` | optional | Filter events by user |
+| **tenantFilter** | `boolean` | optional | Filter events by tenant |
+| **channels** | `object[]` | optional | Named channels for event broadcasting |
+| **rateLimit** | `object` | optional | Rate limiting configuration |
+
diff --git a/content/docs/references/system/index.mdx b/content/docs/references/system/index.mdx
index a82ccf6b1..00a34db37 100644
--- a/content/docs/references/system/index.mdx
+++ b/content/docs/references/system/index.mdx
@@ -37,5 +37,6 @@ This section contains all protocol schemas for the system layer of ObjectStack.
+
diff --git a/content/docs/references/system/meta.json b/content/docs/references/system/meta.json
index e70c88158..c60d8d68c 100644
--- a/content/docs/references/system/meta.json
+++ b/content/docs/references/system/meta.json
@@ -29,6 +29,7 @@
"service-registry",
"startup-orchestrator",
"tracing",
- "translation"
+ "translation",
+ "worker"
]
}
\ No newline at end of file
diff --git a/content/docs/references/system/metadata-loader.mdx b/content/docs/references/system/metadata-loader.mdx
index 44ed1bcfc..bb6a70630 100644
--- a/content/docs/references/system/metadata-loader.mdx
+++ b/content/docs/references/system/metadata-loader.mdx
@@ -1,6 +1,6 @@
---
title: Metadata Loader
-description: Metadata loading and persistence protocol
+description: Metadata Loader protocol schemas
---
# Metadata Loader
@@ -9,319 +9,193 @@ description: Metadata loading and persistence protocol
**Source:** `packages/spec/src/system/metadata-loader.zod.ts`
-## Overview
-
-Metadata Loader protocol defines the standard interface for loading and saving metadata in ObjectStack. It enables consistent metadata operations across different storage backends (filesystem, HTTP, S3, databases) and serialization formats (JSON, YAML, TypeScript).
-
## TypeScript Usage
```typescript
-import {
- MetadataFormatSchema,
- MetadataStatsSchema,
- MetadataLoadOptionsSchema
-} from '@objectstack/spec/system';
-
-import type {
- MetadataFormat,
- MetadataStats,
- MetadataLoadOptions
-} from '@objectstack/spec/system';
-
-// Load metadata with options
-const options: MetadataLoadOptions = {
- patterns: ['**/*.object.ts', '**/*.object.json'],
- validate: true,
- useCache: true,
- recursive: true
-};
-```
-
----
-
-## Schemas
+import { MetadataCollectionInfoSchema, MetadataExportOptionsSchema, MetadataFormatSchema, MetadataImportOptionsSchema, MetadataLoadOptionsSchema, MetadataLoadResultSchema, MetadataLoaderContractSchema, MetadataManagerConfigSchema, MetadataSaveOptionsSchema, MetadataSaveResultSchema, MetadataStatsSchema, MetadataWatchEventSchema } from '@objectstack/spec/system';
+import type { MetadataCollectionInfo, MetadataExportOptions, MetadataFormat, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
-### MetadataFormat
-
-Supported serialization formats for metadata.
-
-**Values:**
-- `json` - JSON format
-- `yaml` - YAML format
-- `typescript` - TypeScript files (.ts)
-- `javascript` - JavaScript files (.js)
-
-#### Example
-
-```typescript
-const format: MetadataFormat = 'json';
+// Validate data
+const result = MetadataCollectionInfoSchema.parse(data);
```
---
-### MetadataStats
-
-Information about a metadata item without loading its full content.
+## MetadataCollectionInfo
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **size** | `number` | ✅ | File size in bytes |
-| **modifiedAt** | `Date` | ✅ | Last modified date |
-| **etag** | `string` | ✅ | Entity tag for cache validation |
-| **format** | `MetadataFormat` | ✅ | Serialization format |
-| **path** | `string` | optional | File system path |
-| **metadata** | `Record` | optional | Provider-specific metadata |
-
-#### Example
-
-```json
-{
- "size": 2048,
- "modifiedAt": "2026-01-31T08:00:00Z",
- "etag": "abc123def456",
- "format": "json",
- "path": "/app/metadata/customer.object.json"
-}
-```
+| **type** | `string` | ✅ | Collection type |
+| **count** | `integer` | ✅ | Number of items |
+| **formats** | `Enum<'json' \| 'yaml' \| 'typescript' \| 'javascript'>[]` | ✅ | Formats in collection |
+| **totalSize** | `integer` | optional | Total size in bytes |
+| **lastModified** | `string` | optional | Last modification date |
+| **location** | `string` | optional | Collection location |
---
-### MetadataLoadOptions
+## MetadataExportOptions
-Options for loading metadata.
+### Properties
-#### Properties
-
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **patterns** | `string[]` | optional | - | File glob patterns to match |
-| **ifNoneMatch** | `string` | optional | - | ETag for conditional request |
-| **ifModifiedSince** | `Date` | optional | - | Only load if modified after this date |
-| **validate** | `boolean` | optional | true | Validate against schema |
-| **useCache** | `boolean` | optional | true | Enable caching |
-| **filter** | `string` | optional | - | Filter predicate as string |
-| **limit** | `number` | optional | - | Maximum items to load |
-| **recursive** | `boolean` | optional | true | Search subdirectories |
-
-#### Example
-
-```typescript
-const options: MetadataLoadOptions = {
- patterns: ['**/*.object.ts', '**/*.object.json'],
- ifModifiedSince: new Date('2026-01-01'),
- validate: true,
- useCache: true,
- recursive: true,
- limit: 100
-};
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **output** | `string` | ✅ | Output file path |
+| **format** | `Enum<'json' \| 'yaml' \| 'typescript' \| 'javascript'>` | optional | Export format |
+| **filter** | `string` | optional | Filter items to export |
+| **includeStats** | `boolean` | optional | Include metadata statistics |
+| **compress** | `boolean` | optional | Compress output (gzip) |
+| **prettify** | `boolean` | optional | Pretty print output |
---
-## Usage Examples
-
-### Load All Objects
-
-```typescript
-import { MetadataLoader } from '@objectstack/core';
-
-const loader = new MetadataLoader();
-
-const objects = await loader.load({
- patterns: ['**/*.object.ts'],
- validate: true,
- recursive: true
-});
+## MetadataFormat
-console.log(`Loaded ${objects.length} objects`);
-```
-
-### Load with Filtering
-
-```typescript
-const objects = await loader.load({
- patterns: ['**/*.object.ts'],
- filter: "(item) => item.name.startsWith('sys_')",
- limit: 50
-});
-```
+### Allowed Values
-### Conditional Loading (Cache Validation)
+* `json`
+* `yaml`
+* `typescript`
+* `javascript`
-```typescript
-const stats = await loader.getStats('/metadata/customer.object.json');
-
-const objects = await loader.load({
- patterns: ['customer.object.json'],
- ifNoneMatch: stats.etag,
- ifModifiedSince: stats.modifiedAt
-});
-
-// Returns empty if not modified
-if (objects.length === 0) {
- console.log('Using cached data');
-}
-```
-
-### Load from Multiple Formats
+---
-```typescript
-const metadata = await loader.load({
- patterns: [
- '**/*.object.ts', // TypeScript
- '**/*.object.json', // JSON
- '**/*.object.yaml' // YAML
- ],
- validate: true
-});
-```
+## MetadataImportOptions
-### Get Metadata Statistics
+### Properties
-```typescript
-const stats = await loader.getStats('/metadata/customer.object.json');
-
-console.log(`Size: ${stats.size} bytes`);
-console.log(`Modified: ${stats.modifiedAt}`);
-console.log(`Format: ${stats.format}`);
-console.log(`ETag: ${stats.etag}`);
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **conflictResolution** | `Enum<'skip' \| 'overwrite' \| 'merge' \| 'fail'>` | optional | How to handle existing items |
+| **validate** | `boolean` | optional | Validate before import |
+| **dryRun** | `boolean` | optional | Simulate import without saving |
+| **continueOnError** | `boolean` | optional | Continue if validation fails |
+| **transform** | `string` | optional | Transform items before import |
---
-## Glob Patterns
+## MetadataLoadOptions
-### Common Patterns
+### Properties
-```typescript
-// All object files
-patterns: ['**/*.object.ts']
-
-// All files in specific directory
-patterns: ['src/domains/**/*.object.ts']
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **patterns** | `string[]` | optional | File glob patterns |
+| **ifNoneMatch** | `string` | optional | ETag for conditional request |
+| **ifModifiedSince** | `string` | optional | Only load if modified after this date |
+| **validate** | `boolean` | optional | Validate against schema |
+| **useCache** | `boolean` | optional | Enable caching |
+| **filter** | `string` | optional | Filter predicate as string |
+| **limit** | `integer` | optional | Maximum items to load |
+| **recursive** | `boolean` | optional | Search subdirectories |
-// Multiple file types
-patterns: ['**/*.object.{ts,json,yaml}']
+---
-// Exclude patterns (using filter)
-patterns: ['**/*.object.ts']
-filter: "(item) => !item.name.startsWith('test_')"
-```
+## MetadataLoadResult
-### Pattern Examples
+### Properties
-| Pattern | Matches |
-| :--- | :--- |
-| `**/*.object.ts` | All .object.ts files recursively |
-| `src/**/*.object.ts` | All .object.ts in src/ directory |
-| `*.object.json` | .object.json files in current directory only |
-| `{a,b}/*.ts` | .ts files in a/ or b/ directories |
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **data** | `any \| null` | optional | Loaded metadata |
+| **fromCache** | `boolean` | optional | Loaded from cache |
+| **notModified** | `boolean` | optional | Not modified since last request |
+| **etag** | `string` | optional | Entity tag |
+| **stats** | `object` | optional | Metadata statistics |
+| **loadTime** | `number` | optional | Load duration in ms |
---
-## Best Practices
-
-### 1. Use Specific Patterns
+## MetadataLoaderContract
-```typescript
-// ✅ Good - specific patterns
-patterns: ['src/domains/**/*.object.ts']
+### Properties
-// ❌ Avoid - too broad
-patterns: ['**/*']
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **name** | `string` | ✅ | Loader identifier |
+| **supportedFormats** | `Enum<'json' \| 'yaml' \| 'typescript' \| 'javascript'>[]` | ✅ | Supported formats |
+| **supportsWatch** | `boolean` | optional | Supports file watching |
+| **supportsWrite** | `boolean` | optional | Supports write operations |
+| **supportsCache** | `boolean` | optional | Supports caching |
-### 2. Enable Validation
+---
-```typescript
-// ✅ Always validate in production
-const options: MetadataLoadOptions = {
- validate: true,
- patterns: ['**/*.object.ts']
-};
-```
+## MetadataManagerConfig
-### 3. Use Caching
+### Properties
-```typescript
-// ✅ Enable caching for performance
-const options: MetadataLoadOptions = {
- useCache: true,
- ifModifiedSince: lastLoadTime
-};
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **rootDir** | `string` | optional | Root directory path |
+| **formats** | `Enum<'json' \| 'yaml' \| 'typescript' \| 'javascript'>[]` | optional | Enabled formats |
+| **cache** | `object` | optional | Cache settings |
+| **watch** | `boolean` | optional | Enable file watching |
+| **watchOptions** | `object` | optional | File watcher options |
+| **validation** | `object` | optional | Validation settings |
+| **loaderOptions** | `Record` | optional | Loader-specific configuration |
-### 4. Limit Results for Large Datasets
+---
-```typescript
-// ✅ Use pagination for large datasets
-const options: MetadataLoadOptions = {
- patterns: ['**/*.object.ts'],
- limit: 100
-};
-```
+## MetadataSaveOptions
-### 5. Handle Load Errors
+### Properties
-```typescript
-try {
- const metadata = await loader.load(options);
- // Process metadata
-} catch (error) {
- if (error.code === 'VALIDATION_FAILED') {
- // Handle validation errors
- console.error('Invalid metadata:', error.details);
- } else {
- // Handle other errors
- throw error;
- }
-}
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **format** | `Enum<'json' \| 'yaml' \| 'typescript' \| 'javascript'>` | optional | Output format |
+| **prettify** | `boolean` | optional | Format with indentation |
+| **indent** | `integer` | optional | Indentation spaces |
+| **sortKeys** | `boolean` | optional | Sort object keys |
+| **includeDefaults** | `boolean` | optional | Include default values |
+| **backup** | `boolean` | optional | Create backup file |
+| **overwrite** | `boolean` | optional | Overwrite existing file |
+| **atomic** | `boolean` | optional | Use atomic write operation |
+| **path** | `string` | optional | Custom output path |
---
-## Storage Backends
+## MetadataSaveResult
-### File System
+### Properties
-```typescript
-const loader = new FileSystemMetadataLoader({
- basePath: '/app/metadata'
-});
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **success** | `boolean` | ✅ | Save successful |
+| **path** | `string` | ✅ | Output path |
+| **etag** | `string` | optional | Generated entity tag |
+| **size** | `integer` | optional | File size |
+| **saveTime** | `number` | optional | Save duration in ms |
+| **backupPath** | `string` | optional | Backup file path |
-### HTTP/Remote
+---
-```typescript
-const loader = new HttpMetadataLoader({
- baseUrl: 'https://api.example.com/metadata'
-});
-```
+## MetadataStats
-### S3
+### Properties
-```typescript
-const loader = new S3MetadataLoader({
- bucket: 'my-metadata-bucket',
- prefix: 'metadata/'
-});
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **size** | `integer` | ✅ | File size in bytes |
+| **modifiedAt** | `string` | ✅ | Last modified date |
+| **etag** | `string` | ✅ | Entity tag for cache validation |
+| **format** | `Enum<'json' \| 'yaml' \| 'typescript' \| 'javascript'>` | ✅ | Serialization format |
+| **path** | `string` | optional | File system path |
+| **metadata** | `Record` | optional | Provider-specific metadata |
-### Database
+---
-```typescript
-const loader = new DatabaseMetadataLoader({
- table: 'metadata',
- connectionString: 'postgresql://...'
-});
-```
+## MetadataWatchEvent
----
+### Properties
-## Related
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **type** | `Enum<'added' \| 'changed' \| 'deleted'>` | ✅ | Event type |
+| **metadataType** | `string` | ✅ | Type of metadata |
+| **name** | `string` | ✅ | Item identifier |
+| **path** | `string` | ✅ | File path |
+| **data** | `any` | optional | Item data |
+| **timestamp** | `string` | ✅ | Event timestamp |
-- [Manifest](/docs/references/system/manifest) - Plugin manifest specification
-- [Plugin](/docs/references/system/plugin) - Plugin protocol
-- [Object](/docs/references/data/object) - Object metadata schema
diff --git a/content/docs/references/system/plugin-lifecycle-events.mdx b/content/docs/references/system/plugin-lifecycle-events.mdx
index 4965dc895..95c83e690 100644
--- a/content/docs/references/system/plugin-lifecycle-events.mdx
+++ b/content/docs/references/system/plugin-lifecycle-events.mdx
@@ -1,6 +1,6 @@
---
title: Plugin Lifecycle Events
-description: Plugin lifecycle event schemas
+description: Plugin Lifecycle Events protocol schemas
---
# Plugin Lifecycle Events
@@ -9,301 +9,185 @@ description: Plugin lifecycle event schemas
**Source:** `packages/spec/src/system/plugin-lifecycle-events.zod.ts`
-## Overview
-
-Plugin lifecycle events protocol defines Zod schemas for all event data structures emitted during plugin lifecycle phases. These schemas provide runtime validation and type safety for event handlers.
-
## TypeScript Usage
```typescript
-import {
- PluginRegisteredEventSchema,
- PluginLifecyclePhaseEventSchema,
- PluginErrorEventSchema,
- ServiceRegisteredEventSchema,
- HookRegisteredEventSchema,
- KernelReadyEventSchema,
- PluginLifecycleEventType
-} from '@objectstack/spec/system';
-
-import type {
- PluginRegisteredEvent,
- PluginLifecyclePhaseEvent,
- PluginErrorEvent,
- EventPhase
-} from '@objectstack/spec/system';
-
-// Validate event data
-const event = PluginRegisteredEventSchema.parse({
- pluginName: 'crm-plugin',
- timestamp: Date.now(),
- version: '1.0.0'
-});
+import { EventPhaseSchema, HookRegisteredEventSchema, HookTriggeredEventSchema, KernelEventBaseSchema, KernelReadyEventSchema, KernelShutdownEventSchema, PluginErrorEventSchema, PluginEventBaseSchema, PluginLifecycleEventTypeSchema, PluginLifecyclePhaseEventSchema, PluginRegisteredEventSchema, ServiceRegisteredEventSchema, ServiceUnregisteredEventSchema } from '@objectstack/spec/system';
+import type { EventPhase, HookRegisteredEvent, HookTriggeredEvent, KernelEventBase, KernelReadyEvent, KernelShutdownEvent, PluginErrorEvent, PluginEventBase, PluginLifecycleEventType, PluginLifecyclePhaseEvent, PluginRegisteredEvent, ServiceRegisteredEvent, ServiceUnregisteredEvent } from '@objectstack/spec/system';
+
+// Validate data
+const result = EventPhaseSchema.parse(data);
```
---
-## Event Types
-
-### PluginLifecycleEventType
+## EventPhase
-Enumeration of all possible plugin lifecycle event types:
+Plugin lifecycle phase
-**Kernel Events:**
-- `kernel:ready` - Kernel initialization completed
-- `kernel:shutdown` - Kernel is shutting down
-- `kernel:before-init` - Before kernel initialization
-- `kernel:after-init` - After kernel initialization
+### Allowed Values
-**Plugin Events:**
-- `plugin:registered` - Plugin registered with kernel
-- `plugin:before-init` - Before plugin initialization
-- `plugin:init` - During plugin initialization
-- `plugin:after-init` - After plugin initialization
-- `plugin:before-start` - Before plugin startup
-- `plugin:started` - Plugin started successfully
-- `plugin:after-start` - After plugin startup
-- `plugin:before-destroy` - Before plugin destruction
-- `plugin:destroyed` - Plugin destroyed
-- `plugin:after-destroy` - After plugin destruction
-- `plugin:error` - Plugin encountered an error
+* `init`
+* `start`
+* `destroy`
-**Service Events:**
-- `service:registered` - Service registered in DI container
-- `service:unregistered` - Service unregistered from DI container
+---
-**Hook Events:**
-- `hook:registered` - Hook registered
-- `hook:triggered` - Hook triggered
+## HookRegisteredEvent
----
+### Properties
-## Event Schemas
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **hookName** | `string` | ✅ | Name of the hook |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
+| **handlerCount** | `integer` | ✅ | Number of handlers registered for this hook |
-### PluginRegisteredEvent
+---
-Emitted when a plugin is registered with the kernel.
+## HookTriggeredEvent
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **pluginName** | `string` | ✅ | Name of the plugin |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **version** | `string` | optional | Plugin version |
-
-#### Example
-
-```json
-{
- "pluginName": "crm-plugin",
- "timestamp": 1706659200000,
- "version": "1.0.0"
-}
-```
+| **hookName** | `string` | ✅ | Name of the hook |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
+| **args** | `any[]` | ✅ | Arguments passed to the hook handlers |
+| **handlerCount** | `integer` | optional | Number of handlers that will handle this event |
---
-### PluginLifecyclePhaseEvent
+## KernelEventBase
-Emitted during plugin lifecycle phases (init, start, destroy).
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **pluginName** | `string` | ✅ | Name of the plugin |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **duration** | `number` | optional | Duration of the phase in milliseconds |
-| **phase** | `'init' \| 'start' \| 'destroy'` | optional | Lifecycle phase |
-
-#### Example
-
-```json
-{
- "pluginName": "crm-plugin",
- "timestamp": 1706659200000,
- "duration": 1250,
- "phase": "init"
-}
-```
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
---
-### PluginErrorEvent
-
-Emitted when a plugin encounters an error.
+## KernelReadyEvent
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **pluginName** | `string` | ✅ | Name of the plugin |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **error** | `Error` | ✅ | Error object |
-| **phase** | `'init' \| 'start' \| 'destroy'` | ✅ | Lifecycle phase where error occurred |
-| **errorMessage** | `string` | optional | Error message (for serialization) |
-| **errorStack** | `string` | optional | Error stack trace (for debugging) |
-
-#### Example
-
-```json
-{
- "pluginName": "crm-plugin",
- "timestamp": 1706659200000,
- "error": "Error: Connection failed",
- "phase": "start",
- "errorMessage": "Connection failed",
- "errorStack": "Error: Connection failed\n at ..."
-}
-```
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
+| **duration** | `number` | optional | Total initialization duration in milliseconds |
+| **pluginCount** | `integer` | optional | Number of plugins initialized |
---
-### ServiceRegisteredEvent
-
-Emitted when a service is registered in the DI container.
+## KernelShutdownEvent
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **serviceName** | `string` | ✅ | Name of the registered service |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **serviceType** | `string` | optional | Type or interface name of the service |
-
-#### Example
-
-```json
-{
- "serviceName": "database",
- "timestamp": 1706659200000,
- "serviceType": "IDataEngine"
-}
-```
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
+| **reason** | `string` | optional | Reason for kernel shutdown |
---
-### ServiceUnregisteredEvent
-
-Emitted when a service is unregistered from the DI container.
+## PluginErrorEvent
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **serviceName** | `string` | ✅ | Name of the unregistered service |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-
-#### Example
-
-```json
-{
- "serviceName": "database",
- "timestamp": 1706659200000
-}
-```
+| **pluginName** | `string` | ✅ | Name of the plugin |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds when event occurred |
+| **error** | `any` | ✅ | Error object |
+| **phase** | `Enum<'init' \| 'start' \| 'destroy'>` | ✅ | Lifecycle phase where error occurred |
+| **errorMessage** | `string` | optional | Error message |
+| **errorStack** | `string` | optional | Error stack trace |
---
-### HookRegisteredEvent
-
-Emitted when a hook is registered.
+## PluginEventBase
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **hookName** | `string` | ✅ | Name of the hook |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **handlerCount** | `number` | ✅ | Number of handlers registered for this hook |
+| **pluginName** | `string` | ✅ | Name of the plugin |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds when event occurred |
-#### Example
+---
-```json
-{
- "hookName": "data.beforeInsert",
- "timestamp": 1706659200000,
- "handlerCount": 3
-}
-```
+## PluginLifecycleEventType
+
+Plugin lifecycle event type
+
+### Allowed Values
+
+* `kernel:ready`
+* `kernel:shutdown`
+* `kernel:before-init`
+* `kernel:after-init`
+* `plugin:registered`
+* `plugin:before-init`
+* `plugin:init`
+* `plugin:after-init`
+* `plugin:before-start`
+* `plugin:started`
+* `plugin:after-start`
+* `plugin:before-destroy`
+* `plugin:destroyed`
+* `plugin:after-destroy`
+* `plugin:error`
+* `service:registered`
+* `service:unregistered`
+* `hook:registered`
+* `hook:triggered`
---
-### HookTriggeredEvent
+## PluginLifecyclePhaseEvent
-Emitted when a hook is triggered.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **hookName** | `string` | ✅ | Name of the hook |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **args** | `any[]` | ✅ | Arguments passed to hook handlers |
-| **handlerCount** | `number` | optional | Number of handlers that will handle this event |
-
-#### Example
-
-```json
-{
- "hookName": "data.beforeInsert",
- "timestamp": 1706659200000,
- "args": [{ "object": "customer", "data": {...} }],
- "handlerCount": 3
-}
-```
+| **pluginName** | `string` | ✅ | Name of the plugin |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds when event occurred |
+| **duration** | `number` | optional | Duration of the lifecycle phase in milliseconds |
+| **phase** | `Enum<'init' \| 'start' \| 'destroy'>` | optional | Lifecycle phase |
---
-### KernelReadyEvent
+## PluginRegisteredEvent
-Emitted when the kernel initialization is complete.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **duration** | `number` | optional | Total initialization duration in milliseconds |
-| **pluginCount** | `number` | optional | Number of plugins initialized |
-
-#### Example
-
-```json
-{
- "timestamp": 1706659200000,
- "duration": 5400,
- "pluginCount": 12
-}
-```
+| **pluginName** | `string` | ✅ | Name of the plugin |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds when event occurred |
+| **version** | `string` | optional | Plugin version |
---
-### KernelShutdownEvent
-
-Emitted when the kernel is shutting down.
+## ServiceRegisteredEvent
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |
-| **reason** | `string` | optional | Reason for kernel shutdown |
+| **serviceName** | `string` | ✅ | Name of the registered service |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
+| **serviceType** | `string` | optional | Type or interface name of the service |
-#### Example
+---
-```json
-{
- "timestamp": 1706659200000,
- "reason": "SIGTERM received"
-}
-```
+## ServiceUnregisteredEvent
----
+### Properties
-## Related
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **serviceName** | `string` | ✅ | Name of the unregistered service |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds |
-- [Plugin](/docs/references/system/plugin) - Plugin protocol
-- [Startup Orchestrator](/docs/references/system/startup-orchestrator) - Plugin startup orchestration
-- [Events](/docs/references/system/events) - Event system protocol
diff --git a/content/docs/references/system/plugin-validator.mdx b/content/docs/references/system/plugin-validator.mdx
index 8f59deeae..552054a96 100644
--- a/content/docs/references/system/plugin-validator.mdx
+++ b/content/docs/references/system/plugin-validator.mdx
@@ -1,6 +1,6 @@
---
title: Plugin Validator
-description: Plugin validation protocol
+description: Plugin Validator protocol schemas
---
# Plugin Validator
@@ -9,289 +9,64 @@ description: Plugin validation protocol
**Source:** `packages/spec/src/system/plugin-validator.zod.ts`
-## Overview
-
-Plugin Validator protocol defines schemas for validating plugin configurations, manifests, and metadata. It provides structured error and warning reporting for plugin validation operations.
-
## TypeScript Usage
```typescript
-import {
- ValidationErrorSchema,
- ValidationWarningSchema,
- ValidationResultSchema
-} from '@objectstack/spec/system';
-
-import type {
- ValidationError,
- ValidationWarning,
- ValidationResult
-} from '@objectstack/spec/system';
+import { PluginMetadataSchema, ValidationErrorSchema, ValidationResultSchema, ValidationWarningSchema } from '@objectstack/spec/system';
+import type { PluginMetadata, ValidationError, ValidationResult, ValidationWarning } from '@objectstack/spec/system';
-// Validate plugin
-const result: ValidationResult = {
- valid: false,
- errors: [{
- field: 'name',
- message: 'Plugin name is required',
- code: 'REQUIRED_FIELD'
- }],
- warnings: [{
- field: 'description',
- message: 'Description is recommended',
- code: 'MISSING_DESCRIPTION'
- }]
-};
+// Validate data
+const result = PluginMetadataSchema.parse(data);
```
---
-## Schemas
+## PluginMetadata
-### ValidationError
+Plugin metadata for validation
-Represents a single validation error that prevents plugin from loading.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **field** | `string` | ✅ | Field name that failed validation |
-| **message** | `string` | ✅ | Human-readable error message |
-| **code** | `string` | optional | Machine-readable error code |
-
-#### Example
-
-```json
-{
- "field": "version",
- "message": "Invalid semver format",
- "code": "INVALID_VERSION"
-}
-```
+| **name** | `string` | ✅ | Unique plugin identifier |
+| **version** | `string` | optional | Semantic version (e.g., 1.0.0) |
+| **dependencies** | `string[]` | optional | Array of plugin names this plugin depends on |
+| **signature** | `string` | optional | Cryptographic signature for plugin verification |
---
-### ValidationWarning
+## ValidationError
-Represents a non-fatal validation warning.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **field** | `string` | ✅ | Field name with warning |
-| **message** | `string` | ✅ | Human-readable warning message |
-| **code** | `string` | optional | Machine-readable warning code |
-
-#### Example
-
-```json
-{
- "field": "description",
- "message": "Description is empty",
- "code": "MISSING_DESCRIPTION"
-}
-```
+| **field** | `string` | ✅ | Field name that failed validation |
+| **message** | `string` | ✅ | Human-readable error message |
+| **code** | `string` | optional | Machine-readable error code |
---
-### ValidationResult
+## ValidationResult
-Result of plugin validation operation.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **valid** | `boolean` | ✅ | Whether the plugin passed validation |
-| **errors** | `ValidationError[]` | optional | Validation errors (block loading) |
-| **warnings** | `ValidationWarning[]` | optional | Validation warnings (non-blocking) |
-
-#### Example
-
-```json
-{
- "valid": false,
- "errors": [{
- "field": "name",
- "message": "Plugin name is required",
- "code": "REQUIRED_FIELD"
- }],
- "warnings": [{
- "field": "description",
- "message": "Description is recommended",
- "code": "MISSING_DESCRIPTION"
- }]
-}
-```
-
----
-
-## Common Error Codes
-
-### Required Field Errors
-
-| Code | Description |
-| :--- | :--- |
-| `REQUIRED_FIELD` | Required field is missing |
-| `INVALID_FORMAT` | Field format is invalid |
-| `INVALID_TYPE` | Field has wrong type |
-
-### Version Errors
-
-| Code | Description |
-| :--- | :--- |
-| `INVALID_VERSION` | Version is not valid semver |
-| `VERSION_MISMATCH` | Version conflicts with dependencies |
-
-### Dependency Errors
-
-| Code | Description |
-| :--- | :--- |
-| `MISSING_DEPENDENCY` | Required dependency not found |
-| `CIRCULAR_DEPENDENCY` | Circular dependency detected |
-| `INCOMPATIBLE_VERSION` | Dependency version incompatible |
-
-### Capability Errors
-
-| Code | Description |
-| :--- | :--- |
-| `INVALID_CAPABILITY` | Unknown capability declared |
-| `CAPABILITY_CONFLICT` | Conflicting capabilities |
-
----
-
-## Usage Examples
-
-### Basic Validation
-
-```typescript
-import { PluginValidator } from '@objectstack/core';
-
-const validator = new PluginValidator();
-
-const result = validator.validate(pluginManifest);
-
-if (!result.valid) {
- console.error('Validation failed:');
- result.errors?.forEach(err => {
- console.error(`- ${err.field}: ${err.message} (${err.code})`);
- });
-}
-
-if (result.warnings?.length) {
- console.warn('Validation warnings:');
- result.warnings.forEach(warn => {
- console.warn(`- ${warn.field}: ${warn.message}`);
- });
-}
-```
-
-### Validation with Error Handling
-
-```typescript
-try {
- const result = validator.validate(pluginManifest);
-
- if (!result.valid) {
- throw new ValidationError('Plugin validation failed', result.errors);
- }
-
- // Continue with plugin loading
- await loadPlugin(pluginManifest);
-} catch (error) {
- if (error instanceof ValidationError) {
- // Handle validation errors
- logValidationErrors(error.errors);
- } else {
- // Handle other errors
- throw error;
- }
-}
-```
-
-### Custom Validation Rules
-
-```typescript
-const validator = new PluginValidator({
- customRules: [
- {
- field: 'name',
- validate: (value) => {
- if (!value.startsWith('objectstack-')) {
- return {
- valid: false,
- error: {
- field: 'name',
- message: 'Plugin name must start with "objectstack-"',
- code: 'INVALID_PREFIX'
- }
- };
- }
- return { valid: true };
- }
- }
- ]
-});
-```
+| **errors** | `object[]` | optional | Validation errors |
+| **warnings** | `object[]` | optional | Validation warnings |
---
-## Best Practices
-
-### 1. Always Check Validation Results
-
-```typescript
-const result = validator.validate(manifest);
-
-if (!result.valid) {
- // Never ignore validation errors
- throw new Error('Plugin validation failed');
-}
-```
+## ValidationWarning
-### 2. Log Warnings
+### Properties
-```typescript
-if (result.warnings?.length) {
- // Log warnings for debugging
- logger.warn('Plugin validation warnings:', result.warnings);
-}
-```
-
-### 3. Use Error Codes
-
-```typescript
-// Check specific error codes
-const hasVersionError = result.errors?.some(e =>
- e.code === 'INVALID_VERSION'
-);
-
-if (hasVersionError) {
- // Handle version errors specifically
-}
-```
-
-### 4. Provide Helpful Error Messages
-
-```typescript
-const customValidator = {
- validate: (value) => ({
- valid: false,
- error: {
- field: 'dependencies',
- message: 'Dependency "@objectstack/core" version "^2.0.0" is incompatible with current version "1.5.0"',
- code: 'INCOMPATIBLE_VERSION'
- }
- })
-};
-```
-
----
-
-## Related
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **field** | `string` | ✅ | Field name with warning |
+| **message** | `string` | ✅ | Human-readable warning message |
+| **code** | `string` | optional | Machine-readable warning code |
-- [Plugin](/docs/references/system/plugin) - Plugin protocol
-- [Manifest](/docs/references/system/manifest) - Plugin manifest specification
-- [Plugin Capability](/docs/references/system/plugin-capability) - Plugin capabilities
diff --git a/content/docs/references/system/service-registry.mdx b/content/docs/references/system/service-registry.mdx
index 7b70885fe..bb5d449f7 100644
--- a/content/docs/references/system/service-registry.mdx
+++ b/content/docs/references/system/service-registry.mdx
@@ -1,6 +1,6 @@
---
title: Service Registry
-description: Service registry protocol
+description: Service Registry protocol schemas
---
# Service Registry
@@ -9,417 +9,92 @@ description: Service registry protocol
**Source:** `packages/spec/src/system/service-registry.zod.ts`
-## Overview
-
-Service Registry protocol defines schemas for service registration, dependency injection, and service discovery. It provides configuration and metadata structures for managing services in the ObjectStack kernel.
-
## TypeScript Usage
```typescript
-import {
- ServiceMetadataSchema,
- ServiceRegistryConfigSchema,
- ServiceScopeType
-} from '@objectstack/spec/system';
+import { ScopeConfigSchema, ScopeInfoSchema, ServiceFactoryRegistrationSchema, ServiceMetadataSchema, ServiceRegistryConfigSchema, ServiceScopeTypeSchema } from '@objectstack/spec/system';
+import type { ScopeConfig, ScopeInfo, ServiceFactoryRegistration, ServiceMetadata, ServiceRegistryConfig, ServiceScopeType } from '@objectstack/spec/system';
-import type {
- ServiceMetadata,
- ServiceRegistryConfig,
- ServiceScopeType
-} from '@objectstack/spec/system';
+// Validate data
+const result = ScopeConfigSchema.parse(data);
```
---
-## Schemas
-
-### ServiceScopeType
-
-Different service scoping strategies.
+## ScopeConfig
-**Values:**
-- `singleton` - Single instance shared across the application
-- `transient` - New instance created each time
-- `scoped` - Instance per scope (request, session, transaction, etc.)
+### Properties
-#### Example
-
-```typescript
-const scope: ServiceScopeType = 'singleton';
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **scopeType** | `string` | ✅ | Type of scope |
+| **scopeId** | `string` | optional | Unique scope identifier |
+| **metadata** | `Record` | optional | Scope-specific context metadata |
---
-### ServiceMetadata
-
-Metadata about a registered service.
+## ScopeInfo
-#### Properties
+### Properties
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **name** | `string` | ✅ | - | Unique service name identifier |
-| **scope** | `ServiceScopeType` | optional | 'singleton' | Service scope type |
-| **type** | `string` | optional | - | Service type or interface name |
-| **registeredAt** | `number` | optional | - | Unix timestamp in milliseconds when service was registered |
-| **metadata** | `Record` | optional | - | Additional service-specific metadata |
-
-#### Example
-
-```json
-{
- "name": "database",
- "scope": "singleton",
- "type": "IDataEngine",
- "registeredAt": 1706659200000,
- "metadata": {
- "driver": "postgres",
- "version": "1.0.0"
- }
-}
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **scopeId** | `string` | ✅ | Unique scope identifier |
+| **scopeType** | `string` | ✅ | Type of scope |
+| **createdAt** | `integer` | ✅ | Unix timestamp in milliseconds when scope was created |
+| **serviceCount** | `integer` | optional | Number of services registered in this scope |
+| **metadata** | `Record` | optional | Scope-specific context metadata |
---
-### ServiceRegistryConfig
-
-Configuration for service registry behavior.
+## ServiceFactoryRegistration
-#### Properties
+### Properties
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **strictMode** | `boolean` | optional | true | Throw errors on invalid operations |
-| **allowOverwrite** | `boolean` | optional | false | Allow overwriting existing service registrations |
-| **enableLogging** | `boolean` | optional | true | Enable service registration/resolution logging |
-| **scopeTypes** | `string[]` | optional | - | Custom scope types supported |
-
-#### Example
-
-```json
-{
- "strictMode": true,
- "allowOverwrite": false,
- "enableLogging": true,
- "scopeTypes": ["singleton", "transient", "request", "session"]
-}
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **name** | `string` | ✅ | Unique service name identifier |
+| **scope** | `Enum<'singleton' \| 'transient' \| 'scoped'>` | optional | Service scope type |
+| **factoryType** | `Enum<'sync' \| 'async'>` | optional | Whether factory is synchronous or asynchronous |
+| **singleton** | `boolean` | optional | Whether to cache the factory result (singleton pattern) |
---
-## Usage Examples
-
-### Register Singleton Service
-
-```typescript
-import { ServiceRegistry } from '@objectstack/core';
-
-const registry = new ServiceRegistry();
-
-// Register a singleton service
-registry.register('database', dataEngineInstance, {
- scope: 'singleton',
- type: 'IDataEngine',
- metadata: {
- driver: 'postgres',
- connectionPool: true
- }
-});
-```
-
-### Register Transient Service
-
-```typescript
-// Register a transient service (new instance each time)
-registry.register('logger', LoggerFactory, {
- scope: 'transient',
- type: 'ILogger'
-});
-```
-
-### Register Scoped Service
-
-```typescript
-// Register a scoped service (per request)
-registry.register('userContext', UserContextFactory, {
- scope: 'scoped',
- type: 'IUserContext',
- metadata: {
- scopeType: 'request'
- }
-});
-```
-
-### Resolve Service
-
-```typescript
-// Resolve a service
-const database = registry.resolve('database');
-
-// Resolve with type checking
-const logger = registry.resolve('logger');
-```
-
-### Get Service Metadata
-
-```typescript
-const metadata = registry.getMetadata('database');
-
-console.log(`Service: ${metadata.name}`);
-console.log(`Type: ${metadata.type}`);
-console.log(`Scope: ${metadata.scope}`);
-console.log(`Registered at: ${new Date(metadata.registeredAt!)}`);
-```
+## ServiceMetadata
-### List All Services
+### Properties
-```typescript
-const services = registry.list();
-
-services.forEach(metadata => {
- console.log(`${metadata.name} (${metadata.scope})`);
-});
-```
-
-### Unregister Service
-
-```typescript
-registry.unregister('database');
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **name** | `string` | ✅ | Unique service name identifier |
+| **scope** | `Enum<'singleton' \| 'transient' \| 'scoped'>` | optional | Service scope type |
+| **type** | `string` | optional | Service type or interface name |
+| **registeredAt** | `integer` | optional | Unix timestamp in milliseconds when service was registered |
+| **metadata** | `Record` | optional | Additional service-specific metadata |
---
-## Service Scopes
-
-### Singleton
-
-Single instance shared across the entire application.
-
-```typescript
-registry.register('config', configInstance, {
- scope: 'singleton'
-});
-
-const config1 = registry.resolve('config');
-const config2 = registry.resolve('config');
-// config1 === config2 (same instance)
-```
-
-### Transient
-
-New instance created for each resolution.
-
-```typescript
-registry.register('logger', LoggerFactory, {
- scope: 'transient'
-});
-
-const logger1 = registry.resolve('logger');
-const logger2 = registry.resolve('logger');
-// logger1 !== logger2 (different instances)
-```
-
-### Scoped
-
-Instance per scope (request, session, transaction, etc.).
-
-```typescript
-// Create a request scope
-const requestScope = registry.createScope('request');
+## ServiceRegistryConfig
-registry.register('userContext', UserContextFactory, {
- scope: 'scoped'
-});
+### Properties
-// Same instance within scope
-const ctx1 = requestScope.resolve('userContext');
-const ctx2 = requestScope.resolve('userContext');
-// ctx1 === ctx2
-
-// Different instance in different scope
-const requestScope2 = registry.createScope('request');
-const ctx3 = requestScope2.resolve('userContext');
-// ctx1 !== ctx3
-```
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **strictMode** | `boolean` | optional | Throw errors on invalid operations (duplicate registration, service not found, etc.) |
+| **allowOverwrite** | `boolean` | optional | Allow overwriting existing service registrations |
+| **enableLogging** | `boolean` | optional | Enable logging for service registration and retrieval |
+| **scopeTypes** | `string[]` | optional | Supported scope types |
+| **maxServices** | `integer` | optional | Maximum number of services that can be registered |
---
-## Configuration Examples
-
-### Strict Mode
-
-```typescript
-// Throw errors on invalid operations
-const registry = new ServiceRegistry({
- strictMode: true
-});
-
-// This will throw if service doesn't exist
-const service = registry.resolve('non-existent'); // Error!
-
-// This will throw if service already exists
-registry.register('database', db1);
-registry.register('database', db2); // Error!
-```
-
-### Permissive Mode
-
-```typescript
-// Allow more flexible operations
-const registry = new ServiceRegistry({
- strictMode: false,
- allowOverwrite: true
-});
-
-// Returns undefined instead of throwing
-const service = registry.resolve('non-existent'); // undefined
-
-// Allows overwriting
-registry.register('database', db1);
-registry.register('database', db2); // OK, replaces db1
-```
-
-### Custom Scope Types
-
-```typescript
-const registry = new ServiceRegistry({
- scopeTypes: ['singleton', 'transient', 'request', 'session', 'transaction']
-});
-
-// Register with custom scope
-registry.register('transactionManager', factory, {
- scope: 'transaction'
-});
-```
-
----
-
-## Best Practices
-
-### 1. Use Singleton for Stateless Services
-
-```typescript
-// ✅ Good - configuration is stateless and shared
-registry.register('config', configInstance, {
- scope: 'singleton'
-});
-
-// ✅ Good - shared connection pool
-registry.register('database', dataEngine, {
- scope: 'singleton'
-});
-```
-
-### 2. Use Transient for Stateful Services
-
-```typescript
-// ✅ Good - each logger can have its own state
-registry.register('logger', LoggerFactory, {
- scope: 'transient'
-});
-```
+## ServiceScopeType
-### 3. Use Scoped for Request-Specific Data
+Service scope type
-```typescript
-// ✅ Good - user context per request
-registry.register('userContext', UserContextFactory, {
- scope: 'scoped',
- metadata: { scopeType: 'request' }
-});
-
-// ✅ Good - transaction per request
-registry.register('transaction', TransactionFactory, {
- scope: 'scoped',
- metadata: { scopeType: 'request' }
-});
-```
-
-### 4. Include Type Information
-
-```typescript
-// ✅ Good - document the interface
-registry.register('database', dataEngine, {
- scope: 'singleton',
- type: 'IDataEngine',
- metadata: {
- driver: 'postgres',
- version: '1.0.0'
- }
-});
-```
-
-### 5. Handle Resolution Errors
-
-```typescript
-try {
- const service = registry.resolve('database');
-} catch (error) {
- if (error.code === 'SERVICE_NOT_FOUND') {
- console.error('Database service not registered');
- } else {
- throw error;
- }
-}
-```
-
----
-
-## Dependency Injection Patterns
-
-### Constructor Injection
-
-```typescript
-class UserService {
- constructor(
- private database: IDataEngine,
- private logger: ILogger
- ) {}
-}
-
-// Register factory that resolves dependencies
-registry.register('userService', () => {
- const database = registry.resolve('database');
- const logger = registry.resolve('logger');
- return new UserService(database, logger);
-}, { scope: 'singleton' });
-```
-
-### Property Injection
-
-```typescript
-class OrderService {
- database?: IDataEngine;
- logger?: ILogger;
-
- init() {
- this.database = registry.resolve('database');
- this.logger = registry.resolve('logger');
- }
-}
-```
-
-### Method Injection
-
-```typescript
-class ReportService {
- generate(database: IDataEngine, logger: ILogger) {
- // Use injected dependencies
- }
-}
-
-// Resolve and inject at call time
-const reportService = new ReportService();
-reportService.generate(
- registry.resolve('database'),
- registry.resolve('logger')
-);
-```
-
----
+### Allowed Values
-## Related
+* `singleton`
+* `transient`
+* `scoped`
-- [Plugin](/docs/references/system/plugin) - Plugin protocol
-- [Startup Orchestrator](/docs/references/system/startup-orchestrator) - Plugin startup
-- [Plugin Lifecycle Events](/docs/references/system/plugin-lifecycle-events) - Service registration events
diff --git a/content/docs/references/system/startup-orchestrator.mdx b/content/docs/references/system/startup-orchestrator.mdx
index 8a8c82723..99c87441c 100644
--- a/content/docs/references/system/startup-orchestrator.mdx
+++ b/content/docs/references/system/startup-orchestrator.mdx
@@ -1,6 +1,6 @@
---
title: Startup Orchestrator
-description: Plugin startup orchestration protocol
+description: Startup Orchestrator protocol schemas
---
# Startup Orchestrator
@@ -9,291 +9,67 @@ description: Plugin startup orchestration protocol
**Source:** `packages/spec/src/system/startup-orchestrator.zod.ts`
-## Overview
-
-Startup Orchestrator protocol defines schemas for orchestrating plugin startup sequences, including dependency resolution, health checks, and rollback on failure.
-
## TypeScript Usage
```typescript
-import {
- StartupOptionsSchema,
- HealthStatusSchema,
- PluginStartupResultSchema,
- StartupOrchestrationResultSchema
-} from '@objectstack/spec/system';
-
-import type {
- StartupOptions,
- StartupOptionsInput,
- HealthStatus,
- PluginStartupResult,
- StartupOrchestrationResult
-} from '@objectstack/spec/system';
-
-// Configure startup options
-const options: StartupOptionsInput = {
- timeout: 30000,
- rollbackOnFailure: true,
- healthCheck: true,
- parallel: false
-};
-
-const validated = StartupOptionsSchema.parse(options);
-```
-
----
-
-## Schemas
-
-### StartupOptions
+import { HealthStatusSchema, PluginStartupResultSchema, StartupOptionsSchema, StartupOrchestrationResultSchema } from '@objectstack/spec/system';
+import type { HealthStatus, PluginStartupResult, StartupOptions, StartupOrchestrationResult } from '@objectstack/spec/system';
-Configuration for plugin startup orchestration.
-
-#### Properties
-
-| Property | Type | Required | Default | Description |
-| :--- | :--- | :--- | :--- | :--- |
-| **timeout** | `number` | optional | 30000 | Maximum time (ms) to wait for each plugin to start |
-| **rollbackOnFailure** | `boolean` | optional | true | Whether to rollback (destroy) already-started plugins on failure |
-| **healthCheck** | `boolean` | optional | false | Whether to run health checks after startup |
-| **parallel** | `boolean` | optional | false | Whether to start plugins in parallel when dependencies allow |
-| **context** | `any` | optional | - | Custom context to pass to plugin lifecycle methods |
-
-#### Example
-
-```typescript
-const options: StartupOptions = {
- timeout: 30000,
- rollbackOnFailure: true,
- healthCheck: true, // Enable health checks for production
- parallel: false
-};
+// Validate data
+const result = HealthStatusSchema.parse(data);
```
---
-### HealthStatus
+## HealthStatus
-Health status for a plugin after startup.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **healthy** | `boolean` | ✅ | Whether the plugin is healthy |
-| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds when health check was performed |
+| **timestamp** | `integer` | ✅ | Unix timestamp in milliseconds when health check was performed |
| **details** | `Record` | optional | Optional plugin-specific health details |
| **message** | `string` | optional | Error message if plugin is unhealthy |
-#### Example
-
-```json
-{
- "healthy": true,
- "timestamp": 1706659200000,
- "details": {
- "databaseConnected": true,
- "memoryUsage": 45.2
- }
-}
-```
-
---
-### PluginStartupResult
-
-Result of a single plugin startup operation.
+## PluginStartupResult
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **plugin** | `object` | ✅ | Plugin metadata (name, version) |
-| **plugin.name** | `string` | ✅ | Plugin name |
-| **plugin.version** | `string` | optional | Plugin version |
+| **plugin** | `Record` | ✅ | Plugin metadata |
| **success** | `boolean` | ✅ | Whether the plugin started successfully |
| **duration** | `number` | ✅ | Time taken to start the plugin in milliseconds |
-| **error** | `Error` | optional | Error object if startup failed |
-| **health** | `HealthStatus` | optional | Health status after startup (if healthCheck enabled) |
-
-#### Example
-
-```json
-{
- "plugin": {
- "name": "crm-plugin",
- "version": "1.0.0"
- },
- "success": true,
- "duration": 1250,
- "health": {
- "healthy": true,
- "timestamp": 1706659200000
- }
-}
-```
+| **error** | `any` | optional | Error object if startup failed |
+| **health** | `object` | optional | Health status after startup if health check was enabled |
---
-### StartupOrchestrationResult
+## StartupOptions
-Overall result of orchestrating startup for multiple plugins.
-
-#### Properties
+### Properties
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
-| **results** | `PluginStartupResult[]` | ✅ | Startup results for each plugin |
-| **totalDuration** | `number` | ✅ | Total time taken for all plugins in milliseconds |
-| **allSuccessful** | `boolean` | ✅ | Whether all plugins started successfully |
-| **rolledBack** | `string[]` | optional | Names of plugins that were rolled back |
-
-#### Example
-
-```json
-{
- "results": [
- {
- "plugin": { "name": "plugin1" },
- "success": true,
- "duration": 1200
- },
- {
- "plugin": { "name": "plugin2" },
- "success": true,
- "duration": 850
- }
- ],
- "totalDuration": 2050,
- "allSuccessful": true
-}
-```
-
----
-
-## Usage Examples
-
-### Basic Sequential Startup
-
-```typescript
-import { StartupOrchestrator } from '@objectstack/core';
-
-const orchestrator = new StartupOrchestrator(kernel);
-
-const result = await orchestrator.startPlugins({
- timeout: 30000,
- rollbackOnFailure: true,
- parallel: false
-});
-
-if (result.allSuccessful) {
- console.log(`All ${result.results.length} plugins started in ${result.totalDuration}ms`);
-} else {
- console.error('Some plugins failed to start');
-}
-```
-
-### Parallel Startup with Health Checks
-
-```typescript
-const result = await orchestrator.startPlugins({
- timeout: 60000,
- rollbackOnFailure: true,
- healthCheck: true,
- parallel: true
-});
-
-result.results.forEach(r => {
- if (r.success && r.health?.healthy) {
- console.log(`✓ ${r.plugin.name} - healthy (${r.duration}ms)`);
- } else if (r.success && !r.health?.healthy) {
- console.warn(`⚠ ${r.plugin.name} - started but unhealthy`);
- } else {
- console.error(`✗ ${r.plugin.name} - failed:`, r.error);
- }
-});
-```
-
-### Custom Context
-
-```typescript
-const result = await orchestrator.startPlugins({
- timeout: 30000,
- rollbackOnFailure: true,
- context: {
- environment: 'production',
- region: 'us-east-1',
- requestId: 'abc-123'
- }
-});
-```
-
-### Handling Rollback
-
-```typescript
-const result = await orchestrator.startPlugins({
- timeout: 30000,
- rollbackOnFailure: true
-});
-
-if (!result.allSuccessful && result.rolledBack) {
- console.log(`Rolled back plugins: ${result.rolledBack.join(', ')}`);
-}
-```
+| **timeout** | `integer` | optional | Maximum time in milliseconds to wait for each plugin to start |
+| **rollbackOnFailure** | `boolean` | optional | Whether to rollback already-started plugins if any plugin fails |
+| **healthCheck** | `boolean` | optional | Whether to run health checks after plugin startup |
+| **parallel** | `boolean` | optional | Whether to start plugins in parallel when dependencies allow |
+| **context** | `any` | optional | Custom context object to pass to plugin lifecycle methods |
---
-## Best Practices
-
-### 1. Set Appropriate Timeouts
-
-```typescript
-// Short timeout for simple plugins
-const quickStartup = { timeout: 10000 };
-
-// Longer timeout for complex plugins (databases, external services)
-const complexStartup = { timeout: 60000 };
-```
+## StartupOrchestrationResult
-### 2. Enable Health Checks for Critical Systems
+### Properties
-```typescript
-const result = await orchestrator.startPlugins({
- healthCheck: true, // Always check health for production
- rollbackOnFailure: true
-});
-```
-
-### 3. Use Parallel Startup Carefully
-
-```typescript
-// Only use parallel when plugins are truly independent
-const result = await orchestrator.startPlugins({
- parallel: true, // Faster, but requires careful dependency management
- timeout: 30000
-});
-```
-
-### 4. Always Handle Errors
-
-```typescript
-const result = await orchestrator.startPlugins(options);
-
-for (const r of result.results) {
- if (!r.success) {
- logger.error(`Plugin ${r.plugin.name} failed:`, {
- error: r.error,
- duration: r.duration
- });
- }
-}
-```
-
----
-
-## Related
+| Property | Type | Required | Description |
+| :--- | :--- | :--- | :--- |
+| **results** | `object[]` | ✅ | Startup results for each plugin |
+| **totalDuration** | `number` | ✅ | Total time taken for all plugins in milliseconds |
+| **allSuccessful** | `boolean` | ✅ | Whether all plugins started successfully |
+| **rolledBack** | `string[]` | optional | Names of plugins that were rolled back |
-- [Plugin](/docs/references/system/plugin) - Plugin protocol
-- [Plugin Lifecycle Events](/docs/references/system/plugin-lifecycle-events) - Lifecycle event schemas
-- [Manifest](/docs/references/system/manifest) - Plugin manifest specification
diff --git a/packages/spec/json-schema/system/BatchProgress.json b/packages/spec/json-schema/system/BatchProgress.json
new file mode 100644
index 000000000..c41c65486
--- /dev/null
+++ b/packages/spec/json-schema/system/BatchProgress.json
@@ -0,0 +1,72 @@
+{
+ "$ref": "#/definitions/BatchProgress",
+ "definitions": {
+ "BatchProgress": {
+ "type": "object",
+ "properties": {
+ "batchId": {
+ "type": "string",
+ "description": "Batch job identifier"
+ },
+ "total": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Total number of items"
+ },
+ "processed": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "description": "Items processed"
+ },
+ "succeeded": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "description": "Items succeeded"
+ },
+ "failed": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "description": "Items failed"
+ },
+ "percentage": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 100,
+ "description": "Progress percentage"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "running",
+ "completed",
+ "failed",
+ "cancelled"
+ ],
+ "description": "Batch status"
+ },
+ "startedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When batch started"
+ },
+ "completedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When batch completed"
+ }
+ },
+ "required": [
+ "batchId",
+ "total",
+ "percentage",
+ "status"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/BatchTask.json b/packages/spec/json-schema/system/BatchTask.json
new file mode 100644
index 000000000..98f82ec6d
--- /dev/null
+++ b/packages/spec/json-schema/system/BatchTask.json
@@ -0,0 +1,63 @@
+{
+ "$ref": "#/definitions/BatchTask",
+ "definitions": {
+ "BatchTask": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique batch job identifier"
+ },
+ "type": {
+ "type": "string",
+ "pattern": "^[a-z_][a-z0-9_]*$",
+ "description": "Task type (snake_case)"
+ },
+ "items": {
+ "type": "array",
+ "description": "Array of items to process"
+ },
+ "batchSize": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 100,
+ "description": "Number of items per batch"
+ },
+ "queue": {
+ "type": "string",
+ "default": "batch",
+ "description": "Queue for batch tasks"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ],
+ "default": "normal",
+ "description": "Batch task priority"
+ },
+ "parallel": {
+ "type": "boolean",
+ "default": true,
+ "description": "Process batches in parallel"
+ },
+ "stopOnError": {
+ "type": "boolean",
+ "default": false,
+ "description": "Stop batch if any item fails"
+ }
+ },
+ "required": [
+ "id",
+ "type",
+ "items"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/DeadLetterQueueEntry.json b/packages/spec/json-schema/system/DeadLetterQueueEntry.json
new file mode 100644
index 000000000..563a396b1
--- /dev/null
+++ b/packages/spec/json-schema/system/DeadLetterQueueEntry.json
@@ -0,0 +1,137 @@
+{
+ "$ref": "#/definitions/DeadLetterQueueEntry",
+ "definitions": {
+ "DeadLetterQueueEntry": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique entry identifier"
+ },
+ "event": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique event identifier"
+ },
+ "name": {
+ "type": "string",
+ "minLength": 3,
+ "pattern": "^[a-z][a-z0-9_.]*$",
+ "description": "Event name (lowercase with dots, e.g., user.created, order.paid)"
+ },
+ "payload": {
+ "description": "Event payload schema"
+ },
+ "metadata": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "type": "string",
+ "description": "Event source (e.g., plugin name, system component)"
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time",
+ "description": "ISO 8601 datetime when event was created"
+ },
+ "userId": {
+ "type": "string",
+ "description": "User who triggered the event"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "Tenant identifier for multi-tenant systems"
+ },
+ "correlationId": {
+ "type": "string",
+ "description": "Correlation ID for event tracing"
+ },
+ "causationId": {
+ "type": "string",
+ "description": "ID of the event that caused this event"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ],
+ "default": "normal",
+ "description": "Event priority"
+ }
+ },
+ "required": [
+ "source",
+ "timestamp"
+ ],
+ "additionalProperties": false,
+ "description": "Event metadata"
+ }
+ },
+ "required": [
+ "name",
+ "metadata"
+ ],
+ "additionalProperties": false,
+ "description": "Original event"
+ },
+ "error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Error message"
+ },
+ "stack": {
+ "type": "string",
+ "description": "Error stack trace"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ }
+ },
+ "required": [
+ "message"
+ ],
+ "additionalProperties": false,
+ "description": "Failure details"
+ },
+ "retries": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Number of retry attempts"
+ },
+ "firstFailedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When event first failed"
+ },
+ "lastFailedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When event last failed"
+ },
+ "failedHandler": {
+ "type": "string",
+ "description": "Handler ID that failed"
+ }
+ },
+ "required": [
+ "id",
+ "event",
+ "error",
+ "retries",
+ "firstFailedAt",
+ "lastFailedAt"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/Event.json b/packages/spec/json-schema/system/Event.json
index 4542af540..68b491cd2 100644
--- a/packages/spec/json-schema/system/Event.json
+++ b/packages/spec/json-schema/system/Event.json
@@ -4,6 +4,10 @@
"Event": {
"type": "object",
"properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique event identifier"
+ },
"name": {
"type": "string",
"minLength": 3,
@@ -32,6 +36,26 @@
"tenantId": {
"type": "string",
"description": "Tenant identifier for multi-tenant systems"
+ },
+ "correlationId": {
+ "type": "string",
+ "description": "Correlation ID for event tracing"
+ },
+ "causationId": {
+ "type": "string",
+ "description": "ID of the event that caused this event"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ],
+ "default": "normal",
+ "description": "Event priority"
}
},
"required": [
diff --git a/packages/spec/json-schema/system/EventBusConfig.json b/packages/spec/json-schema/system/EventBusConfig.json
new file mode 100644
index 000000000..700f5d692
--- /dev/null
+++ b/packages/spec/json-schema/system/EventBusConfig.json
@@ -0,0 +1,552 @@
+{
+ "$ref": "#/definitions/EventBusConfig",
+ "definitions": {
+ "EventBusConfig": {
+ "type": "object",
+ "properties": {
+ "persistence": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": false,
+ "description": "Enable event persistence"
+ },
+ "retention": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Days to retain persisted events"
+ },
+ "storage": {
+ "type": "string",
+ "enum": [
+ "database",
+ "file",
+ "s3",
+ "custom"
+ ],
+ "default": "database",
+ "description": "Storage backend for persisted events"
+ }
+ },
+ "required": [
+ "retention"
+ ],
+ "additionalProperties": false,
+ "description": "Event persistence configuration"
+ },
+ "queue": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "default": "events",
+ "description": "Event queue name"
+ },
+ "concurrency": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 10,
+ "description": "Max concurrent event handlers"
+ },
+ "retryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Max retries for failed events"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential",
+ "description": "Backoff strategy"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Maximum retry delay"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Default retry policy for events"
+ },
+ "deadLetterQueue": {
+ "type": "string",
+ "description": "Dead letter queue name for failed events"
+ },
+ "priorityEnabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Process events based on priority"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Event queue configuration"
+ },
+ "eventSourcing": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": false,
+ "description": "Enable event sourcing"
+ },
+ "snapshotInterval": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 100,
+ "description": "Create snapshot every N events"
+ },
+ "snapshotRetention": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 10,
+ "description": "Number of snapshots to retain"
+ },
+ "retention": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 365,
+ "description": "Days to retain events"
+ },
+ "aggregateTypes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Aggregate types to enable event sourcing for"
+ },
+ "storage": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "database",
+ "file",
+ "s3",
+ "eventstore"
+ ],
+ "default": "database",
+ "description": "Storage backend"
+ },
+ "options": {
+ "type": "object",
+ "additionalProperties": {},
+ "description": "Storage-specific options"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Event store configuration"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Event sourcing configuration"
+ },
+ "replay": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Enable event replay capability"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Event replay configuration"
+ },
+ "webhooks": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique webhook identifier"
+ },
+ "eventPattern": {
+ "type": "string",
+ "description": "Event name pattern (supports wildcards)"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "description": "Webhook endpoint URL"
+ },
+ "method": {
+ "type": "string",
+ "enum": [
+ "GET",
+ "POST",
+ "PUT",
+ "PATCH"
+ ],
+ "default": "POST",
+ "description": "HTTP method"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "HTTP headers"
+ },
+ "authentication": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "none",
+ "bearer",
+ "basic",
+ "api-key"
+ ],
+ "description": "Auth type"
+ },
+ "credentials": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Auth credentials"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false,
+ "description": "Authentication configuration"
+ },
+ "retryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Max retry attempts"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Max retry delay"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Retry policy"
+ },
+ "timeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 30000,
+ "description": "Request timeout in milliseconds"
+ },
+ "enabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Whether webhook is enabled"
+ }
+ },
+ "required": [
+ "eventPattern",
+ "url"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Webhook configurations"
+ },
+ "messageQueue": {
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "enum": [
+ "kafka",
+ "rabbitmq",
+ "aws-sqs",
+ "redis-pubsub",
+ "google-pubsub",
+ "azure-service-bus"
+ ],
+ "description": "Message queue provider"
+ },
+ "topic": {
+ "type": "string",
+ "description": "Topic or queue name"
+ },
+ "eventPattern": {
+ "type": "string",
+ "default": "*",
+ "description": "Event name pattern to publish (supports wildcards)"
+ },
+ "partitionKey": {
+ "type": "string",
+ "description": "JSON path for partition key (e.g., \"metadata.tenantId\")"
+ },
+ "format": {
+ "type": "string",
+ "enum": [
+ "json",
+ "avro",
+ "protobuf"
+ ],
+ "default": "json",
+ "description": "Message serialization format"
+ },
+ "includeMetadata": {
+ "type": "boolean",
+ "default": true,
+ "description": "Include event metadata in message"
+ },
+ "compression": {
+ "type": "string",
+ "enum": [
+ "none",
+ "gzip",
+ "snappy",
+ "lz4"
+ ],
+ "default": "none",
+ "description": "Message compression"
+ },
+ "batchSize": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1,
+ "description": "Batch size for publishing"
+ },
+ "flushIntervalMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Flush interval for batching"
+ }
+ },
+ "required": [
+ "provider",
+ "topic"
+ ],
+ "additionalProperties": false,
+ "description": "Message queue integration"
+ },
+ "realtime": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Enable real-time notifications"
+ },
+ "protocol": {
+ "type": "string",
+ "enum": [
+ "websocket",
+ "sse",
+ "long-polling"
+ ],
+ "default": "websocket",
+ "description": "Real-time protocol"
+ },
+ "eventPattern": {
+ "type": "string",
+ "default": "*",
+ "description": "Event pattern to broadcast"
+ },
+ "userFilter": {
+ "type": "boolean",
+ "default": true,
+ "description": "Filter events by user"
+ },
+ "tenantFilter": {
+ "type": "boolean",
+ "default": true,
+ "description": "Filter events by tenant"
+ },
+ "channels": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Channel name"
+ },
+ "eventPattern": {
+ "type": "string",
+ "description": "Event pattern for channel"
+ }
+ },
+ "required": [
+ "name",
+ "eventPattern"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Named channels for event broadcasting"
+ },
+ "rateLimit": {
+ "type": "object",
+ "properties": {
+ "maxEventsPerSecond": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Max events per second per client"
+ },
+ "windowMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Rate limit window"
+ }
+ },
+ "required": [
+ "maxEventsPerSecond"
+ ],
+ "additionalProperties": false,
+ "description": "Rate limiting configuration"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Real-time notification configuration"
+ },
+ "eventTypes": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 3,
+ "pattern": "^[a-z][a-z0-9_.]*$",
+ "description": "Event type name (lowercase with dots)"
+ },
+ "version": {
+ "type": "string",
+ "default": "1.0.0",
+ "description": "Event schema version"
+ },
+ "schema": {
+ "description": "JSON Schema for event payload validation"
+ },
+ "description": {
+ "type": "string",
+ "description": "Event type description"
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false,
+ "description": "Whether this event type is deprecated"
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Event type tags"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Event type definitions"
+ },
+ "handlers": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique handler identifier"
+ },
+ "eventName": {
+ "type": "string",
+ "description": "Name of event to handle (supports wildcards like user.*)"
+ },
+ "priority": {
+ "type": "integer",
+ "default": 0,
+ "description": "Execution priority (lower numbers execute first)"
+ },
+ "async": {
+ "type": "boolean",
+ "default": true,
+ "description": "Execute in background (true) or block (false)"
+ },
+ "retry": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Maximum retry attempts"
+ },
+ "backoffMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial backoff delay"
+ },
+ "backoffMultiplier": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 2,
+ "description": "Backoff multiplier"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Retry policy for failed handlers"
+ },
+ "timeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Handler timeout in milliseconds"
+ }
+ },
+ "required": [
+ "eventName"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Global event handlers"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventHandler.json b/packages/spec/json-schema/system/EventHandler.json
index 4af643941..77e1536c8 100644
--- a/packages/spec/json-schema/system/EventHandler.json
+++ b/packages/spec/json-schema/system/EventHandler.json
@@ -4,6 +4,10 @@
"EventHandler": {
"type": "object",
"properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique handler identifier"
+ },
"eventName": {
"type": "string",
"description": "Name of event to handle (supports wildcards like user.*)"
@@ -17,6 +21,36 @@
"type": "boolean",
"default": true,
"description": "Execute in background (true) or block (false)"
+ },
+ "retry": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Maximum retry attempts"
+ },
+ "backoffMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial backoff delay"
+ },
+ "backoffMultiplier": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 2,
+ "description": "Backoff multiplier"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Retry policy for failed handlers"
+ },
+ "timeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Handler timeout in milliseconds"
}
},
"required": [
diff --git a/packages/spec/json-schema/system/EventLogEntry.json b/packages/spec/json-schema/system/EventLogEntry.json
new file mode 100644
index 000000000..81885cfb7
--- /dev/null
+++ b/packages/spec/json-schema/system/EventLogEntry.json
@@ -0,0 +1,153 @@
+{
+ "$ref": "#/definitions/EventLogEntry",
+ "definitions": {
+ "EventLogEntry": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique log entry identifier"
+ },
+ "event": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique event identifier"
+ },
+ "name": {
+ "type": "string",
+ "minLength": 3,
+ "pattern": "^[a-z][a-z0-9_.]*$",
+ "description": "Event name (lowercase with dots, e.g., user.created, order.paid)"
+ },
+ "payload": {
+ "description": "Event payload schema"
+ },
+ "metadata": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "type": "string",
+ "description": "Event source (e.g., plugin name, system component)"
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time",
+ "description": "ISO 8601 datetime when event was created"
+ },
+ "userId": {
+ "type": "string",
+ "description": "User who triggered the event"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "Tenant identifier for multi-tenant systems"
+ },
+ "correlationId": {
+ "type": "string",
+ "description": "Correlation ID for event tracing"
+ },
+ "causationId": {
+ "type": "string",
+ "description": "ID of the event that caused this event"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ],
+ "default": "normal",
+ "description": "Event priority"
+ }
+ },
+ "required": [
+ "source",
+ "timestamp"
+ ],
+ "additionalProperties": false,
+ "description": "Event metadata"
+ }
+ },
+ "required": [
+ "name",
+ "metadata"
+ ],
+ "additionalProperties": false,
+ "description": "The event"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "processing",
+ "completed",
+ "failed"
+ ],
+ "description": "Processing status"
+ },
+ "handlersExecuted": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "handlerId": {
+ "type": "string",
+ "description": "Handler identifier"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "success",
+ "failed",
+ "timeout"
+ ],
+ "description": "Handler execution status"
+ },
+ "durationMs": {
+ "type": "integer",
+ "description": "Execution duration"
+ },
+ "error": {
+ "type": "string",
+ "description": "Error message if failed"
+ }
+ },
+ "required": [
+ "handlerId",
+ "status"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Handlers that processed this event"
+ },
+ "receivedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When event was received"
+ },
+ "processedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When event was processed"
+ },
+ "totalDurationMs": {
+ "type": "integer",
+ "description": "Total processing time"
+ }
+ },
+ "required": [
+ "id",
+ "event",
+ "status",
+ "receivedAt"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventMessageQueueConfig.json b/packages/spec/json-schema/system/EventMessageQueueConfig.json
new file mode 100644
index 000000000..662855a1a
--- /dev/null
+++ b/packages/spec/json-schema/system/EventMessageQueueConfig.json
@@ -0,0 +1,79 @@
+{
+ "$ref": "#/definitions/EventMessageQueueConfig",
+ "definitions": {
+ "EventMessageQueueConfig": {
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "enum": [
+ "kafka",
+ "rabbitmq",
+ "aws-sqs",
+ "redis-pubsub",
+ "google-pubsub",
+ "azure-service-bus"
+ ],
+ "description": "Message queue provider"
+ },
+ "topic": {
+ "type": "string",
+ "description": "Topic or queue name"
+ },
+ "eventPattern": {
+ "type": "string",
+ "default": "*",
+ "description": "Event name pattern to publish (supports wildcards)"
+ },
+ "partitionKey": {
+ "type": "string",
+ "description": "JSON path for partition key (e.g., \"metadata.tenantId\")"
+ },
+ "format": {
+ "type": "string",
+ "enum": [
+ "json",
+ "avro",
+ "protobuf"
+ ],
+ "default": "json",
+ "description": "Message serialization format"
+ },
+ "includeMetadata": {
+ "type": "boolean",
+ "default": true,
+ "description": "Include event metadata in message"
+ },
+ "compression": {
+ "type": "string",
+ "enum": [
+ "none",
+ "gzip",
+ "snappy",
+ "lz4"
+ ],
+ "default": "none",
+ "description": "Message compression"
+ },
+ "batchSize": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1,
+ "description": "Batch size for publishing"
+ },
+ "flushIntervalMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Flush interval for batching"
+ }
+ },
+ "required": [
+ "provider",
+ "topic"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventMetadata.json b/packages/spec/json-schema/system/EventMetadata.json
index c4bfc6d96..0eeb92963 100644
--- a/packages/spec/json-schema/system/EventMetadata.json
+++ b/packages/spec/json-schema/system/EventMetadata.json
@@ -20,6 +20,26 @@
"tenantId": {
"type": "string",
"description": "Tenant identifier for multi-tenant systems"
+ },
+ "correlationId": {
+ "type": "string",
+ "description": "Correlation ID for event tracing"
+ },
+ "causationId": {
+ "type": "string",
+ "description": "ID of the event that caused this event"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ],
+ "default": "normal",
+ "description": "Event priority"
}
},
"required": [
diff --git a/packages/spec/json-schema/system/EventPersistence.json b/packages/spec/json-schema/system/EventPersistence.json
index 1b2c357fd..416b09cb5 100644
--- a/packages/spec/json-schema/system/EventPersistence.json
+++ b/packages/spec/json-schema/system/EventPersistence.json
@@ -13,6 +13,17 @@
"type": "integer",
"exclusiveMinimum": 0,
"description": "Days to retain persisted events"
+ },
+ "storage": {
+ "type": "string",
+ "enum": [
+ "database",
+ "file",
+ "s3",
+ "custom"
+ ],
+ "default": "database",
+ "description": "Storage backend for persisted events"
}
},
"required": [
diff --git a/packages/spec/json-schema/system/EventPriority.json b/packages/spec/json-schema/system/EventPriority.json
new file mode 100644
index 000000000..4779582c1
--- /dev/null
+++ b/packages/spec/json-schema/system/EventPriority.json
@@ -0,0 +1,16 @@
+{
+ "$ref": "#/definitions/EventPriority",
+ "definitions": {
+ "EventPriority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ]
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventQueueConfig.json b/packages/spec/json-schema/system/EventQueueConfig.json
new file mode 100644
index 000000000..e80718062
--- /dev/null
+++ b/packages/spec/json-schema/system/EventQueueConfig.json
@@ -0,0 +1,67 @@
+{
+ "$ref": "#/definitions/EventQueueConfig",
+ "definitions": {
+ "EventQueueConfig": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "default": "events",
+ "description": "Event queue name"
+ },
+ "concurrency": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 10,
+ "description": "Max concurrent event handlers"
+ },
+ "retryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Max retries for failed events"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential",
+ "description": "Backoff strategy"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Maximum retry delay"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Default retry policy for events"
+ },
+ "deadLetterQueue": {
+ "type": "string",
+ "description": "Dead letter queue name for failed events"
+ },
+ "priorityEnabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Process events based on priority"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventReplayConfig.json b/packages/spec/json-schema/system/EventReplayConfig.json
new file mode 100644
index 000000000..4f1c47c7b
--- /dev/null
+++ b/packages/spec/json-schema/system/EventReplayConfig.json
@@ -0,0 +1,50 @@
+{
+ "$ref": "#/definitions/EventReplayConfig",
+ "definitions": {
+ "EventReplayConfig": {
+ "type": "object",
+ "properties": {
+ "fromTimestamp": {
+ "type": "string",
+ "format": "date-time",
+ "description": "Start timestamp for replay (ISO 8601)"
+ },
+ "toTimestamp": {
+ "type": "string",
+ "format": "date-time",
+ "description": "End timestamp for replay (ISO 8601)"
+ },
+ "eventTypes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Event types to replay (empty = all)"
+ },
+ "filters": {
+ "type": "object",
+ "additionalProperties": {},
+ "description": "Additional filters for event selection"
+ },
+ "speed": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1,
+ "description": "Replay speed multiplier (1 = real-time)"
+ },
+ "targetHandlers": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Handler IDs to execute (empty = all)"
+ }
+ },
+ "required": [
+ "fromTimestamp"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventSourcingConfig.json b/packages/spec/json-schema/system/EventSourcingConfig.json
new file mode 100644
index 000000000..1d4b45f71
--- /dev/null
+++ b/packages/spec/json-schema/system/EventSourcingConfig.json
@@ -0,0 +1,65 @@
+{
+ "$ref": "#/definitions/EventSourcingConfig",
+ "definitions": {
+ "EventSourcingConfig": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": false,
+ "description": "Enable event sourcing"
+ },
+ "snapshotInterval": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 100,
+ "description": "Create snapshot every N events"
+ },
+ "snapshotRetention": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 10,
+ "description": "Number of snapshots to retain"
+ },
+ "retention": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 365,
+ "description": "Days to retain events"
+ },
+ "aggregateTypes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Aggregate types to enable event sourcing for"
+ },
+ "storage": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "database",
+ "file",
+ "s3",
+ "eventstore"
+ ],
+ "default": "database",
+ "description": "Storage backend"
+ },
+ "options": {
+ "type": "object",
+ "additionalProperties": {},
+ "description": "Storage-specific options"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Event store configuration"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventTypeDefinition.json b/packages/spec/json-schema/system/EventTypeDefinition.json
new file mode 100644
index 000000000..a90d6ab44
--- /dev/null
+++ b/packages/spec/json-schema/system/EventTypeDefinition.json
@@ -0,0 +1,45 @@
+{
+ "$ref": "#/definitions/EventTypeDefinition",
+ "definitions": {
+ "EventTypeDefinition": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 3,
+ "pattern": "^[a-z][a-z0-9_.]*$",
+ "description": "Event type name (lowercase with dots)"
+ },
+ "version": {
+ "type": "string",
+ "default": "1.0.0",
+ "description": "Event schema version"
+ },
+ "schema": {
+ "description": "JSON Schema for event payload validation"
+ },
+ "description": {
+ "type": "string",
+ "description": "Event type description"
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false,
+ "description": "Whether this event type is deprecated"
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Event type tags"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/EventWebhookConfig.json b/packages/spec/json-schema/system/EventWebhookConfig.json
new file mode 100644
index 000000000..36924ede0
--- /dev/null
+++ b/packages/spec/json-schema/system/EventWebhookConfig.json
@@ -0,0 +1,119 @@
+{
+ "$ref": "#/definitions/EventWebhookConfig",
+ "definitions": {
+ "EventWebhookConfig": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique webhook identifier"
+ },
+ "eventPattern": {
+ "type": "string",
+ "description": "Event name pattern (supports wildcards)"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "description": "Webhook endpoint URL"
+ },
+ "method": {
+ "type": "string",
+ "enum": [
+ "GET",
+ "POST",
+ "PUT",
+ "PATCH"
+ ],
+ "default": "POST",
+ "description": "HTTP method"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "HTTP headers"
+ },
+ "authentication": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "none",
+ "bearer",
+ "basic",
+ "api-key"
+ ],
+ "description": "Auth type"
+ },
+ "credentials": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Auth credentials"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false,
+ "description": "Authentication configuration"
+ },
+ "retryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Max retry attempts"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Max retry delay"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Retry policy"
+ },
+ "timeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 30000,
+ "description": "Request timeout in milliseconds"
+ },
+ "enabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Whether webhook is enabled"
+ }
+ },
+ "required": [
+ "eventPattern",
+ "url"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/QueueConfig.json b/packages/spec/json-schema/system/QueueConfig.json
new file mode 100644
index 000000000..3943f8af5
--- /dev/null
+++ b/packages/spec/json-schema/system/QueueConfig.json
@@ -0,0 +1,133 @@
+{
+ "$ref": "#/definitions/QueueConfig",
+ "definitions": {
+ "QueueConfig": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Queue name (snake_case)"
+ },
+ "concurrency": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 5,
+ "description": "Max concurrent task executions"
+ },
+ "rateLimit": {
+ "type": "object",
+ "properties": {
+ "max": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Maximum tasks per duration"
+ },
+ "duration": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Duration in milliseconds"
+ }
+ },
+ "required": [
+ "max",
+ "duration"
+ ],
+ "additionalProperties": false,
+ "description": "Rate limit configuration"
+ },
+ "defaultRetryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Maximum retry attempts"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential",
+ "description": "Backoff strategy between retries"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay in milliseconds"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Maximum retry delay in milliseconds"
+ },
+ "backoffMultiplier": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 2,
+ "description": "Multiplier for exponential backoff"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Default retry policy for tasks"
+ },
+ "deadLetterQueue": {
+ "type": "string",
+ "description": "Dead letter queue name"
+ },
+ "priority": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "description": "Queue priority (lower = higher priority)"
+ },
+ "autoScale": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": false,
+ "description": "Enable auto-scaling"
+ },
+ "minWorkers": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1,
+ "description": "Minimum workers"
+ },
+ "maxWorkers": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 10,
+ "description": "Maximum workers"
+ },
+ "scaleUpThreshold": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 100,
+ "description": "Queue size to scale up"
+ },
+ "scaleDownThreshold": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 10,
+ "description": "Queue size to scale down"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Auto-scaling configuration"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/RealTimeNotificationConfig.json b/packages/spec/json-schema/system/RealTimeNotificationConfig.json
new file mode 100644
index 000000000..9b72239d1
--- /dev/null
+++ b/packages/spec/json-schema/system/RealTimeNotificationConfig.json
@@ -0,0 +1,85 @@
+{
+ "$ref": "#/definitions/RealTimeNotificationConfig",
+ "definitions": {
+ "RealTimeNotificationConfig": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Enable real-time notifications"
+ },
+ "protocol": {
+ "type": "string",
+ "enum": [
+ "websocket",
+ "sse",
+ "long-polling"
+ ],
+ "default": "websocket",
+ "description": "Real-time protocol"
+ },
+ "eventPattern": {
+ "type": "string",
+ "default": "*",
+ "description": "Event pattern to broadcast"
+ },
+ "userFilter": {
+ "type": "boolean",
+ "default": true,
+ "description": "Filter events by user"
+ },
+ "tenantFilter": {
+ "type": "boolean",
+ "default": true,
+ "description": "Filter events by tenant"
+ },
+ "channels": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Channel name"
+ },
+ "eventPattern": {
+ "type": "string",
+ "description": "Event pattern for channel"
+ }
+ },
+ "required": [
+ "name",
+ "eventPattern"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Named channels for event broadcasting"
+ },
+ "rateLimit": {
+ "type": "object",
+ "properties": {
+ "maxEventsPerSecond": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Max events per second per client"
+ },
+ "windowMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Rate limit window"
+ }
+ },
+ "required": [
+ "maxEventsPerSecond"
+ ],
+ "additionalProperties": false,
+ "description": "Rate limiting configuration"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/Task.json b/packages/spec/json-schema/system/Task.json
new file mode 100644
index 000000000..af048cccc
--- /dev/null
+++ b/packages/spec/json-schema/system/Task.json
@@ -0,0 +1,145 @@
+{
+ "$ref": "#/definitions/Task",
+ "definitions": {
+ "Task": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique task identifier"
+ },
+ "type": {
+ "type": "string",
+ "pattern": "^[a-z_][a-z0-9_]*$",
+ "description": "Task type (snake_case)"
+ },
+ "payload": {
+ "description": "Task payload data"
+ },
+ "queue": {
+ "type": "string",
+ "default": "default",
+ "description": "Queue name"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ],
+ "default": "normal",
+ "description": "Task priority level"
+ },
+ "retryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Maximum retry attempts"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential",
+ "description": "Backoff strategy between retries"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay in milliseconds"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Maximum retry delay in milliseconds"
+ },
+ "backoffMultiplier": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 2,
+ "description": "Multiplier for exponential backoff"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Retry policy configuration"
+ },
+ "timeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Task timeout in milliseconds"
+ },
+ "scheduledAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "ISO 8601 datetime to execute task"
+ },
+ "attempts": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "description": "Number of execution attempts"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "queued",
+ "processing",
+ "completed",
+ "failed",
+ "cancelled",
+ "timeout",
+ "dead"
+ ],
+ "default": "pending",
+ "description": "Current task status"
+ },
+ "metadata": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When task was created"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "Last update time"
+ },
+ "createdBy": {
+ "type": "string",
+ "description": "User who created task"
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Task tags for filtering"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Task metadata"
+ }
+ },
+ "required": [
+ "id",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/TaskExecutionResult.json b/packages/spec/json-schema/system/TaskExecutionResult.json
new file mode 100644
index 000000000..1931cd288
--- /dev/null
+++ b/packages/spec/json-schema/system/TaskExecutionResult.json
@@ -0,0 +1,85 @@
+{
+ "$ref": "#/definitions/TaskExecutionResult",
+ "definitions": {
+ "TaskExecutionResult": {
+ "type": "object",
+ "properties": {
+ "taskId": {
+ "type": "string",
+ "description": "Task identifier"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "queued",
+ "processing",
+ "completed",
+ "failed",
+ "cancelled",
+ "timeout",
+ "dead"
+ ],
+ "description": "Execution status"
+ },
+ "result": {
+ "description": "Execution result data"
+ },
+ "error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Error message"
+ },
+ "stack": {
+ "type": "string",
+ "description": "Error stack trace"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ }
+ },
+ "required": [
+ "message"
+ ],
+ "additionalProperties": false,
+ "description": "Error details if failed"
+ },
+ "durationMs": {
+ "type": "integer",
+ "description": "Execution duration in milliseconds"
+ },
+ "startedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When execution started"
+ },
+ "completedAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When execution completed"
+ },
+ "attempt": {
+ "type": "integer",
+ "minimum": 1,
+ "description": "Attempt number (1-indexed)"
+ },
+ "willRetry": {
+ "type": "boolean",
+ "description": "Whether task will be retried"
+ }
+ },
+ "required": [
+ "taskId",
+ "status",
+ "startedAt",
+ "attempt",
+ "willRetry"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/TaskPriority.json b/packages/spec/json-schema/system/TaskPriority.json
new file mode 100644
index 000000000..af5f4d8a5
--- /dev/null
+++ b/packages/spec/json-schema/system/TaskPriority.json
@@ -0,0 +1,16 @@
+{
+ "$ref": "#/definitions/TaskPriority",
+ "definitions": {
+ "TaskPriority": {
+ "type": "string",
+ "enum": [
+ "critical",
+ "high",
+ "normal",
+ "low",
+ "background"
+ ]
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/TaskRetryPolicy.json b/packages/spec/json-schema/system/TaskRetryPolicy.json
new file mode 100644
index 000000000..e38b1d11c
--- /dev/null
+++ b/packages/spec/json-schema/system/TaskRetryPolicy.json
@@ -0,0 +1,46 @@
+{
+ "$ref": "#/definitions/TaskRetryPolicy",
+ "definitions": {
+ "TaskRetryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Maximum retry attempts"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential",
+ "description": "Backoff strategy between retries"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay in milliseconds"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Maximum retry delay in milliseconds"
+ },
+ "backoffMultiplier": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 2,
+ "description": "Multiplier for exponential backoff"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/TaskStatus.json b/packages/spec/json-schema/system/TaskStatus.json
new file mode 100644
index 000000000..69356ead3
--- /dev/null
+++ b/packages/spec/json-schema/system/TaskStatus.json
@@ -0,0 +1,19 @@
+{
+ "$ref": "#/definitions/TaskStatus",
+ "definitions": {
+ "TaskStatus": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "queued",
+ "processing",
+ "completed",
+ "failed",
+ "cancelled",
+ "timeout",
+ "dead"
+ ]
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/WorkerConfig.json b/packages/spec/json-schema/system/WorkerConfig.json
new file mode 100644
index 000000000..f32e01765
--- /dev/null
+++ b/packages/spec/json-schema/system/WorkerConfig.json
@@ -0,0 +1,188 @@
+{
+ "$ref": "#/definitions/WorkerConfig",
+ "definitions": {
+ "WorkerConfig": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Worker name"
+ },
+ "queues": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "description": "Queue names to process"
+ },
+ "queueConfigs": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Queue name (snake_case)"
+ },
+ "concurrency": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 5,
+ "description": "Max concurrent task executions"
+ },
+ "rateLimit": {
+ "type": "object",
+ "properties": {
+ "max": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Maximum tasks per duration"
+ },
+ "duration": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Duration in milliseconds"
+ }
+ },
+ "required": [
+ "max",
+ "duration"
+ ],
+ "additionalProperties": false,
+ "description": "Rate limit configuration"
+ },
+ "defaultRetryPolicy": {
+ "type": "object",
+ "properties": {
+ "maxRetries": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 3,
+ "description": "Maximum retry attempts"
+ },
+ "backoffStrategy": {
+ "type": "string",
+ "enum": [
+ "fixed",
+ "linear",
+ "exponential"
+ ],
+ "default": "exponential",
+ "description": "Backoff strategy between retries"
+ },
+ "initialDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Initial retry delay in milliseconds"
+ },
+ "maxDelayMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 60000,
+ "description": "Maximum retry delay in milliseconds"
+ },
+ "backoffMultiplier": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 2,
+ "description": "Multiplier for exponential backoff"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Default retry policy for tasks"
+ },
+ "deadLetterQueue": {
+ "type": "string",
+ "description": "Dead letter queue name"
+ },
+ "priority": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "description": "Queue priority (lower = higher priority)"
+ },
+ "autoScale": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": false,
+ "description": "Enable auto-scaling"
+ },
+ "minWorkers": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1,
+ "description": "Minimum workers"
+ },
+ "maxWorkers": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 10,
+ "description": "Maximum workers"
+ },
+ "scaleUpThreshold": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 100,
+ "description": "Queue size to scale up"
+ },
+ "scaleDownThreshold": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 10,
+ "description": "Queue size to scale down"
+ }
+ },
+ "additionalProperties": false,
+ "description": "Auto-scaling configuration"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Queue configurations"
+ },
+ "pollIntervalMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 1000,
+ "description": "Queue polling interval in milliseconds"
+ },
+ "visibilityTimeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 30000,
+ "description": "How long a task is invisible after being claimed"
+ },
+ "defaultTimeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 300000,
+ "description": "Default task timeout in milliseconds"
+ },
+ "shutdownTimeoutMs": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "default": 30000,
+ "description": "Graceful shutdown timeout in milliseconds"
+ },
+ "handlers": {
+ "type": "object",
+ "additionalProperties": true,
+ "description": "Task type handlers"
+ }
+ },
+ "required": [
+ "name",
+ "queues"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
diff --git a/packages/spec/json-schema/system/WorkerStats.json b/packages/spec/json-schema/system/WorkerStats.json
new file mode 100644
index 000000000..e284e39db
--- /dev/null
+++ b/packages/spec/json-schema/system/WorkerStats.json
@@ -0,0 +1,90 @@
+{
+ "$ref": "#/definitions/WorkerStats",
+ "definitions": {
+ "WorkerStats": {
+ "type": "object",
+ "properties": {
+ "workerName": {
+ "type": "string",
+ "description": "Worker name"
+ },
+ "totalProcessed": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Total tasks processed"
+ },
+ "succeeded": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Successful tasks"
+ },
+ "failed": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Failed tasks"
+ },
+ "active": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Currently active tasks"
+ },
+ "avgExecutionMs": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Average execution time in milliseconds"
+ },
+ "uptimeMs": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Worker uptime in milliseconds"
+ },
+ "queues": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "pending": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Pending tasks"
+ },
+ "active": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Active tasks"
+ },
+ "completed": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Completed tasks"
+ },
+ "failed": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Failed tasks"
+ }
+ },
+ "required": [
+ "pending",
+ "active",
+ "completed",
+ "failed"
+ ],
+ "additionalProperties": false
+ },
+ "description": "Per-queue statistics"
+ }
+ },
+ "required": [
+ "workerName",
+ "totalProcessed",
+ "succeeded",
+ "failed",
+ "active",
+ "uptimeMs"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+}
\ No newline at end of file
From fb41cc09747295ce2e99f2b8f64b74bd14922f5c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 31 Jan 2026 10:19:23 +0000
Subject: [PATCH 3/4] Add changeset for patch release 0.7.2
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
---
.changeset/patch-release.md | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 .changeset/patch-release.md
diff --git a/.changeset/patch-release.md b/.changeset/patch-release.md
new file mode 100644
index 000000000..f10df795e
--- /dev/null
+++ b/.changeset/patch-release.md
@@ -0,0 +1,16 @@
+---
+"@objectstack/spec": patch
+"@objectstack/core": patch
+"@objectstack/types": patch
+"@objectstack/objectql": patch
+"@objectstack/runtime": patch
+"@objectstack/client": patch
+"@objectstack/client-react": patch
+"@objectstack/driver-memory": patch
+"@objectstack/plugin-hono-server": patch
+"@objectstack/plugin-msw": patch
+"@objectstack/cli": patch
+"@objectstack/ai-bridge": patch
+---
+
+Patch release: Updated documentation and JSON schemas
From f77c036988a98eacaca03a6d000fe951efb9f1f8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 31 Jan 2026 10:19:45 +0000
Subject: [PATCH 4/4] Update CHANGELOG for version 0.7.2 patch release
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
---
CHANGELOG.md | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f97a8523..c2ee24421 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Security
+## [0.7.2] - 2026-01-31
+
+### Changed
+- Updated system protocol JSON schemas (events, worker, metadata-loader)
+- Enhanced documentation structure for system protocols
+- Generated comprehensive JSON schema documentation
+
## [0.7.1] - 2026-01-31
### Changed
@@ -185,7 +192,8 @@ Mark breaking changes clearly:
---
-[Unreleased]: https://github.com/objectstack-ai/spec/compare/v0.7.1...HEAD
+[Unreleased]: https://github.com/objectstack-ai/spec/compare/v0.7.2...HEAD
+[0.7.2]: https://github.com/objectstack-ai/spec/compare/v0.7.1...v0.7.2
[0.7.1]: https://github.com/objectstack-ai/spec/compare/v0.6.1...v0.7.1
[0.6.1]: https://github.com/objectstack-ai/spec/compare/v0.4.1...v0.6.1
[0.4.1]: https://github.com/objectstack-ai/spec/compare/v0.4.0...v0.4.1