Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/NEXT_STEP.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@

**Checklist:**

- [ ] Create deployment protocol with packages, validation, rollback, and history
- [x] Create deployment protocol with packages, validation, rollback, and history — ✅ `system/deploy-bundle.zod.ts` (DeployBundle, MigrationPlan, DeployDiff, DeployValidationResult)
- [ ] Create sandbox management with metadata/data cloning and PII masking
- [ ] Create fiscal year and business calendar protocol
- [ ] Enhance audit trail with structured query protocol
Expand Down Expand Up @@ -147,7 +147,7 @@
**Checklist:**

- [ ] Create IAuditService contract for audit trail querying and management
- [ ] Create IDeploymentService contract for package deployment and rollback
- [x] Create IDeploymentService contract for package deployment and rollback — ✅ `contracts/deploy-pipeline-service.ts` (IDeployPipelineService) + `contracts/schema-diff-service.ts` (ISchemaDiffService)
- [ ] Create ISLAService contract for SLA evaluation and escalation
- [ ] Create ISchedulerService contract for scheduled job management
- [ ] Create IDocumentService contract for document generation
Expand Down
64 changes: 64 additions & 0 deletions packages/spec/src/contracts/app-lifecycle-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

/**
* IAppLifecycleService - App Marketplace Installation Contract
*
* Defines the interface for installing, upgrading, and uninstalling
* marketplace apps into tenant databases.
*
* An app installation:
* 1. Checks compatibility with the tenant environment
* 2. Applies schema changes (creates tables, indexes)
* 3. Seeds initial data
* 4. Registers metadata (objects, views, flows) in the tenant registry
*/

import type { AppManifest, AppCompatibilityCheck, AppInstallResult } from '../system/app-install.zod.js';

// ==========================================================================
// Service Interface
// ==========================================================================

export interface IAppLifecycleService {
/**
* Check whether an app is compatible with a tenant's environment.
* Validates kernel version, existing objects, dependencies, and quotas.
*
* @param tenantId - Target tenant
* @param manifest - App manifest to check
* @returns Compatibility check result
*/
checkCompatibility(tenantId: string, manifest: AppManifest): Promise<AppCompatibilityCheck>;

/**
* Install an app into a tenant's database.
* Applies schema changes, seeds data, and registers metadata.
*
* @param tenantId - Target tenant
* @param manifest - App manifest
* @param config - Optional configuration overrides
* @returns Installation result
*/
installApp(tenantId: string, manifest: AppManifest, config?: Record<string, unknown>): Promise<AppInstallResult>;

/**
* Uninstall an app from a tenant's database.
* Removes metadata registrations. Optionally drops tables.
*
* @param tenantId - Target tenant
* @param appId - App to uninstall
* @param dropTables - Whether to drop database tables (default: false)
* @returns Whether the uninstallation succeeded
*/
uninstallApp(tenantId: string, appId: string, dropTables?: boolean): Promise<{ success: boolean }>;

/**
* Upgrade an installed app to a new version.
* Applies schema migrations and updates metadata.
*
* @param tenantId - Target tenant
* @param manifest - New version app manifest
* @returns Installation result for the upgrade
*/
upgradeApp(tenantId: string, manifest: AppManifest): Promise<AppInstallResult>;
}
87 changes: 87 additions & 0 deletions packages/spec/src/contracts/deploy-pipeline-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

/**
* IDeployPipelineService - Metadata-Driven Deployment Pipeline Contract
*
* Orchestrates the complete deployment lifecycle:
* 1. Validate bundle (Zod schema validation)
* 2. Plan deployment (introspect → diff → generate migrations)
* 3. Execute deployment (apply migrations → register metadata)
* 4. Rollback on failure
*
* Target: 2-5 second deployments for schema changes.
* No Docker builds, no CI/CD pipelines — just metadata push.
*/

import type {
DeployBundle,
DeployValidationResult,
MigrationPlan,
DeployStatus,
} from '../system/deploy-bundle.zod.js';

// ==========================================================================
// Types
// ==========================================================================

/**
* Deployment execution result.
*/
export interface DeployExecutionResult {
/** Unique deployment identifier */
deploymentId: string;
/** Final deployment status */
status: DeployStatus;
/** Total execution duration in milliseconds */
durationMs: number;
/** Number of DDL statements executed */
statementsExecuted: number;
/** Error message if deployment failed */
error?: string;
/** Timestamp of deployment completion (ISO 8601) */
completedAt: string;
}

// ==========================================================================
// Service Interface
// ==========================================================================

export interface IDeployPipelineService {
/**
* Validate a deploy bundle against Zod schemas.
* Checks object definitions, view configs, flow definitions, and permissions.
*
* @param bundle - Deploy bundle to validate
* @returns Validation result with issues list
*/
validateBundle(bundle: DeployBundle): DeployValidationResult;

/**
* Plan a deployment by introspecting the current schema and generating
* a migration plan for the diff.
*
* @param tenantId - Target tenant
* @param bundle - Deploy bundle to plan for
* @returns Migration plan with ordered DDL statements
*/
planDeployment(tenantId: string, bundle: DeployBundle): Promise<MigrationPlan>;

/**
* Execute a deployment plan against a tenant's database.
* Applies DDL statements and registers metadata changes.
*
* @param tenantId - Target tenant
* @param plan - Migration plan to execute
* @returns Execution result with deployment ID and status
*/
executeDeployment(tenantId: string, plan: MigrationPlan): Promise<DeployExecutionResult>;

/**
* Rollback a previous deployment.
* Executes reverse DDL statements and restores previous metadata state.
*
* @param tenantId - Target tenant
* @param deploymentId - Deployment to rollback
*/
rollbackDeployment(tenantId: string, deploymentId: string): Promise<void>;
}
8 changes: 8 additions & 0 deletions packages/spec/src/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,11 @@ export * from './workflow-service.js';
export * from './feed-service.js';
export * from './export-service.js';
export * from './package-service.js';

// Provisioning & Deployment
export * from './turso-platform.js';
export * from './provisioning-service.js';
export * from './schema-diff-service.js';
export * from './deploy-pipeline-service.js';
export * from './tenant-router.js';
export * from './app-lifecycle-service.js';
82 changes: 82 additions & 0 deletions packages/spec/src/contracts/provisioning-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

/**
* IProvisioningService - Tenant Provisioning Service Contract
*
* Defines the interface for the "Register → Instant ObjectOS" provisioning pipeline.
* Manages the complete tenant lifecycle: create → active → suspend → resume → destroy.
*
* The provisioning service orchestrates:
* 1. Turso database creation via ITursoPlatformService
* 2. Schema synchronization via ISchemaDiffService
* 3. Seed data population
* 4. Tenant record registration in the control plane
*
* Follows Dependency Inversion Principle - consumers depend on this interface,
* not on concrete provisioning implementations.
*/

import type {
TenantProvisioningRequest,
TenantProvisioningResult,
TenantProvisioningStatus,
TenantPlan,
} from '../system/provisioning.zod.js';

// ==========================================================================
// Service Interface
// ==========================================================================

export interface IProvisioningService {
/**
* Provision a new tenant with an isolated database.
* Creates the Turso database, syncs schema, seeds data, and registers the tenant.
* Target latency: 2-5 seconds.
*
* @param request - Provisioning request with org, plan, and region
* @returns Provisioning result with tenant ID, connection URL, and step statuses
*/
provisionTenant(request: TenantProvisioningRequest): Promise<TenantProvisioningResult>;

/**
* Suspend a tenant (e.g., unpaid, policy violation).
* Revokes tokens and sets the database to read-only mode.
*
* @param tenantId - Tenant to suspend
*/
suspendTenant(tenantId: string): Promise<void>;

/**
* Resume a previously suspended tenant.
* Restores full read-write access and issues new tokens.
*
* @param tenantId - Tenant to resume
*/
resumeTenant(tenantId: string): Promise<void>;

/**
* Permanently destroy a tenant and its database.
* Optionally creates a final backup before deletion.
* Respects the grace period defined in lifecycle hooks.
*
* @param tenantId - Tenant to destroy
*/
destroyTenant(tenantId: string): Promise<void>;

/**
* Get the current provisioning status of a tenant.
*
* @param tenantId - Tenant to query
* @returns Current provisioning status
*/
getTenantStatus(tenantId: string): Promise<TenantProvisioningStatus>;

/**
* Migrate a tenant to a different subscription plan.
* Updates quotas and resource limits accordingly.
*
* @param tenantId - Tenant to migrate
* @param newPlan - Target subscription plan
*/
migrateTenantPlan(tenantId: string, newPlan: TenantPlan): Promise<void>;
}
132 changes: 132 additions & 0 deletions packages/spec/src/contracts/schema-diff-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

/**
* ISchemaDiffService - Schema Introspection & Diff Contract
*
* Compares the desired metadata state (ObjectStack object definitions)
* against the current database schema and generates DDL migration plans.
*
* Pipeline: Introspect Current → Diff vs Desired → Generate Migrations → Apply
*
* This service is dialect-aware and generates DDL appropriate for the
* target database (PostgreSQL, SQLite/Turso, MySQL, etc.).
*/

import type { DeployDiff, MigrationPlan } from '../system/deploy-bundle.zod.js';
import type { SQLDialect } from '../data/driver-sql.zod.js';

// ==========================================================================
// Types
// ==========================================================================

/**
* Introspected schema representation of the current database state.
*/
export interface IntrospectedSchema {
/** Object/table names and their column definitions */
tables: Record<string, IntrospectedTable>;
/** Database dialect */
dialect: string;
/** Introspection timestamp (ISO 8601) */
introspectedAt: string;
}

/**
* Introspected table (current database state).
*/
export interface IntrospectedTable {
/** Table name */
name: string;
/** Column definitions */
columns: IntrospectedColumn[];
/** Index definitions */
indexes: IntrospectedIndex[];
}

/**
* Introspected column definition.
*/
export interface IntrospectedColumn {
/** Column name */
name: string;
/** SQL data type */
type: string;
/** Whether the column is nullable */
nullable: boolean;
/** Default value expression */
defaultValue?: string;
/** Whether this column is a primary key */
primaryKey: boolean;
}

/**
* Introspected index definition.
*/
export interface IntrospectedIndex {
/** Index name */
name: string;
/** Columns included in the index */
columns: string[];
/** Whether the index enforces uniqueness */
unique: boolean;
}

/**
* Migration apply result.
*/
export interface MigrationApplyResult {
/** Whether all migrations applied successfully */
success: boolean;
/** Number of statements executed */
statementsExecuted: number;
/** Total execution duration in milliseconds */
durationMs: number;
/** Error message if a statement failed */
error?: string;
/** Index of the failed statement (if any) */
failedAtIndex?: number;
}

// ==========================================================================
// Service Interface
// ==========================================================================

export interface ISchemaDiffService {
/**
* Introspect the current database schema.
* Reads table definitions, columns, indexes from the live database.
*
* @param driver - Data driver to introspect
* @returns Current schema representation
*/
introspect(driver: unknown): Promise<IntrospectedSchema>;

/**
* Compute the diff between current schema and desired object definitions.
*
* @param current - Introspected current schema
* @param desired - Desired ObjectStack object definitions
* @returns Schema diff describing all changes
*/
diff(current: IntrospectedSchema, desired: Record<string, unknown>[]): DeployDiff;

/**
* Generate SQL migration statements from a schema diff.
* Output is dialect-specific (PostgreSQL, SQLite, etc.).
*
* @param diff - Schema diff to generate migrations for
* @param dialect - Target SQL dialect
* @returns Ordered migration plan
*/
generateMigrations(diff: DeployDiff, dialect: SQLDialect): MigrationPlan;

/**
* Apply a migration plan to the database.
* Executes statements in order within a transaction (when supported).
*
* @param driver - Data driver to apply migrations to
* @param plan - Migration plan to execute
* @returns Apply result with success status and timing
*/
applyMigrations(driver: unknown, plan: MigrationPlan): Promise<MigrationApplyResult>;
}
Loading