diff --git a/internal/planning/OPTIMIZATION_ROADMAP.md b/internal/planning/OPTIMIZATION_ROADMAP.md new file mode 100644 index 0000000..2dbfbf1 --- /dev/null +++ b/internal/planning/OPTIMIZATION_ROADMAP.md @@ -0,0 +1,1283 @@ +# ObjectStack Protocol - Optimization Roadmap + +> **Date:** 2026-01-23 +> **Phase:** Post-Review Implementation Plan +> **Timeline:** Q1 2026 - Q4 2026 +> **Priority Framework:** Critical → High → Medium → Low + +--- + +## 🎯 Overview + +This roadmap addresses the gaps identified in the **[PROTOCOL_REVIEW.md](./PROTOCOL_REVIEW.md)** comprehensive assessment. Tasks are organized by priority and estimated effort. + +### Priority Definitions + +- **🔴 CRITICAL:** Blocking production deployment, compliance/security risks +- **🟡 HIGH:** Significant impact on developer experience or feature completeness +- **🟢 MEDIUM:** Quality of life improvements, nice-to-have features +- **⚪ LOW:** Future enhancements, edge cases + +--- + +## 📅 Q1 2026: Foundation & Compliance + +### Sprint 1 (Weeks 1-2): Audit & Security + +#### 🔴 CRITICAL: Audit Log Schema +**File:** `packages/spec/src/system/audit.zod.ts` +**Effort:** 3 days +**Owner:** System Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/system/audit.zod.ts +import { z } from 'zod' + +export const AuditLogSchema = z.object({ + id: z.string().uuid(), + + // WHO performed the action + actor: z.object({ + userId: z.string(), + username: z.string(), + roleId: z.string(), + impersonating: z.boolean().default(false), + }), + + // WHAT action was performed + action: z.enum([ + // Data operations + 'create', 'read', 'update', 'delete', 'undelete', + 'export', 'import', 'bulk_update', 'bulk_delete', + + // Authentication + 'login', 'logout', 'login_failed', 'password_reset', + 'mfa_enabled', 'mfa_disabled', + + // Authorization + 'permission_granted', 'permission_revoked', + 'role_assigned', 'role_removed', + + // API access + 'api_key_created', 'api_key_revoked', + 'oauth_token_issued', 'oauth_token_revoked', + + // Configuration changes + 'object_created', 'object_modified', 'object_deleted', + 'field_created', 'field_modified', 'field_deleted', + 'workflow_activated', 'workflow_deactivated', + ]), + + // WHERE (resource affected) + resource: z.object({ + type: z.enum(['record', 'object', 'field', 'user', 'role', 'permission', 'api_key', 'workflow', 'flow']), + objectName: z.string().optional(), + recordId: z.string().optional(), + fieldName: z.string().optional(), + }), + + // WHEN + timestamp: z.string().datetime(), + + // HOW (context) + metadata: z.object({ + ipAddress: z.string(), + userAgent: z.string(), + requestId: z.string().uuid(), + sessionId: z.string(), + + // Change tracking + oldValue: z.any().nullable(), + newValue: z.any().nullable(), + changeReason: z.string().optional(), // User-provided audit reason + + // Geolocation (optional) + geoLocation: z.object({ + country: z.string(), + region: z.string(), + city: z.string(), + }).optional(), + }), +}) + +export const AuditConfigSchema = z.object({ + enabled: z.boolean().default(true), + + // Retention + retentionDays: z.number().default(180), // 6 months (GDPR) + archiveAfterDays: z.number().default(90), // Move to cold storage + archiveDestination: z.enum(['s3', 'glacier', 'database']).default('s3'), + + // Tracking granularity + trackReads: z.boolean().default(false), // Expensive! Only for sensitive data + trackFieldChanges: z.boolean().default(true), + trackLogins: z.boolean().default(true), + + // Exclusions + excludeObjects: z.array(z.string()).optional(), // Objects to skip + excludeFields: z.array(z.string()).optional(), // Fields to skip (e.g., password) + excludeUsers: z.array(z.string()).optional(), // System users + + // Alerting + alertOnSuspiciousActivity: z.boolean().default(true), + suspiciousPatterns: z.array(z.object({ + name: z.string(), + condition: z.string(), // Formula: "COUNT(login_failed) > 5 IN LAST 10 MINUTES" + severity: z.enum(['low', 'medium', 'high', 'critical']), + alertRecipients: z.array(z.string()), // Email addresses + webhookUrl: z.string().url().optional(), + })).optional(), +}) + +export type AuditLog = z.infer +export type AuditConfig = z.infer +``` + +**Acceptance Criteria:** +- [ ] Schema validates all common audit scenarios +- [ ] Supports SOX, HIPAA, GDPR compliance requirements +- [ ] JSON schema generated correctly +- [ ] Unit tests with 90%+ coverage +- [ ] Documentation with examples + +**Compliance Impact:** +- SOX: ✅ Tracks all financial record changes +- HIPAA: ✅ Tracks all PHI access +- GDPR: ✅ Tracks all PII processing + +--- + +#### 🔴 CRITICAL: Multi-Tenancy Isolation Strategy +**File:** `packages/spec/src/system/tenant.zod.ts` (expand existing) +**Effort:** 5 days +**Owner:** System Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/system/tenant.zod.ts +import { z } from 'zod' + +export const TenantIsolationStrategySchema = z.enum([ + 'row_level', // Add tenant_id to every table + PostgreSQL RLS + 'schema_level', // CREATE SCHEMA tenant_123 for each tenant + 'database_level', // CREATE DATABASE tenant_123_db for each tenant +]) + +export const TenantSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + slug: z.string().regex(/^[a-z0-9-]+$/), // tenant1, acme-corp + + // Isolation configuration + isolation: z.object({ + strategy: TenantIsolationStrategySchema.default('row_level'), + + // Row-level configuration + tenantIdColumn: z.string().default('tenant_id'), + enforceRLS: z.boolean().default(true), // PostgreSQL Row-Level Security + + // Schema-level configuration + schemaPrefix: z.string().default('tenant_'), + + // Database-level configuration + databasePrefix: z.string().default('tenant_'), + databaseHost: z.string().optional(), // Separate DB host for enterprise + }), + + // Resource quotas + quotas: z.object({ + maxUsers: z.number().default(100), + maxRecords: z.number().default(1000000), + maxStorageGb: z.number().default(100), + maxApiCallsPerMonth: z.number().default(1000000), + maxConcurrentJobs: z.number().default(10), + maxObjectsPerTenant: z.number().default(100), + maxWorkflowsPerObject: z.number().default(10), + }), + + // Feature flags + features: z.object({ + enableAI: z.boolean().default(false), + enableAPI: z.boolean().default(true), + enableWebhooks: z.boolean().default(true), + enableRealtime: z.boolean().default(false), + enableAdvancedReports: z.boolean().default(false), + enableMobileApp: z.boolean().default(true), + }), + + // Status & lifecycle + status: z.enum(['trial', 'active', 'suspended', 'churned']), + tier: z.enum(['free', 'starter', 'professional', 'enterprise']), + trialEndsAt: z.string().datetime().optional(), + + // Metadata + createdAt: z.string().datetime(), + updatedAt: z.string().datetime(), + createdBy: z.string(), +}) + +export const TenantIsolationPolicySchema = z.object({ + // Security policies + enforceRLS: z.boolean().default(true), + preventCrossTenantQueries: z.boolean().default(true), + auditCrossTenantAttempts: z.boolean().default(true), + + // Data residency + dataResidency: z.object({ + region: z.string(), // "us-east-1", "eu-west-1" + allowCrossRegionReplication: z.boolean().default(false), + }).optional(), + + // Backup & disaster recovery + backup: z.object({ + enabled: z.boolean().default(true), + frequency: z.enum(['hourly', 'daily', 'weekly']).default('daily'), + retentionDays: z.number().default(30), + }), +}) + +export type Tenant = z.infer +export type TenantIsolationPolicy = z.infer +``` + +**Documentation Required:** +Create `content/docs/specifications/multi-tenancy.mdx`: + +```markdown +# Multi-Tenancy Architecture + +## Isolation Strategies + +### Row-Level (Recommended for Most Use Cases) +- Add `tenant_id` column to every table +- Use PostgreSQL Row-Level Security (RLS) policies +- ✅ Pros: Simple backups, cost-efficient, easy migrations +- ❌ Cons: Risk of data leakage if RLS misconfigured + +### Schema-Level (Enterprise Tier) +- CREATE SCHEMA tenant_123 for each tenant +- ✅ Pros: Better isolation, easier debugging +- ❌ Cons: Complex backups, expensive migrations + +### Database-Level (Regulated Industries) +- CREATE DATABASE tenant_123_db for each tenant +- ✅ Pros: Perfect isolation, regulatory compliance +- ❌ Cons: Expensive, connection pool limits + +## Implementation Guide + +### Row-Level Security Example (PostgreSQL) +\`\`\`sql +-- Enable RLS on table +ALTER TABLE accounts ENABLE ROW LEVEL SECURITY; + +-- Create policy +CREATE POLICY tenant_isolation ON accounts + USING (tenant_id = current_setting('app.current_tenant')::uuid); + +-- Set tenant context +SET app.current_tenant = 'f47ac10b-58cc-4372-a567-0e02b2c3d479'; +\`\`\` +``` + +**Acceptance Criteria:** +- [ ] All three strategies documented +- [ ] Migration guide for switching strategies +- [ ] Security best practices documented +- [ ] Unit tests for each strategy +- [ ] JSON schema generated + +--- + +### Sprint 2 (Weeks 3-4): Workflow & Formula Enhancements + +#### 🟡 HIGH: Workflow Action Expansion +**File:** `packages/spec/src/data/workflow.zod.ts` (expand existing) +**Effort:** 3 days +**Owner:** Data Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/data/workflow.zod.ts +export const WorkflowActionSchema = z.discriminatedUnion('type', [ + // Existing actions + z.object({ + type: z.literal('fieldUpdate'), + field: z.string(), + value: z.any() + }), + z.object({ + type: z.literal('email'), + template: z.string(), + recipients: z.array(z.string()) + }), + + // NEW: Communication actions + z.object({ + type: z.literal('sms'), + phoneNumberField: z.string(), + messageTemplate: z.string(), + provider: z.enum(['twilio', 'vonage', 'aws_sns']).optional(), + }), + z.object({ + type: z.literal('slack'), + channel: z.string(), // #sales or @username + messageTemplate: z.string(), + attachments: z.array(z.object({ + title: z.string(), + text: z.string(), + color: z.string().optional(), + })).optional(), + }), + z.object({ + type: z.literal('teams'), + webhookUrl: z.string().url(), + messageTemplate: z.string(), + theme: z.enum(['default', 'success', 'warning', 'error']).optional(), + }), + + // NEW: Integration actions + z.object({ + type: z.literal('httpCallout'), + method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']), + url: z.string().url(), + headers: z.record(z.string()).optional(), + body: z.any().optional(), + timeout: z.number().default(30), + retryOnFailure: z.boolean().default(false), + }), + z.object({ + type: z.literal('webhook'), + webhookId: z.string(), // Reference to webhook.zod.ts + payload: z.any().optional(), + }), + + // NEW: Task creation + z.object({ + type: z.literal('createTask'), + subject: z.string(), + description: z.string().optional(), + assignedTo: z.string(), // User ID or formula + dueDate: z.string().optional(), // ISO date or formula + priority: z.enum(['low', 'medium', 'high']).default('medium'), + }), + + // NEW: System actions + z.object({ + type: z.literal('customScript'), + scriptName: z.string(), + parameters: z.record(z.any()).optional(), + }), + z.object({ + type: z.literal('pushNotification'), + title: z.string(), + body: z.string(), + recipients: z.array(z.string()), // User IDs + actionUrl: z.string().url().optional(), + }), +]) +``` + +**Acceptance Criteria:** +- [ ] 10+ action types supported +- [ ] Examples for each action type in docs +- [ ] Integration tests with mock providers +- [ ] Error handling for failed actions + +--- + +#### 🟡 HIGH: Formula Function Library Documentation +**File:** `content/docs/references/formula-functions.mdx` +**Effort:** 4 days +**Owner:** Documentation Team + +**Create comprehensive function library:** +```markdown +# Formula Function Library + +## Text Functions + +### UPPER(text) +Converts text to uppercase. +\`\`\` +UPPER("hello") → "HELLO" +\`\`\` + +### LOWER(text) +Converts text to lowercase. + +### CONCATENATE(text1, text2, ...) +Joins text strings. +\`\`\` +CONCATENATE(first_name, " ", last_name) → "John Doe" +\`\`\` + +### TEXT(number) +Converts number to text. + +### VALUE(text) +Converts text to number. + +### LEN(text) +Returns text length. + +### TRIM(text) +Removes leading/trailing spaces. + +### LEFT(text, num_chars) +Returns leftmost characters. + +### RIGHT(text, num_chars) +Returns rightmost characters. + +### MID(text, start, length) +Returns substring. + +### FIND(search, text) +Returns position of substring (1-based). + +### REPLACE(text, old, new) +Replaces text. + +## Math Functions + +### SUM(number1, number2, ...) +Adds numbers. + +### AVERAGE(number1, number2, ...) +Calculates average. + +### ROUND(number, decimals) +Rounds to decimal places. + +### CEILING(number) +Rounds up. + +### FLOOR(number) +Rounds down. + +### ABS(number) +Absolute value. + +### MIN(number1, number2, ...) +Returns minimum. + +### MAX(number1, number2, ...) +Returns maximum. + +### POWER(base, exponent) +Raises to power. + +### SQRT(number) +Square root. + +### MOD(number, divisor) +Modulo (remainder). + +## Date Functions + +### TODAY() +Current date (no time). + +### NOW() +Current date and time. + +### YEAR(date) +Extract year. + +### MONTH(date) +Extract month (1-12). + +### DAY(date) +Extract day (1-31). + +### ADDDAYS(date, days) +Add days to date. +\`\`\` +ADDDAYS(TODAY(), 7) → 7 days from now +\`\`\` + +### ADDMONTHS(date, months) +Add months. + +### ADDYEARS(date, years) +Add years. + +### DATE(year, month, day) +Create date. + +### DATEVALUE(text) +Parse date from text. + +### TIMEDIFF(date1, date2, unit) +Difference between dates. +\`\`\` +TIMEDIFF(due_date, TODAY(), "days") → days until due +\`\`\` +Units: "seconds", "minutes", "hours", "days", "months", "years" + +## Logical Functions + +### IF(condition, true_value, false_value) +Conditional logic. +\`\`\` +IF(amount > 1000, "High", "Low") +\`\`\` + +### AND(condition1, condition2, ...) +Logical AND. + +### OR(condition1, condition2, ...) +Logical OR. + +### NOT(condition) +Logical NOT. + +### ISBLANK(field) +Check if null/empty. + +### ISNUMBER(value) +Check if numeric. + +### CASE(expression, value1, result1, value2, result2, ..., default) +Switch-case logic. +\`\`\` +CASE(status, "new", 0, "in_progress", 50, "done", 100, 0) +\`\`\` + +## Lookup Functions + +### LOOKUP(field) +Get related field value. +\`\`\` +LOOKUP(account.industry) → Industry of related account +\`\`\` + +### ROLLUP(related_object, field, function) +Aggregate related records. +\`\`\` +ROLLUP(opportunities, amount, SUM) → Total opportunity amount +\`\`\` +Functions: SUM, AVG, MIN, MAX, COUNT + +### PARENT(field) +Get parent record field (master-detail). + +## Advanced Functions + +### REGEX(text, pattern) +Regular expression match. +\`\`\` +REGEX(email, "^[a-z0-9]+@[a-z]+\.[a-z]{2,3}$") +\`\`\` + +### JSON(path, json_string) +Extract from JSON. +\`\`\` +JSON("address.city", custom_data) → "San Francisco" +\`\`\` + +### HASH(text, algorithm) +Hash text. +\`\`\` +HASH(email, "sha256") → "a665a45920..." +\`\`\` + +### ENCRYPT(text, key) +Encrypt text (AES-256). + +### DECRYPT(encrypted, key) +Decrypt text. + +## Type Conversion + +### TEXT(value) +Convert to text. + +### VALUE(text) +Convert to number. + +### DATE(value) +Convert to date. + +### BOOLEAN(value) +Convert to boolean. +``` + +**Acceptance Criteria:** +- [ ] All 50+ functions documented +- [ ] Examples for each function +- [ ] Type compatibility matrix +- [ ] Error cases documented + +--- + +## 📅 Q2 2026: UI & Page Components + +### Sprint 3 (Weeks 5-6): Page Component System + +#### 🟡 HIGH: Page Component Schema +**File:** `packages/spec/src/ui/page.zod.ts` (expand existing) +**Effort:** 5 days +**Owner:** UI Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/ui/page.zod.ts +import { z } from 'zod' + +export const PageRegionSchema = z.object({ + name: z.string(), + type: z.enum(['header', 'sidebar_left', 'sidebar_right', 'main', 'footer']), + width: z.number().min(1).max(12).optional(), // Grid columns + minHeight: z.number().optional(), // Pixels + components: z.array(z.lazy(() => PageComponentSchema)), + + // Responsive behavior + mobile: z.object({ + hidden: z.boolean().default(false), + stackComponents: z.boolean().default(true), + }).optional(), +}) + +export const PageComponentSchema = z.discriminatedUnion('type', [ + // Record components + z.object({ + type: z.literal('record_detail'), + objectName: z.string(), + recordId: z.string().optional(), // Formula or parameter + layout: z.enum(['simple', 'tabbed', 'wizard']).default('simple'), + }), + z.object({ + type: z.literal('related_list'), + objectName: z.string(), + relationshipName: z.string(), + viewName: z.string().optional(), + maxRecords: z.number().default(10), + enableInlineEdit: z.boolean().default(false), + }), + + // Analytics components + z.object({ + type: z.literal('dashboard_widget'), + widgetId: z.string(), + refreshInterval: z.number().optional(), // Seconds + }), + z.object({ + type: z.literal('report'), + reportId: z.string(), + chartType: z.enum(['table', 'bar', 'line', 'pie']).optional(), + }), + z.object({ + type: z.literal('metric_card'), + title: z.string(), + formula: z.string(), // e.g., "COUNT(opportunity WHERE status = 'won')" + format: z.enum(['number', 'currency', 'percent']).default('number'), + trend: z.boolean().default(false), // Show trend arrow + }), + + // Custom content + z.object({ + type: z.literal('custom_html'), + html: z.string(), + }), + z.object({ + type: z.literal('iframe'), + url: z.string().url(), + height: z.number().default(600), + }), + z.object({ + type: z.literal('markdown'), + content: z.string(), + }), + + // Navigation components + z.object({ + type: z.literal('recent_items'), + objectNames: z.array(z.string()).optional(), + maxItems: z.number().default(10), + }), + z.object({ + type: z.literal('global_search'), + placeholder: z.string().optional(), + }), + + // Collaboration + z.object({ + type: z.literal('activity_timeline'), + recordId: z.string().optional(), + objectName: z.string().optional(), + maxItems: z.number().default(20), + }), + z.object({ + type: z.literal('comments'), + recordId: z.string().optional(), + enableMentions: z.boolean().default(true), + }), +]) + +export const PageSchema = z.object({ + name: z.string(), + label: z.string(), + type: z.enum(['record', 'home', 'app', 'utility']), + + // Object-specific pages + objectName: z.string().optional(), + recordId: z.string().optional(), + + // Layout + layout: z.enum(['one_column', 'two_column_left', 'two_column_right', 'three_column']).default('one_column'), + regions: z.array(PageRegionSchema), + + // Permissions + permissions: z.array(z.string()).optional(), // Role names + + // Metadata + description: z.string().optional(), + isActive: z.boolean().default(true), +}) + +export type Page = z.infer +export type PageRegion = z.infer +export type PageComponent = z.infer +``` + +**Acceptance Criteria:** +- [ ] 15+ component types supported +- [ ] FlexiPage-style regions (header, sidebars, main, footer) +- [ ] Responsive behavior defined +- [ ] Examples for common page layouts +- [ ] JSON schema generated + +--- + +### Sprint 4 (Weeks 7-8): Report Enhancements + +#### 🟢 MEDIUM: Report Grouping & Subtotals +**File:** `packages/spec/src/ui/report.zod.ts` (expand existing) +**Effort:** 3 days +**Owner:** UI Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/ui/report.zod.ts +export const ReportGroupingSchema = z.object({ + field: z.string(), + sortOrder: z.enum(['asc', 'desc']).default('asc'), + + // Date grouping (for date fields) + dateGrouping: z.enum(['day', 'week', 'month', 'quarter', 'year']).optional(), + + // Subtotals + subtotals: z.array(z.object({ + field: z.string(), + function: z.enum(['sum', 'avg', 'count', 'min', 'max', 'median']), + label: z.string().optional(), + })), +}) + +export const ReportFilterSchema = z.object({ + field: z.string(), + operator: z.enum([ + 'equals', 'not_equals', + 'greater_than', 'greater_than_or_equal', + 'less_than', 'less_than_or_equal', + 'contains', 'not_contains', + 'starts_with', 'ends_with', + 'in', 'not_in', + 'between', + 'is_null', 'is_not_null', + ]), + value: z.any().optional(), + values: z.array(z.any()).optional(), // For 'in' operator + + // Filter logic + filterLogic: z.string().optional(), // "1 AND (2 OR 3)" +}) + +export const ReportSchema = z.object({ + // ... existing fields + + // Grouping (max 3 levels) + groupings: z.array(ReportGroupingSchema).max(3), + + // Filters + filters: z.array(ReportFilterSchema), + + // Cross-filters (related objects) + crossFilters: z.array(z.object({ + relatedObject: z.string(), + hasRecords: z.boolean(), // "Has Opportunities" vs "Has No Opportunities" + relationshipName: z.string(), + })).optional(), + + // Custom summary formulas + customSummaryFormulas: z.array(z.object({ + name: z.string(), + label: z.string(), + formula: z.string(), // e.g., "SUM(amount) / COUNT(id)" + format: z.enum(['number', 'currency', 'percent']).default('number'), + })).optional(), + + // Chart settings + chart: z.object({ + type: z.enum(['bar', 'line', 'pie', 'donut', 'funnel', 'scatter']), + xAxis: z.string(), + yAxis: z.string(), + legend: z.boolean().default(true), + }).optional(), +}) +``` + +**Acceptance Criteria:** +- [ ] 3-level grouping support +- [ ] Subtotal functions (sum, avg, count, min, max, median) +- [ ] Cross-filter support +- [ ] Custom summary formulas +- [ ] Examples for common report patterns + +--- + +## 📅 Q3 2026: AI Safety & Advanced Features + +### Sprint 5 (Weeks 9-10): AI Safety + +#### 🔴 CRITICAL: AI Safety & Guardrails +**File:** `packages/spec/src/ai/safety.zod.ts` (new) +**Effort:** 5 days +**Owner:** AI Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/ai/safety.zod.ts +import { z } from 'zod' + +export const SafetyGuardrailTypeSchema = z.enum([ + 'prompt_injection_detection', // Detect malicious prompts + 'pii_detection', // Prevent PII leakage + 'hallucination_detection', // Check for factual errors + 'output_validation', // Validate generated code/queries + 'content_moderation', // Block offensive content + 'jailbreak_prevention', // Prevent system prompt overrides + 'sql_injection_prevention', // Prevent SQL injection in generated queries + 'xss_prevention', // Prevent XSS in generated HTML/JS +]) + +export const SafetyGuardrailSchema = z.object({ + name: z.string(), + type: SafetyGuardrailTypeSchema, + enabled: z.boolean().default(true), + action: z.enum(['block', 'warn', 'log']).default('block'), + threshold: z.number().min(0).max(1).optional(), // Confidence threshold (0.0-1.0) + + // Custom validation + validationScript: z.string().optional(), // JavaScript validator function + + // Error handling + errorMessage: z.string().optional(), + fallbackResponse: z.string().optional(), +}) + +export const PiiProtectionConfigSchema = z.object({ + enabled: z.boolean().default(true), + + // Redaction + redactFromPrompts: z.boolean().default(true), + redactFromResponses: z.boolean().default(true), + redactionPlaceholder: z.string().default('[REDACTED]'), + + // PII types + detectEmails: z.boolean().default(true), + detectPhones: z.boolean().default(true), + detectSSNs: z.boolean().default(true), + detectCreditCards: z.boolean().default(true), + detectPasswords: z.boolean().default(true), + detectApiKeys: z.boolean().default(true), + + // Allowed PII (opt-in) + allowedPiiTypes: z.array(z.enum(['email', 'phone', 'ssn', 'credit_card'])).optional(), + + // Custom PII patterns (regex) + customPiiPatterns: z.array(z.object({ + name: z.string(), + pattern: z.string(), // Regex pattern + replacement: z.string().default('[REDACTED]'), + })).optional(), +}) + +export const OutputValidationConfigSchema = z.object({ + enabled: z.boolean().default(true), + + // SQL validation + validateSQLQueries: z.boolean().default(true), + allowedSQLCommands: z.array(z.enum(['SELECT', 'INSERT', 'UPDATE', 'DELETE'])).default(['SELECT']), + blockDangerousFunctions: z.boolean().default(true), // Block DROP, TRUNCATE, etc. + + // JavaScript validation + validateJavaScript: z.boolean().default(true), + allowEval: z.boolean().default(false), + allowedFunctions: z.array(z.string()).optional(), // Whitelist + + // HTML validation + validateHTML: z.boolean().default(true), + allowedTags: z.array(z.string()).optional(), // e.g., ['p', 'div', 'span'] + blockScriptTags: z.boolean().default(true), + + // Sandbox execution + sandboxGeneratedCode: z.boolean().default(true), + sandboxTimeout: z.number().default(5000), // Milliseconds +}) + +export const RateLimitingConfigSchema = z.object({ + enabled: z.boolean().default(true), + + // Request limits + maxRequestsPerMinute: z.number().default(10), + maxRequestsPerHour: z.number().default(100), + maxRequestsPerDay: z.number().default(1000), + + // Token limits + maxTokensPerRequest: z.number().default(4000), + maxTokensPerHour: z.number().default(100000), + maxTokensPerDay: z.number().default(1000000), + + // Cost limits + maxCostPerRequestUsd: z.number().optional(), + maxCostPerDayUsd: z.number().optional(), +}) + +export const SafetyConfigSchema = z.object({ + // Guardrails + guardrails: z.array(SafetyGuardrailSchema), + + // PII protection + piiProtection: PiiProtectionConfigSchema, + + // Output validation + outputValidation: OutputValidationConfigSchema, + + // Rate limiting + rateLimiting: RateLimitingConfigSchema, + + // Monitoring & alerts + monitoring: z.object({ + logAllRequests: z.boolean().default(true), + logBlockedRequests: z.boolean().default(true), + alertOnThresholdExceeded: z.boolean().default(true), + alertRecipients: z.array(z.string()).optional(), + }), +}) + +export type SafetyGuardrail = z.infer +export type SafetyConfig = z.infer +``` + +**Acceptance Criteria:** +- [ ] 8+ guardrail types implemented +- [ ] PII detection with 90%+ accuracy +- [ ] SQL/XSS injection prevention +- [ ] Integration tests with attack scenarios +- [ ] Documentation with security best practices + +--- + +### Sprint 6 (Weeks 11-12): AI Conversation & Cost Management + +#### 🟡 HIGH: Conversation Memory Schema +**File:** `packages/spec/src/ai/conversation.zod.ts` (new) +**Effort:** 3 days +**Owner:** AI Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/ai/conversation.zod.ts +import { z } from 'zod' + +export const ConversationMessageSchema = z.object({ + id: z.string().uuid(), + role: z.enum(['user', 'assistant', 'system', 'tool']), + content: z.string(), + timestamp: z.string().datetime(), + + // Token tracking + promptTokens: z.number().optional(), + completionTokens: z.number().optional(), + totalTokens: z.number().optional(), + + // Tool calls + toolCalls: z.array(z.object({ + id: z.string(), + type: z.literal('function'), + function: z.object({ + name: z.string(), + arguments: z.string(), // JSON string + }), + result: z.any().optional(), + })).optional(), + + // Metadata + metadata: z.record(z.any()).optional(), +}) + +export const TokenBudgetSchema = z.object({ + maxTokensPerMessage: z.number().default(4000), + maxTokensPerConversation: z.number().default(128000), + maxMessagesPerConversation: z.number().default(100), + + totalTokensUsed: z.number(), + estimatedCostUsd: z.number(), + + // Auto-summarization + enableAutoSummarization: z.boolean().default(true), + summarizeAfterTokens: z.number().default(100000), // Summarize old messages +}) + +export const ConversationSchema = z.object({ + id: z.string().uuid(), + agentId: z.string(), + userId: z.string(), + + // Messages + messages: z.array(ConversationMessageSchema), + + // Token budget + tokenBudget: TokenBudgetSchema, + + // Conversation state + status: z.enum(['active', 'completed', 'failed', 'timeout']), + startedAt: z.string().datetime(), + completedAt: z.string().datetime().optional(), + + // Context + context: z.record(z.any()).optional(), // Persistent context across messages + + // Metadata + title: z.string().optional(), + tags: z.array(z.string()).optional(), + metadata: z.record(z.any()).optional(), +}) + +export type ConversationMessage = z.infer +export type Conversation = z.infer +``` + +--- + +#### 🟡 HIGH: AI Cost Tracking +**File:** `packages/spec/src/ai/cost.zod.ts` (new) +**Effort:** 3 days +**Owner:** AI Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/ai/cost.zod.ts +import { z } from 'zod' + +export const ModelPricingSchema = z.object({ + modelId: z.string(), + provider: z.enum(['openai', 'anthropic', 'azure', 'google', 'cohere', 'huggingface']), + + pricing: z.object({ + promptTokensPer1k: z.number(), // USD per 1000 prompt tokens + completionTokensPer1k: z.number(), // USD per 1000 completion tokens + embeddingPer1k: z.number().optional(), + fineTuningTrainingPer1k: z.number().optional(), + fineTuningInferencePer1k: z.number().optional(), + }), + + // Effective dates + effectiveFrom: z.string().datetime(), + effectiveTo: z.string().datetime().optional(), +}) + +export const UsageCostSchema = z.object({ + tenantId: z.string(), + period: z.string(), // "2024-01" (monthly) + + // Breakdown by model + breakdown: z.array(z.object({ + modelId: z.string(), + provider: z.string(), + + promptTokens: z.number(), + completionTokens: z.number(), + totalTokens: z.number(), + + promptCostUsd: z.number(), + completionCostUsd: z.number(), + totalCostUsd: z.number(), + + requestCount: z.number(), + })), + + // Totals + totalPromptTokens: z.number(), + totalCompletionTokens: z.number(), + totalTokens: z.number(), + totalCostUsd: z.number(), + + // Budget & alerts + budgetLimitUsd: z.number().optional(), + budgetUsedPercent: z.number(), + budgetAlertThreshold: z.number().default(0.9), // Alert at 90% + budgetExceeded: z.boolean(), +}) + +export type ModelPricing = z.infer +export type UsageCost = z.infer +``` + +--- + +## 📅 Q4 2026: API Enhancements & Polish + +### Sprint 7 (Weeks 13-14): API Improvements + +#### 🟢 MEDIUM: Cursor-Based Pagination +**File:** `packages/spec/src/api/contract.zod.ts` (expand) +**Effort:** 2 days +**Owner:** API Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/api/contract.zod.ts +export const CursorPaginationSchema = z.object({ + cursor: z.string().optional(), // Opaque cursor (base64-encoded) + limit: z.number().min(1).max(100).default(25), + hasMore: z.boolean(), + nextCursor: z.string().optional(), + previousCursor: z.string().optional(), +}) + +export const ListRecordResponseSchema = z.object({ + data: z.array(z.any()), + + // Support both offset and cursor pagination + pagination: z.union([ + OffsetPaginationSchema, + CursorPaginationSchema, + ]), + + metadata: ResponseMetadataSchema, +}) +``` + +--- + +#### 🟢 MEDIUM: Field Projection +**File:** `packages/spec/src/api/contract.zod.ts` (expand) +**Effort:** 2 days +**Owner:** API Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/api/contract.zod.ts +export const FieldProjectionSchema = z.object({ + fields: z.array(z.string()).optional(), // Include only these fields + exclude: z.array(z.string()).optional(), // Exclude these fields + include: z.object({ + relatedObjects: z.array(z.string()).optional(), // Include related objects + }).optional(), +}) + +// Usage: GET /api/account/123?fields=name,email,phone&include=contacts +``` + +--- + +#### 🟢 MEDIUM: API Versioning +**File:** `packages/spec/src/system/api.zod.ts` (expand) +**Effort:** 2 days +**Owner:** System Protocol Team + +**Implementation:** +```typescript +// packages/spec/src/system/api.zod.ts +export const ApiVersionSchema = z.object({ + version: z.string(), // "v1", "v2", "2024-01-15" + status: z.enum(['stable', 'beta', 'deprecated', 'sunset']), + + deprecated: z.boolean().default(false), + deprecationDate: z.string().datetime().optional(), + sunsetDate: z.string().datetime().optional(), // When version will be removed + + // Versioning strategy + versioningStrategy: z.enum(['header', 'url', 'query']).default('url'), + // Header: X-API-Version: v1 + // URL: /api/v1/account/123 + // Query: /api/account/123?version=v1 + + // Migration guide + changelogUrl: z.string().url().optional(), + migrationGuideUrl: z.string().url().optional(), +}) +``` + +--- + +### Sprint 8 (Weeks 15-16): Final Polish + +#### 🟢 MEDIUM: Documentation Cleanup +**Effort:** 5 days +**Owner:** Documentation Team + +**Tasks:** +- [ ] Update all MDX files with new schemas +- [ ] Add examples for every protocol file +- [ ] Create migration guides for breaking changes +- [ ] Add architecture diagrams for new features +- [ ] Review and update CONTRIBUTING.md + +--- + +## 📊 Progress Tracking + +### Key Metrics + +| Metric | Target | Current | Status | +|--------|--------|---------|--------| +| Protocol Completeness | 95% | 75% | 🟡 | +| Documentation Coverage | 90% | 60% | 🟡 | +| Unit Test Coverage | 85% | 70% | 🟡 | +| Schema Generation | 100% | 100% | ✅ | +| JSON Schema Validation | 100% | 100% | ✅ | + +### Milestones + +- **Q1 2026 End:** ✅ Audit, tenancy, workflow actions, formula docs +- **Q2 2026 End:** ✅ Page components, report enhancements +- **Q3 2026 End:** ✅ AI safety, conversation memory, cost tracking +- **Q4 2026 End:** ✅ API improvements, documentation polish + +--- + +## 🚨 Risk Management + +### High-Risk Items + +| Risk | Impact | Mitigation | +|------|--------|-----------| +| Multi-tenancy RLS misconfiguration | 🔴 Critical | Comprehensive testing, security audit, PostgreSQL expert review | +| AI safety bypasses | 🔴 Critical | Red team testing, external security review | +| Performance degradation (audit logs) | 🟡 High | Async logging, partitioned tables, archival strategy | +| Breaking changes in API | 🟡 High | Versioning strategy, deprecation notices, migration guides | + +--- + +## 📞 Contact & Ownership + +| Area | Team | Lead | Slack Channel | +|------|------|------|---------------| +| Data Protocol | @data-team | TBD | #protocol-data | +| UI Protocol | @ui-team | TBD | #protocol-ui | +| System Protocol | @system-team | TBD | #protocol-system | +| AI Protocol | @ai-team | TBD | #protocol-ai | +| API Protocol | @api-team | TBD | #protocol-api | +| Documentation | @docs-team | TBD | #protocol-docs | + +--- + +**Document Status:** ✅ Complete +**Last Updated:** 2026-01-23 +**Next Review:** End of Q1 2026 diff --git a/internal/planning/PRIORITIES.md b/internal/planning/PRIORITIES.md index 3456ded..bd82432 100644 --- a/internal/planning/PRIORITIES.md +++ b/internal/planning/PRIORITIES.md @@ -1,12 +1,54 @@ # ObjectStack Protocol - Priority Matrix -> Quick reference for what to work on next. See [DEVELOPMENT_ROADMAP.md](./DEVELOPMENT_ROADMAP.md) for the complete plan. +> Quick reference for what to work on next. See [DEVELOPMENT_ROADMAP.md](./DEVELOPMENT_ROADMAP.md) for the complete plan. +> **New:** See [PROTOCOL_REVIEW.md](./PROTOCOL_REVIEW.md) for comprehensive assessment and [OPTIMIZATION_ROADMAP.md](./OPTIMIZATION_ROADMAP.md) for detailed implementation plan. -**Last Updated**: 2026-01-20 +**Last Updated**: 2026-01-23 +**Status**: 75% Complete - Production-Ready with Critical Gaps --- -## 🔥 Critical Path Items (Must Do Now) +## 🚨 NEW: Post-Review Critical Priorities + +Based on the comprehensive protocol review completed on 2026-01-23, the following items are **blocking production deployment**: + +### 🔴 CRITICAL #1: Audit Log Schema (Compliance Blocker) +**File**: `packages/spec/src/system/audit.zod.ts` (new) +**Effort**: 3 days +**Impact**: Required for SOX, HIPAA, GDPR compliance +**Blocks**: Enterprise sales, production deployment + +**Why Critical**: No audit trail = cannot track who did what when = compliance failure. + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 1](./OPTIMIZATION_ROADMAP.md#sprint-1-weeks-1-2-audit--security) + +--- + +### 🔴 CRITICAL #2: Multi-Tenancy Isolation Strategy (Security Blocker) +**File**: `packages/spec/src/system/tenant.zod.ts` (expand existing) +**Effort**: 5 days +**Impact**: Secure multi-tenancy, data isolation +**Blocks**: SaaS deployments, production + +**Why Critical**: Current tenant.zod.ts lacks isolation strategy documentation. Risk of cross-tenant data leakage. + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 1](./OPTIMIZATION_ROADMAP.md#critical-multi-tenancy-isolation-strategy) + +--- + +### 🔴 CRITICAL #3: AI Safety & Guardrails (AI Safety Blocker) +**File**: `packages/spec/src/ai/safety.zod.ts` (new) +**Effort**: 5 days +**Impact**: Prevent prompt injection, PII leakage, hallucinations +**Blocks**: AI feature production deployment + +**Why Critical**: AI features without safety rails = security vulnerabilities, data leaks, compliance violations. + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 5](./OPTIMIZATION_ROADMAP.md#critical-ai-safety--guardrails) + +--- + +## 🔥 Original Critical Path Items (Must Do Now) These are blocking the ecosystem and should be addressed immediately. @@ -137,7 +179,75 @@ export const TriggerContextSchema = z.object({ --- -## 📊 High Priority Features (Do Next) +## 🟡 NEW: High Priority Enhancements (Post-Review) + +### Workflow Action Expansion +**File**: `packages/spec/src/data/workflow.zod.ts` (expand) +**Effort**: 3 days +**Value**: Enable SMS, Slack, webhooks, HTTP callouts +**Current**: Only fieldUpdate + email actions +**Target**: 10+ action types (SMS, Slack, Teams, webhooks, tasks, push notifications) + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 2](./OPTIMIZATION_ROADMAP.md#high-workflow-action-expansion) + +--- + +### Formula Function Library Documentation +**File**: `content/docs/references/formula-functions.mdx` (new) +**Effort**: 4 days +**Value**: 50+ functions documented with examples +**Current**: Formula fields exist but no function reference +**Target**: Complete function library (TEXT, MATH, DATE, LOGICAL, LOOKUP) + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 2](./OPTIMIZATION_ROADMAP.md#high-formula-function-library-documentation) + +--- + +### Page Component Schema (FlexiPage Replacement) +**File**: `packages/spec/src/ui/page.zod.ts` (expand) +**Effort**: 5 days +**Value**: Custom page layouts with regions and components +**Current**: Minimal page.zod.ts (only navigation reference) +**Target**: 15+ component types, Salesforce FlexiPage-style regions + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 3](./OPTIMIZATION_ROADMAP.md#high-page-component-schema) + +--- + +### Report Grouping & Subtotals +**File**: `packages/spec/src/ui/report.zod.ts` (expand) +**Effort**: 3 days +**Value**: Advanced analytics with grouping and roll-ups +**Current**: Basic report types defined +**Target**: 3-level grouping, subtotals, cross-filters, custom summary formulas + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 4](./OPTIMIZATION_ROADMAP.md#medium-report-grouping--subtotals) + +--- + +### AI Conversation Memory +**File**: `packages/spec/src/ai/conversation.zod.ts` (new) +**Effort**: 3 days +**Value**: Multi-turn AI conversations with token budgeting +**Current**: No conversation state management +**Target**: Message history, token tracking, auto-summarization + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 6](./OPTIMIZATION_ROADMAP.md#high-conversation-memory-schema) + +--- + +### AI Cost Tracking +**File**: `packages/spec/src/ai/cost.zod.ts` (new) +**Effort**: 3 days +**Value**: Monitor and control AI API costs +**Current**: RAG tracks tokens but no cost calculation +**Target**: Model pricing, usage breakdown, budget alerts + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 6](./OPTIMIZATION_ROADMAP.md#high-ai-cost-tracking) + +--- + +## 📊 Original High Priority Features (Do Next) ### Query Enhancements **Files**: `packages/spec/src/data/query.zod.ts` @@ -194,7 +304,28 @@ export const TriggerContextSchema = z.object({ --- -## 🧪 Developer Experience Priorities +## 🟢 NEW: Medium Priority Items (Post-Review) + +### Cursor-Based Pagination +**File**: `packages/spec/src/api/contract.zod.ts` (expand) +**Effort**: 2 days +**Value**: Stable pagination for large datasets + +### Field Projection (Sparse Fieldsets) +**File**: `packages/spec/src/api/contract.zod.ts` (expand) +**Effort**: 2 days +**Value**: Request specific fields only (reduce payload size) + +### API Versioning Strategy +**File**: `packages/spec/src/system/api.zod.ts` (expand) +**Effort**: 2 days +**Value**: Support multiple API versions gracefully + +**See**: [OPTIMIZATION_ROADMAP.md - Sprint 7](./OPTIMIZATION_ROADMAP.md#q4-2026-api-enhancements--polish) + +--- + +## 🧪 Original Developer Experience Priorities ### Test Coverage Improvement **Files**: All `*.test.ts` files @@ -354,7 +485,53 @@ export const TriggerContextSchema = z.object({ --- -## 📅 Sprint Planning Guide +## 📅 NEW: Updated Sprint Planning (Post-Review) + +### Q1 2026: Foundation & Compliance (Weeks 1-12) +**Sprint 1-2 (Weeks 1-4): Audit & Security** 🔴 CRITICAL +- [ ] Audit log schema (SOX/HIPAA/GDPR compliance) +- [ ] Multi-tenancy isolation strategy (security) +- [ ] Workflow action expansion (SMS, webhooks, etc.) +- [ ] Formula function library documentation + +**Sprint 3-4 (Weeks 5-8): UI Enhancements** 🟡 HIGH +- [ ] Page component schema (FlexiPage replacement) +- [ ] Report grouping & subtotals +- [ ] Widget component props expansion +- [ ] Mobile layout configurations + +**Sprint 5-6 (Weeks 9-12): AI Safety & Management** 🔴 CRITICAL +- [ ] AI safety & guardrails schema +- [ ] Conversation memory schema +- [ ] AI cost tracking schema +- [ ] Tool calling format standardization + +### Q2-Q4 2026: See [OPTIMIZATION_ROADMAP.md](./OPTIMIZATION_ROADMAP.md) + +--- + +## 📊 NEW: Updated Success Metrics + +| Metric | Before Review | Q1 2026 Target | Q2 Target | Q3 Target | Q4 Target | +|--------|---------------|----------------|-----------|-----------|-----------| +| **Protocol Completeness** | 75% | 85% | 90% | 95% | 98% | +| **Production Ready Modules** | 2/5 | 4/5 | 5/5 | 5/5 | 5/5 | +| **Compliance Ready** | ❌ | ✅ | ✅ | ✅ | ✅ | +| **AI Safety** | ❌ | ✅ | ✅ | ✅ | ✅ | +| **Test Coverage** | 70% | 80% | 85% | 90% | 95% | +| **Documentation Pages** | 50 | 100 | 150 | 200 | 250 | + +--- + +## 📚 Reference Documents + +- **[PROTOCOL_REVIEW.md](./PROTOCOL_REVIEW.md)**: Comprehensive assessment of all 45+ protocols +- **[OPTIMIZATION_ROADMAP.md](./OPTIMIZATION_ROADMAP.md)**: Detailed Q1-Q4 2026 implementation plan +- **[DEVELOPMENT_ROADMAP.md](./DEVELOPMENT_ROADMAP.md)**: Original complete development plan + +--- + +## 📅 Original Sprint Planning Guide ### Sprint 1-2 (Weeks 1-4): Critical Path - [ ] Field Widget Contract diff --git a/internal/planning/PROTOCOL_REVIEW.md b/internal/planning/PROTOCOL_REVIEW.md new file mode 100644 index 0000000..038d25e --- /dev/null +++ b/internal/planning/PROTOCOL_REVIEW.md @@ -0,0 +1,1144 @@ +# ObjectStack Protocol Review - Comprehensive Assessment + +> **Date:** 2026-01-23 +> **Review Scope:** All 45+ protocol files across Data, UI, System, AI, and API modules +> **Status:** 75% Complete - Production-Ready with Critical Gaps + +--- + +## 📊 Executive Summary + +ObjectStack Protocol demonstrates **strong foundational architecture** with excellent implementation of core data layer and UI components. However, **critical enterprise features** (audit logging, multi-tenancy isolation, AI safety) require immediate attention before production deployment. + +### Completion Status by Module + +| Module | Files | Status | Completeness | Production Ready | +|--------|-------|--------|--------------|------------------| +| **Data Protocol (ObjectQL)** | 9 files | 🟢 Mature | 85% | ✅ Yes (with gaps) | +| **UI Protocol (ObjectUI)** | 7 files | 🟡 Active | 75% | ⚠️ Needs Page Component | +| **System Protocol (ObjectOS)** | 17 files | 🟡 Active | 70% | ❌ Missing Audit + Tenancy | +| **AI Protocol** | 6 files | 🔴 Early | 50% | ❌ Missing Safety Rails | +| **API Protocol** | 1 file | 🟢 Stable | 80% | ✅ Yes (needs versioning) | + +--- + +## 1️⃣ DATA PROTOCOL (ObjectQL) - Deep Dive + +### ✅ Strengths + +#### Field Type System (field.zod.ts) +- **35+ field types** covering all common business needs +- **Advanced types**: Geolocation, QR Code, Rating, Slider, Signature, Color Picker, Rich Text, URL, Encrypted +- **Relationship fields**: Lookup (1:N), Master-Detail (cascade delete), Many-to-Many Junction +- **Computed fields**: Formula (read-only), Summary (rollup), Autonumber +- **Proper naming convention**: Uses `camelCase` for config keys, `snake_case` for machine names + +#### Validation System (validation.zod.ts) +- **8 validation types**: Script-based, Unique constraints, State machine, Format patterns, Cross-field dependencies, Async validation, Custom validators, Conditional visibility +- **Comprehensive metadata**: Error messages, active/inactive toggles, execution order +- **Formula support**: Boolean expressions for complex business rules + +#### Object Definition (object.zod.ts) +- **Capabilities flags**: `trackHistory`, `searchable`, `apiEnabled`, `enableSharing`, `enableAudit` +- **Proper indexes**: Unique, non-unique, composite, full-text search +- **Soft delete support**: `is_deleted` flag (though audit schema missing) + +#### Permission Model (permission.zod.ts) +- **CRUD + VAMA**: View All, Modify All for admin overrides +- **Field-level security**: Granular read/write permissions per field +- **Object-level permissions**: Per-object CRUD with inheritance + +#### Query System (query.zod.ts) +- **AST-based**: Filter, Sort, Join, Aggregation, Window Functions, Subqueries +- **Driver abstraction**: Translates to SQL, MongoDB, Redis, Salesforce SOQL +- **Optimization hints**: Index hints, query plans + +### ⚠️ Gaps and Missing Features + +#### 1. Trigger Actions Limited (workflow.zod.ts, trigger.zod.ts) +**Current State:** +```typescript +WorkflowActionSchema = z.discriminatedUnion('type', [ + z.object({ type: z.literal('fieldUpdate'), ... }), + z.object({ type: z.literal('email'), ... }), +]) +``` + +**Missing:** +- SMS notification actions +- Slack/Teams webhook actions +- HTTP callout actions +- Custom script execution +- Push notifications + +**Industry Comparison:** +- Salesforce: 10+ action types (Email, Task, SMS, Chatter, HTTP, Apex) +- ServiceNow: Flow Designer with 50+ actions (REST, SOAP, Scripted) + +**Recommendation:** +```typescript +export const WorkflowActionSchema = z.discriminatedUnion('type', [ + // Existing + z.object({ type: z.literal('fieldUpdate'), field: z.string(), value: z.any() }), + z.object({ type: z.literal('email'), template: z.string(), recipients: z.array(z.string()) }), + + // NEW: Communication actions + z.object({ type: z.literal('sms'), phoneNumberField: z.string(), messageTemplate: z.string() }), + z.object({ type: z.literal('slack'), channel: z.string(), messageTemplate: z.string() }), + z.object({ type: z.literal('teams'), webhookUrl: z.string(), messageTemplate: z.string() }), + + // NEW: Integration actions + z.object({ type: z.literal('httpCallout'), method: z.enum(['GET', 'POST', 'PUT', 'DELETE']), url: z.string(), headers: z.record(z.string()), body: z.any() }), + z.object({ type: z.literal('webhook'), webhookId: z.string(), payload: z.any() }), + + // NEW: System actions + z.object({ type: z.literal('customScript'), scriptName: z.string(), parameters: z.record(z.any()) }), + z.object({ type: z.literal('pushNotification'), title: z.string(), body: z.string(), recipients: z.array(z.string()) }), +]) +``` + +#### 2. Formula Function Library Undocumented (field.zod.ts) +**Current State:** +- Formula fields exist with `expression: z.string()` but no function reference +- No documentation of available functions (SUM, AVG, TEXT, DATE, etc.) + +**Missing:** +- Function signature documentation +- Data type compatibility matrix +- Example formulas + +**Industry Comparison:** +- Salesforce: 100+ formula functions documented (TEXT, DATE, MATH, LOGICAL, ADVANCED) +- ServiceNow: 50+ GlideSystem functions + +**Recommendation:** +Create `packages/spec/docs/formula-functions.md` with complete function library: +```markdown +# Formula Function Library + +## Text Functions +- `UPPER(text)` - Converts to uppercase +- `LOWER(text)` - Converts to lowercase +- `CONCATENATE(text1, text2, ...)` - Joins text strings +- `TEXT(number)` - Converts number to text +- `LEN(text)` - Returns text length + +## Math Functions +- `SUM(field1, field2, ...)` - Adds numbers +- `AVERAGE(field1, field2, ...)` - Calculates average +- `ROUND(number, decimals)` - Rounds to decimal places +- `CEILING(number)` - Rounds up to integer +- `FLOOR(number)` - Rounds down to integer + +## Date Functions +- `TODAY()` - Current date +- `NOW()` - Current date/time +- `YEAR(date)` - Extract year +- `MONTH(date)` - Extract month +- `DAY(date)` - Extract day +- `ADDDAYS(date, days)` - Add days to date + +## Logical Functions +- `IF(condition, true_value, false_value)` - Conditional logic +- `AND(condition1, condition2, ...)` - Logical AND +- `OR(condition1, condition2, ...)` - Logical OR +- `NOT(condition)` - Logical NOT +- `ISBLANK(field)` - Check if field is null/empty +``` + +#### 3. Audit Trail Schema Missing +**Current State:** +- `object.zod.ts` has `trackHistory: z.boolean()` flag +- No schema defining HOW history is tracked +- No field-level change log structure + +**Missing:** +```typescript +// packages/spec/src/data/audit.zod.ts +export const AuditTrailSchema = z.object({ + id: z.string().uuid(), + recordId: z.string(), + objectName: z.string(), + fieldName: z.string().optional(), // Field-level tracking + action: z.enum(['insert', 'update', 'delete', 'undelete', 'view']), + oldValue: z.any().nullable(), + newValue: z.any().nullable(), + userId: z.string(), + timestamp: z.string().datetime(), + ipAddress: z.string().optional(), + userAgent: z.string().optional(), + metadata: z.record(z.any()).optional(), +}) + +export const AuditConfigSchema = z.object({ + retentionDays: z.number().default(180), // GDPR compliance (6 months) + trackViews: z.boolean().default(false), // Track read access for sensitive data + excludeFields: z.array(z.string()).optional(), // Exclude password fields + archiveToS3: z.boolean().default(false), // Cold storage for old audits +}) +``` + +**Industry Comparison:** +- Salesforce: Field History Tracking (tracks up to 20 fields per object, 18-24 months) +- ServiceNow: Audit Log tracks all changes with before/after values +- AWS CloudTrail: 90 days by default, unlimited with S3 archival + +#### 4. Cascade Delete Semantics Incomplete (field.zod.ts) +**Current State:** +```typescript +deleteBehavior: z.enum(['set_null', 'cascade', 'restrict']) +``` + +**Missing:** +- Soft delete tracking (mark as deleted but keep in DB) +- Cascade soft delete (parent deleted → children also soft-deleted) +- Undelete support (restore soft-deleted records) + +**Recommendation:** +```typescript +deleteBehavior: z.enum([ + 'set_null', // Parent deleted → set child FK to null + 'cascade', // Parent deleted → hard delete children + 'restrict', // Prevent delete if children exist + 'soft_cascade', // Parent soft-deleted → soft delete children + 'archive', // Parent deleted → move children to archive table +]) + +export const SoftDeleteConfigSchema = z.object({ + enabled: z.boolean(), + deletedAtField: z.string().default('deleted_at'), + deletedByField: z.string().default('deleted_by'), + retentionDays: z.number().default(30), // Auto-purge after 30 days +}) +``` + +--- + +## 2️⃣ UI PROTOCOL (ObjectUI) - Deep Dive + +### ✅ Strengths + +#### Navigation System (app.zod.ts) +- **Recursive navigation tree**: ObjectNavItem, DashboardNavItem, PageNavItem, URLNavItem, GroupNavItem +- **Proper hierarchy**: Supports nested groups for complex menu structures +- **Branding support**: Logo, colors, favicon + +#### View Configurations (view.zod.ts) +- **ListView types**: Grid, Kanban, Calendar, Gantt, Map, Timeline +- **FormView layouts**: Simple, Tabbed, Wizard with multi-step workflows +- **Proper field ordering**: Section-based layouts with column counts + +#### Dashboard System (dashboard.zod.ts) +- **Grid layout**: 12-column system with row/col positioning +- **Widget types**: Metric, Bar Chart, Line Chart, Pie Chart, Funnel, Table, Custom HTML +- **Refresh intervals**: Auto-refresh support for real-time dashboards + +#### Theme System (theme.zod.ts) +- **Comprehensive**: Colors, typography, spacing, breakpoints, animations, shadows, borders, z-index scales +- **Dark mode support**: `mode: 'light' | 'dark'` +- **Design tokens**: Properly structured for consistent UI + +#### Actions (action.zod.ts) +- **Action types**: Script, URL, Modal, Screen Flow, Quick Actions +- **Locations**: list_toolbar, record_header, record_detail, record_more +- **Proper metadata**: Label, icon, color, tooltip + +### ⚠️ Gaps and Missing Features + +#### 1. Page Component Schema Missing (page.zod.ts) +**Current State:** +- `page.zod.ts` file exists but is minimal (only PageNavItem reference) +- No FlexiPage-style layout system +- No component library definition + +**Missing:** +```typescript +// packages/spec/src/ui/page.zod.ts +export const PageRegionSchema = z.object({ + name: z.string(), + type: z.enum(['header', 'sidebar', 'main', 'footer']), + width: z.number().optional(), // Grid columns (1-12) + components: z.array(PageComponentSchema), +}) + +export const PageComponentSchema = z.discriminatedUnion('type', [ + // Standard components + z.object({ type: z.literal('record_detail'), objectName: z.string(), recordId: z.string() }), + z.object({ type: z.literal('related_list'), objectName: z.string(), relationshipName: z.string() }), + z.object({ type: z.literal('dashboard_widget'), widgetId: z.string() }), + z.object({ type: z.literal('report'), reportId: z.string() }), + + // Custom components + z.object({ type: z.literal('custom_html'), html: z.string() }), + z.object({ type: z.literal('iframe'), url: z.string() }), + z.object({ type: z.literal('visualforce'), pageName: z.string() }), +]) + +export const PageSchema = z.object({ + name: z.string(), + label: z.string(), + objectName: z.string().optional(), // Object-specific page + type: z.enum(['record', 'home', 'app', 'utility']), + regions: z.array(PageRegionSchema), + permissions: z.array(z.string()).optional(), // Role names with access +}) +``` + +**Industry Comparison:** +- Salesforce Lightning Pages: 3-column regions (header, left, main, right, footer) +- ServiceNow: UI Policies + Client Scripts for dynamic forms + +#### 2. Report Schema Incomplete (report.zod.ts) +**Current State:** +- Basic report types (tabular, summary, matrix, chart) defined +- No grouping/subtotals documentation + +**Missing:** +```typescript +export const ReportGroupingSchema = z.object({ + field: z.string(), + sortOrder: z.enum(['asc', 'desc']), + dateGrouping: z.enum(['day', 'week', 'month', 'quarter', 'year']).optional(), + subtotals: z.array(z.object({ + field: z.string(), + function: z.enum(['sum', 'avg', 'count', 'min', 'max', 'median']), + })), +}) + +export const ReportFilterSchema = z.object({ + field: z.string(), + operator: z.enum(['equals', 'not_equals', 'greater_than', 'less_than', 'contains', 'starts_with', 'in', 'between']), + value: z.any(), + filterLogic: z.string().optional(), // "1 AND (2 OR 3)" +}) + +export const ReportSchema = z.object({ + // ... existing fields + groupings: z.array(ReportGroupingSchema).max(3), // Max 3 levels + filters: z.array(ReportFilterSchema), + crossFilters: z.array(z.object({ + relatedObject: z.string(), + hasRecords: z.boolean(), // "Has Opportunities" vs "Has No Opportunities" + })), + customSummaryFormulas: z.array(z.object({ + name: z.string(), + formula: z.string(), // e.g., "SUM(amount) / COUNT(id)" + })), +}) +``` + +#### 3. Widget Component Props Minimal (widget.zod.ts) +**Current State:** +- Basic widget schema exists +- No reusable component patterns + +**Missing:** +- Custom field widget definitions (star rating, color picker) +- Component prop validation schemas +- Widget lifecycle hooks (onInit, onChange, onDestroy) + +**Recommendation:** +```typescript +export const FieldWidgetSchema = z.object({ + name: z.string(), // "star_rating", "color_picker", "rich_text_editor" + label: z.string(), + fieldTypes: z.array(z.string()), // Compatible field types + props: z.record(z.any()), // Component-specific props + + // Lifecycle hooks (optional) + onInit: z.string().optional(), // JavaScript code + onChange: z.string().optional(), + onDestroy: z.string().optional(), + + // Validation + validateProps: z.function().optional(), +}) +``` + +#### 4. Mobile-Specific Layouts Missing +**Current State:** +- Theme has breakpoints but no mobile layout guidance +- No responsive behavior hints + +**Missing:** +```typescript +export const MobileLayoutConfigSchema = z.object({ + enabled: z.boolean(), + collapseSidebar: z.boolean(), + stackColumns: z.boolean(), // Form columns stack vertically + hideFields: z.array(z.string()).optional(), // Fields to hide on mobile + mobileActions: z.array(z.string()).optional(), // Actions available on mobile +}) +``` + +#### 5. Naming Inconsistencies +**Issue:** +- Navigation uses `objectName` but other schemas use `name` + separate `type` field +- Form section columns use string values `'1', '2', '3', '4'` transformed to numbers (awkward) + +**Recommendation:** +- Standardize on `camelCase` for ALL config keys +- Use numeric types directly: `columns: z.number().min(1).max(4)` + +--- + +## 3️⃣ SYSTEM PROTOCOL (ObjectOS) - Deep Dive + +### ✅ Strengths + +#### Manifest System (manifest.zod.ts) +- **Complete plugin lifecycle**: Dependencies, permissions, configuration schema +- **Contribution points**: Kinds, events, menus, translations +- **Version management**: Semver compliance + +#### Identity & Auth (identity.zod.ts, auth.zod.ts) +- **User schema**: Proper user model with email, roles, status +- **Auth protocols**: OAuth2, OIDC, SAML, JWT, MFA +- **Session management**: Device fingerprinting, session timeout + +#### Plugin Context (plugin.zod.ts) +- **Comprehensive context**: ql, os, logger, storage, i18n, metadata, events, app (router/scheduler) +- **Proper isolation**: Plugins cannot interfere with each other + +#### Datasource & Drivers (datasource.zod.ts, driver.zod.ts) +- **Driver capabilities**: Transactions, filters, aggregations, joins, full-text search, window functions, subqueries +- **Connection pooling**: Min/max connections, timeout settings +- **SSL support**: Certificate validation options + +#### API Endpoints (api.zod.ts) +- **Path-based routing**: REST conventions +- **Rate limiting**: Per-endpoint throttling +- **Caching**: HTTP cache headers + +#### Webhooks (webhook.zod.ts) +- **Outbound**: Object-scoped triggers (onCreate, onUpdate, onDelete) +- **Inbound**: Receiver endpoints with HMAC/JWT verification + +#### Events (events.zod.ts) +- **Event bus**: Metadata, handlers, routes, persistence config +- **Async processing**: Queue-based event distribution + +### ⚠️ Critical Gaps + +#### 1. ❌ Audit Log Schema Missing +**Impact:** Cannot achieve SOX, HIPAA, GDPR compliance without audit trail + +**Required:** +```typescript +// packages/spec/src/system/audit.zod.ts +export const AuditLogSchema = z.object({ + id: z.string().uuid(), + + // WHO + actor: z.object({ + userId: z.string(), + username: z.string(), + roleId: z.string(), + impersonating: z.boolean().default(false), // Admin acting as another user + }), + + // WHAT + action: z.enum([ + 'create', 'read', 'update', 'delete', 'undelete', + 'export', 'import', 'bulk_update', 'bulk_delete', + 'login', 'logout', 'login_failed', 'password_reset', + 'permission_granted', 'permission_revoked', + 'role_assigned', 'role_removed', + 'api_key_created', 'api_key_revoked', + ]), + + // WHERE + resource: z.object({ + type: z.enum(['record', 'object', 'field', 'user', 'role', 'permission', 'api_key']), + objectName: z.string().optional(), + recordId: z.string().optional(), + fieldName: z.string().optional(), + }), + + // WHEN + timestamp: z.string().datetime(), + + // CONTEXT + metadata: z.object({ + ipAddress: z.string(), + userAgent: z.string(), + requestId: z.string(), + sessionId: z.string(), + oldValue: z.any().nullable(), + newValue: z.any().nullable(), + changeReason: z.string().optional(), // User-provided reason for audit trail + }), +}) + +export const AuditConfigSchema = z.object({ + enabled: z.boolean(), + retentionDays: z.number().default(180), // 6 months for GDPR + archiveAfterDays: z.number().default(90), // Move to cold storage + trackReads: z.boolean().default(false), // Track read access (expensive!) + excludeObjects: z.array(z.string()).optional(), // Don't audit these objects + alertOnSuspiciousActivity: z.boolean().default(true), + suspiciousPatterns: z.array(z.object({ + name: z.string(), + condition: z.string(), // Formula: "COUNT(login_failed) > 5 IN LAST 10 MINUTES" + alertRecipients: z.array(z.string()), + })).optional(), +}) +``` + +**Industry Comparison:** +- Salesforce: Field History Tracking (20 fields/object, 18-24 months) +- ServiceNow: Audit Log with before/after values +- Kubernetes: Audit Policy with multiple backends (logs, webhooks, files) + +#### 2. ❌ Multi-Tenancy Isolation Strategy Missing +**Current State:** +- `tenant.zod.ts` file exists with basic tenant schema +- No isolation strategy documentation (row-level vs schema-level) + +**Missing:** +```typescript +// packages/spec/src/system/tenant.zod.ts (EXPAND) +export const TenantSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + slug: z.string(), // tenant1.objectstack.com + + // Isolation Strategy + isolation: z.object({ + strategy: z.enum(['row_level', 'schema_level', 'database_level']), + + // Row-level: Add tenant_id to every table + tenantIdColumn: z.string().default('tenant_id'), + + // Schema-level: CREATE SCHEMA tenant_123 + schemaPrefix: z.string().default('tenant_'), + + // Database-level: CREATE DATABASE tenant_123_db + databasePrefix: z.string().default('tenant_'), + }), + + // Resource Quotas + quotas: z.object({ + maxUsers: z.number().default(100), + maxRecords: z.number().default(1000000), + maxStorageGb: z.number().default(100), + maxApiCallsPerMonth: z.number().default(1000000), + maxConcurrentJobs: z.number().default(10), + }), + + // Feature Flags + features: z.object({ + enableAI: z.boolean().default(false), + enableAPI: z.boolean().default(true), + enableWebhooks: z.boolean().default(true), + enableRealtime: z.boolean().default(false), + }), + + // Status + status: z.enum(['active', 'suspended', 'trial', 'churned']), + trialEndsAt: z.string().datetime().optional(), + createdAt: z.string().datetime(), +}) + +export const TenantIsolationPolicySchema = z.object({ + enforceRLS: z.boolean().default(true), // PostgreSQL Row-Level Security + preventCrossTenantQueries: z.boolean().default(true), + auditCrossTenantAttempts: z.boolean().default(true), +}) +``` + +**Industry Best Practices:** +- **Row-Level (Most Common):** Add `tenant_id` to every table + PostgreSQL RLS + - ✅ Pros: Easy backups, cost-efficient, simple migrations + - ❌ Cons: Risk of data leakage if RLS misconfigured +- **Schema-Level:** Separate schema per tenant + - ✅ Pros: Better isolation, easier to debug + - ❌ Cons: Complex backups, schema migrations expensive +- **Database-Level:** Separate DB per tenant + - ✅ Pros: Perfect isolation, regulatory compliance + - ❌ Cons: Expensive, connection pool limits + +**Recommendation:** Default to **Row-Level with PostgreSQL RLS**, offer Schema-Level for enterprise tier. + +#### 3. ⚠️ License & Quota Enforcement Minimal +**Current State:** +- `license.zod.ts` has basic license types but no quota enforcement model + +**Missing:** +```typescript +// packages/spec/src/system/license.zod.ts (EXPAND) +export const LicenseQuotaSchema = z.object({ + // API Quotas + apiCallsPerMonth: z.number(), + apiCallsPerMinute: z.number().default(100), // Rate limiting + + // Storage Quotas + maxStorageGb: z.number(), + maxFileUploadMb: z.number().default(10), + + // User Quotas + maxUsers: z.number(), + maxConcurrentSessions: z.number().default(1000), + + // Data Quotas + maxRecordsPerObject: z.number().default(1000000), + maxObjectsPerTenant: z.number().default(100), + + // AI Quotas (if AI enabled) + maxAiCallsPerMonth: z.number().optional(), + maxTokensPerMonth: z.number().optional(), + + // Automation Quotas + maxWorkflowsPerObject: z.number().default(10), + maxFlowsPerTenant: z.number().default(100), +}) + +export const QuotaUsageSchema = z.object({ + tenantId: z.string(), + period: z.string(), // "2024-01" (monthly) + + apiCallsUsed: z.number(), + storageGbUsed: z.number(), + usersActive: z.number(), + recordsTotal: z.number(), + + // Warnings + quotaWarnings: z.array(z.object({ + type: z.string(), // "api_calls_90_percent" + threshold: z.number(), + message: z.string(), + })), +}) +``` + +#### 4. ⚠️ Job Scheduler Minimal (job.zod.ts) +**Current State:** +- Basic job schema exists +- No retry logic, failure handlers, or job dependencies + +**Missing:** +```typescript +// packages/spec/src/system/job.zod.ts (EXPAND) +export const JobRetryPolicySchema = z.object({ + maxRetries: z.number().default(3), + retryDelaySeconds: z.number().default(60), + backoffStrategy: z.enum(['linear', 'exponential', 'fibonacci']), + retryableErrors: z.array(z.string()).optional(), // Retry only on specific error codes +}) + +export const JobDependencySchema = z.object({ + dependsOn: z.array(z.string()), // Job IDs that must complete first + waitForAll: z.boolean().default(true), // Wait for all or any one +}) + +export const JobSchema = z.object({ + // ... existing fields + retryPolicy: JobRetryPolicySchema.optional(), + dependencies: JobDependencySchema.optional(), + + timeout: z.number().optional(), // Max execution time (seconds) + onSuccess: z.string().optional(), // Webhook URL on success + onFailure: z.string().optional(), // Webhook URL on failure + + priority: z.enum(['low', 'normal', 'high', 'critical']).default('normal'), + + // Dead letter queue + deadLetterQueue: z.object({ + enabled: z.boolean(), + maxRetries: z.number().default(3), + archiveAfterDays: z.number().default(7), + }).optional(), +}) +``` + +#### 5. ⚠️ Policy Evaluation Logic Unclear (policy.zod.ts) +**Current State:** +- `policy.zod.ts` defines policies but no evaluation order documentation + +**Missing:** +How do permissions + sharing rules + policies interact? + +```markdown +# Policy Evaluation Order + +1. **Object-Level Permission** (role.zod.ts) + - Does user's role allow CRUD on this object? + - ❌ No → Return 403 Forbidden + +2. **Sharing Rules** (sharing.zod.ts) + - Is record owned by user or shared with them? + - ❌ No → Return 404 Not Found (hide existence) + +3. **Field-Level Security** (permission.zod.ts) + - Which fields can user read/write? + - Filter out restricted fields + +4. **Territory Hierarchy** (territory.zod.ts) + - Does user's territory include this record's region? + - ❌ No → Deny access + +5. **Global Policies** (policy.zod.ts) + - Data retention policies (e.g., "No access to records > 7 years old") + - Data classification policies (e.g., "Cannot export PII to Excel") + - ❌ Violates policy → Deny access + +6. **Validation Rules** (validation.zod.ts) + - Conditional visibility (e.g., "Show SSN only if country = USA") + +✅ All checks passed → Return record with allowed fields +``` + +#### 6. ⚠️ Real-time Sync Minimal (realtime.zod.ts) +**Current State:** +- Basic schema exists but no subscription management or conflict resolution + +**Missing:** +```typescript +// packages/spec/src/system/realtime.zod.ts (EXPAND) +export const RealtimeSubscriptionSchema = z.object({ + id: z.string().uuid(), + userId: z.string(), + objectName: z.string(), + filters: z.array(FilterSchema).optional(), // Only listen to matching records + events: z.array(z.enum(['create', 'update', 'delete'])), + + // Conflict resolution + conflictResolution: z.enum(['last_write_wins', 'first_write_wins', 'manual']).default('last_write_wins'), +}) + +export const RealtimeEventSchema = z.object({ + id: z.string().uuid(), + objectName: z.string(), + recordId: z.string(), + action: z.enum(['create', 'update', 'delete']), + data: z.record(z.any()), + timestamp: z.string().datetime(), + userId: z.string(), + + // Conflict detection + version: z.number(), // Optimistic locking + previousVersion: z.number().optional(), +}) +``` + +--- + +## 4️⃣ AI PROTOCOL - Deep Dive + +### ✅ Strengths + +#### Agent Definition (agent.zod.ts) +- **Complete agent config**: Instructions, model config (OpenAI/Anthropic/Azure), tools, knowledge, access control +- **Tool integration**: References action/flow/query/vector_search + +#### RAG Pipeline (rag-pipeline.zod.ts) +- **Comprehensive**: Embedding models, vector stores (Pinecone, Weaviate, Qdrant), chunking strategies, retrieval methods (similarity, MMR, hybrid, parent_document) +- **Proper metadata**: Token tracking, relevance scoring + +#### NLQ (nlq.zod.ts) +- **Intent detection**: Entity recognition, field mapping, timeframe handling +- **Confidence scoring**: Certainty levels for generated queries + +#### Model Registry (model-registry.zod.ts) +- **Model definitions**: Provider, dimensions, batch size, context window + +### ⚠️ Critical Gaps - AI Safety & Compliance + +#### 1. ❌ Agent Memory & Conversation State Missing +**Current State:** +- No schema for multi-turn conversation tracking +- No token budget management + +**Missing:** +```typescript +// packages/spec/src/ai/conversation.zod.ts +export const ConversationMessageSchema = z.object({ + id: z.string().uuid(), + role: z.enum(['user', 'assistant', 'system', 'tool']), + content: z.string(), + timestamp: z.string().datetime(), + + // Token tracking + promptTokens: z.number().optional(), + completionTokens: z.number().optional(), + totalTokens: z.number().optional(), + + // Tool calls + toolCalls: z.array(z.object({ + id: z.string(), + toolName: z.string(), + arguments: z.record(z.any()), + result: z.any().optional(), + })).optional(), +}) + +export const ConversationSchema = z.object({ + id: z.string().uuid(), + agentId: z.string(), + userId: z.string(), + messages: z.array(ConversationMessageSchema), + + // Token budget + tokenBudget: z.object({ + maxTokensPerMessage: z.number().default(4000), + maxTokensPerConversation: z.number().default(128000), + totalTokensUsed: z.number(), + estimatedCostUsd: z.number(), + }), + + // Conversation state + status: z.enum(['active', 'completed', 'failed', 'timeout']), + metadata: z.record(z.any()).optional(), +}) +``` + +#### 2. ❌ AI Safety & Guardrails Missing +**Impact:** Risk of hallucinations, prompt injection, data leakage + +**Missing:** +```typescript +// packages/spec/src/ai/safety.zod.ts +export const SafetyGuardrailSchema = z.object({ + name: z.string(), + type: z.enum([ + 'prompt_injection_detection', // Detect malicious prompts + 'pii_detection', // Prevent PII leakage + 'hallucination_detection', // Check for factual errors + 'output_validation', // Validate generated code/queries + 'content_moderation', // Block offensive content + 'jailbreak_prevention', // Prevent system prompt overrides + ]), + + enabled: z.boolean(), + action: z.enum(['block', 'warn', 'log']), + threshold: z.number().min(0).max(1).optional(), // Confidence threshold + + // Custom validation + validationScript: z.string().optional(), // JavaScript validator +}) + +export const SafetyConfigSchema = z.object({ + guardrails: z.array(SafetyGuardrailSchema), + + // PII Protection + piiProtection: z.object({ + enabled: z.boolean(), + redactFromPrompts: z.boolean().default(true), + redactFromResponses: z.boolean().default(true), + allowedPiiTypes: z.array(z.enum(['email', 'phone', 'ssn', 'credit_card'])).optional(), + }), + + // Output Validation + outputValidation: z.object({ + validateSQLQueries: z.boolean().default(true), // Check for SQL injection + validateJavaScript: z.boolean().default(true), // Check for XSS + allowedFunctions: z.array(z.string()).optional(), // Whitelist functions + }), + + // Rate Limiting + rateLimiting: z.object({ + maxRequestsPerMinute: z.number().default(10), + maxTokensPerHour: z.number().default(100000), + }), +}) +``` + +**Industry Comparison:** +- OpenAI Moderation API: Detects harmful content +- Anthropic Constitutional AI: Rule-based safety constraints +- Google Perspective API: Toxicity detection + +#### 3. ⚠️ Tool Calling Format Inconsistent +**Current State:** +- AIToolSchema references 'action', 'flow', 'query', 'vector_search' but not OpenAI standard format + +**Missing:** +```typescript +// packages/spec/src/ai/tool.zod.ts +export const AIToolCallSchema = z.object({ + id: z.string(), // Unique call ID + type: z.literal('function'), + function: z.object({ + name: z.string(), + arguments: z.string(), // JSON string + }), +}) + +export const AIToolResultSchema = z.object({ + toolCallId: z.string(), + output: z.any(), + error: z.string().optional(), +}) + +export const AIToolDefinitionSchema = z.object({ + type: z.literal('function'), + function: z.object({ + name: z.string(), + description: z.string(), + parameters: z.object({ + type: z.literal('object'), + properties: z.record(z.any()), + required: z.array(z.string()).optional(), + }), + }), +}) +``` + +**Align with OpenAI/Claude standard:** +```json +{ + "tools": [ + { + "type": "function", + "function": { + "name": "query_records", + "description": "Query ObjectStack records", + "parameters": { + "type": "object", + "properties": { + "objectName": { "type": "string" }, + "filters": { "type": "array" } + }, + "required": ["objectName"] + } + } + } + ] +} +``` + +#### 4. ⚠️ Cost Tracking & Budgeting Missing +**Current State:** +- RAG pipeline tracks tokens but no cost calculation + +**Missing:** +```typescript +// packages/spec/src/ai/cost.zod.ts +export const ModelPricingSchema = z.object({ + modelId: z.string(), + provider: z.enum(['openai', 'anthropic', 'azure', 'google', 'cohere']), + + pricing: z.object({ + promptTokensPer1k: z.number(), // USD per 1000 prompt tokens + completionTokensPer1k: z.number(), // USD per 1000 completion tokens + embeddingPer1k: z.number().optional(), + fineTuningPer1k: z.number().optional(), + }), +}) + +export const UsageCostSchema = z.object({ + tenantId: z.string(), + period: z.string(), // "2024-01" + + breakdown: z.array(z.object({ + modelId: z.string(), + promptTokens: z.number(), + completionTokens: z.number(), + totalCostUsd: z.number(), + })), + + totalCostUsd: z.number(), + budgetLimitUsd: z.number().optional(), + budgetAlertThreshold: z.number().default(0.9), // Alert at 90% +}) +``` + +--- + +## 5️⃣ API PROTOCOL - Deep Dive + +### ✅ Strengths + +- **Standard CRUD**: Create, Update, Delete, Get, List with proper envelopes +- **Bulk operations**: bulkCreate, bulkUpdate, bulkUpsert, bulkDelete with transaction support +- **Error model**: Code, message, details for structured errors +- **Metadata**: Response includes timestamp, duration, requestId, traceId + +### ⚠️ Gaps + +#### 1. Cursor-Based Pagination Missing +**Current State:** +- Offset-based pagination: `total`, `limit`, `offset`, `hasMore` + +**Missing:** +```typescript +export const CursorPaginationSchema = z.object({ + cursor: z.string().optional(), // Opaque cursor (base64-encoded) + limit: z.number().min(1).max(100).default(25), + hasMore: z.boolean(), + nextCursor: z.string().optional(), +}) +``` + +**Why cursor pagination?** +- Offset pagination breaks with concurrent writes (page drift) +- Cursor pagination is stable and performant for large datasets + +#### 2. Field Projection Missing +**Current State:** +- No schema for sparse fieldsets + +**Missing:** +```typescript +export const FieldProjectionSchema = z.object({ + fields: z.array(z.string()).optional(), // ["id", "name", "email"] + exclude: z.array(z.string()).optional(), // Exclude specific fields +}) + +// Usage: GET /api/account/123?fields=name,email,phone +``` + +#### 3. API Versioning Strategy Missing +**Current State:** +- No version schema + +**Missing:** +```typescript +export const ApiVersionSchema = z.object({ + version: z.string(), // "v1", "v2" + deprecated: z.boolean().default(false), + sunsetDate: z.string().datetime().optional(), // When version will be removed + + versioningStrategy: z.enum(['header', 'url', 'query']), + // Header: X-API-Version: v1 + // URL: /api/v1/account/123 + // Query: /api/account/123?version=v1 +}) +``` + +#### 4. Partial Success in Bulk Operations +**Current State:** +- Bulk operations have `allOrNone: boolean` flag but no partial success semantics + +**Missing:** +```typescript +export const BulkOperationResultSchema = z.object({ + success: z.boolean(), + processed: z.number(), + failed: z.number(), + + results: z.array(z.object({ + id: z.string().optional(), + success: z.boolean(), + error: z.object({ + code: z.string(), + message: z.string(), + }).optional(), + })), + + // Partial success handling + allOrNone: z.boolean().default(true), + rollbackOnError: z.boolean().default(true), +}) +``` + +--- + +## 6️⃣ CROSS-CUTTING CONCERNS + +### Naming Convention Issues + +| Location | Issue | Example | Recommendation | +|----------|-------|---------|----------------| +| `app.zod.ts` | Uses `objectName` | `ObjectNavItem.objectName` | Use `name` + `type` pattern | +| `view.zod.ts` | Form section columns use strings | `columns: '1', '2', '3', '4'` transformed to numbers | Use `z.number()` directly | +| `field.zod.ts` | Mixes camelCase and snake_case | `defaultValue` (config) vs `name` (machine) | ✅ Correct, keep it | + +### Circular Dependencies +- `validation.zod.ts` → `field.zod.ts` +- `permission.zod.ts` → `object.zod.ts` +- Generally safe but watch for import cycles + +### Documentation Quality + +| Module | JSDoc Coverage | Examples | Recommendation | +|--------|---------------|----------|----------------| +| Data Protocol | 80% | Good | Add formula function docs | +| UI Protocol | 60% | Minimal | Add page component examples | +| System Protocol | 70% | Good | Add policy evaluation flow | +| AI Protocol | 50% | Minimal | Add safety guideline examples | +| API Protocol | 80% | Good | Add versioning examples | + +--- + +## 📋 Summary Tables + +### Completion by Protocol File + +| File | Status | Completeness | Critical Gaps | +|------|--------|--------------|---------------| +| `field.zod.ts` | 🟢 Mature | 90% | Formula function docs | +| `object.zod.ts` | 🟢 Mature | 85% | Audit schema | +| `validation.zod.ts` | 🟢 Stable | 90% | None | +| `permission.zod.ts` | 🟢 Stable | 85% | Policy interaction docs | +| `sharing.zod.ts` | 🟢 Stable | 90% | None | +| `workflow.zod.ts` | 🟡 Active | 70% | More action types | +| `trigger.zod.ts` | 🟡 Active | 75% | None | +| `flow.zod.ts` | 🟢 Stable | 85% | None | +| `query.zod.ts` | 🟢 Mature | 90% | None | +| `dataset.zod.ts` | 🟢 Stable | 85% | None | +| `mapping.zod.ts` | 🟢 Stable | 85% | None | +| `app.zod.ts` | 🟢 Stable | 85% | Naming consistency | +| `view.zod.ts` | 🟢 Stable | 80% | Mobile layouts | +| `dashboard.zod.ts` | 🟢 Stable | 85% | None | +| `report.zod.ts` | 🟡 Active | 60% | Grouping/subtotals | +| `action.zod.ts` | 🟢 Stable | 85% | None | +| `page.zod.ts` | 🔴 Minimal | 20% | FlexiPage schema | +| `theme.zod.ts` | 🟢 Mature | 90% | None | +| `widget.zod.ts` | 🟡 Active | 50% | Component props | +| `manifest.zod.ts` | 🟢 Mature | 90% | None | +| `datasource.zod.ts` | 🟢 Stable | 85% | None | +| `driver.zod.ts` | 🟢 Stable | 85% | None | +| `api.zod.ts` | 🟢 Stable | 80% | Rate limiting details | +| `identity.zod.ts` | 🟢 Stable | 85% | None | +| `auth.zod.ts` | 🟢 Mature | 90% | None | +| `role.zod.ts` | 🟢 Stable | 85% | None | +| `policy.zod.ts` | 🟡 Active | 60% | Evaluation order docs | +| `tenant.zod.ts` | 🔴 Critical | 40% | Isolation strategy | +| `license.zod.ts` | 🟡 Active | 60% | Quota enforcement | +| `webhook.zod.ts` | 🟢 Stable | 85% | None | +| `events.zod.ts` | 🟢 Stable | 85% | None | +| `realtime.zod.ts` | 🟡 Active | 50% | Subscription mgmt | +| `job.zod.ts` | 🟡 Active | 60% | Retry logic | +| `territory.zod.ts` | 🟢 Stable | 80% | Hierarchy rollup | +| `organization.zod.ts` | 🟢 Stable | 85% | None | +| `translation.zod.ts` | 🟢 Stable | 85% | None | +| `discovery.zod.ts` | 🟢 Stable | 85% | None | +| `plugin.zod.ts` | 🟢 Mature | 90% | None | +| `agent.zod.ts` | 🟢 Stable | 80% | Memory schema | +| `rag-pipeline.zod.ts` | 🟢 Mature | 90% | None | +| `nlq.zod.ts` | 🟢 Stable | 85% | None | +| `model-registry.zod.ts` | 🟢 Stable | 85% | Cost tracking | +| `predictive.zod.ts` | 🟡 Active | 70% | None | +| `workflow-automation.zod.ts` | 🟡 Active | 70% | None | +| `contract.zod.ts` | 🟢 Stable | 80% | Field projection | + +--- + +## 🎯 Next Steps + +See companion document: **[OPTIMIZATION_ROADMAP.md](./OPTIMIZATION_ROADMAP.md)** for detailed implementation plan. + +### Immediate Actions (This Sprint) +1. Create audit log schema (`packages/spec/src/system/audit.zod.ts`) +2. Document multi-tenancy isolation strategy in `tenant.zod.ts` +3. Expand workflow actions to include SMS, webhooks, HTTP callouts +4. Document formula function library + +### Next Sprint +5. Implement page component schema (`page.zod.ts`) +6. Add AI safety guardrails schema (`packages/spec/src/ai/safety.zod.ts`) +7. Expand license quota enforcement +8. Document policy evaluation order + +### Future Quarters +9. Cursor-based pagination +10. Field projection API +11. API versioning strategy +12. Agent memory & conversation schema + +--- + +**Document Status:** ✅ Complete +**Last Updated:** 2026-01-23 +**Next Review:** After Phase 1 Implementation diff --git a/internal/planning/REVIEW_SUMMARY_CN.md b/internal/planning/REVIEW_SUMMARY_CN.md new file mode 100644 index 0000000..d1b2655 --- /dev/null +++ b/internal/planning/REVIEW_SUMMARY_CN.md @@ -0,0 +1,257 @@ +# ObjectStack 协议审查总结 + +> **审查日期**: 2026-01-23 +> **审查范围**: 所有 45+ 协议文件(Data、UI、System、AI、API 五大模块) +> **当前状态**: 75% 完成度 - 具备生产就绪基础,但存在关键缺口 + +--- + +## 📊 执行摘要 + +### 总体评估 +ObjectStack 协议展现出**强大的基础架构**,核心数据层和 UI 组件实现优秀。但是,**关键企业功能**(审计日志、多租户隔离、AI 安全)需要立即处理,才能投入生产部署。 + +### 各模块完成度 + +| 模块 | 文件数 | 状态 | 完成度 | 生产就绪 | +|------|-------|------|---------|----------| +| **数据协议 (ObjectQL)** | 9 | 🟢 成熟 | 85% | ✅ 是(有缺口)| +| **UI 协议 (ObjectUI)** | 7 | 🟡 活跃 | 75% | ⚠️ 需要页面组件 | +| **系统协议 (ObjectOS)** | 17 | 🟡 活跃 | 70% | ❌ 缺少审计+租户 | +| **AI 协议** | 6 | 🔴 早期 | 50% | ❌ 缺少安全防护 | +| **API 协议** | 1 | 🟢 稳定 | 80% | ✅ 是(需版本控制)| + +--- + +## 🔴 关键优先级(必须立即处理) + +### 1. 审计日志架构(合规阻塞) +**文件**: `packages/spec/src/system/audit.zod.ts`(新建) +**工作量**: 3 天 +**影响**: SOX、HIPAA、GDPR 合规所需 + +**为什么关键**: 没有审计跟踪 = 无法追踪谁在何时做了什么 = 合规失败 + +**功能需求**: +- 记录所有数据操作(创建、读取、更新、删除) +- 记录认证事件(登录、登出、密码重置) +- 记录授权变更(权限授予、角色分配) +- 支持 180 天保留期(GDPR 6 个月要求) +- 可疑活动告警(如:10 分钟内 5 次登录失败) + +--- + +### 2. 多租户隔离策略(安全阻塞) +**文件**: `packages/spec/src/system/tenant.zod.ts`(扩展现有) +**工作量**: 5 天 +**影响**: 安全的多租户、数据隔离 + +**为什么关键**: 当前 tenant.zod.ts 缺少隔离策略文档。存在跨租户数据泄露风险。 + +**需要文档化三种隔离策略**: +1. **行级隔离**(推荐):每个表添加 tenant_id + PostgreSQL RLS + - ✅ 优点:简单备份、成本效益高、易于迁移 + - ❌ 缺点:RLS 配置错误可能导致数据泄露 + +2. **模式级隔离**(企业版):为每个租户创建独立 schema + - ✅ 优点:更好隔离、易于调试 + - ❌ 缺点:复杂备份、迁移成本高 + +3. **数据库级隔离**(受监管行业):为每个租户创建独立数据库 + - ✅ 优点:完美隔离、符合监管要求 + - ❌ 缺点:昂贵、连接池限制 + +--- + +### 3. AI 安全防护(AI 安全阻塞) +**文件**: `packages/spec/src/ai/safety.zod.ts`(新建) +**工作量**: 5 天 +**影响**: 防止提示注入、PII 泄露、幻觉 + +**为什么关键**: 没有安全防护的 AI 功能 = 安全漏洞、数据泄露、合规违规 + +**需要的防护措施**: +1. **提示注入检测**: 检测恶意提示 +2. **PII 检测**: 防止个人信息泄露(邮箱、电话、SSN、信用卡) +3. **幻觉检测**: 检查事实错误 +4. **输出验证**: 验证生成的代码/查询(SQL 注入、XSS 防护) +5. **内容审核**: 阻止攻击性内容 +6. **越狱防护**: 防止系统提示覆盖 + +--- + +## 🟡 高优先级增强(接下来做) + +### 4. 工作流动作扩展 +**文件**: `packages/spec/src/data/workflow.zod.ts` +**工作量**: 3 天 +**当前状态**: 只有字段更新 + 邮件动作 +**目标**: 10+ 动作类型 + +**新增动作类型**: +- SMS 通知(Twilio、Vonage) +- Slack/Teams 消息 +- HTTP 调用(REST API 集成) +- Webhook 触发 +- 任务创建 +- 推送通知 +- 自定义脚本 + +--- + +### 5. 公式函数库文档 +**文件**: `content/docs/references/formula-functions.mdx` +**工作量**: 4 天 +**当前状态**: 公式字段存在但无函数参考 +**目标**: 50+ 函数文档 + +**函数类别**: +- **文本函数**: UPPER、LOWER、CONCATENATE、TEXT、LEN、TRIM +- **数学函数**: SUM、AVERAGE、ROUND、CEILING、FLOOR、ABS、MIN、MAX +- **日期函数**: TODAY、NOW、YEAR、MONTH、DAY、ADDDAYS、TIMEDIFF +- **逻辑函数**: IF、AND、OR、NOT、ISBLANK、CASE +- **查找函数**: LOOKUP、ROLLUP、PARENT +- **高级函数**: REGEX、JSON、HASH、ENCRYPT + +--- + +### 6. 页面组件架构(FlexiPage 替代) +**文件**: `packages/spec/src/ui/page.zod.ts` +**工作量**: 5 天 +**当前状态**: 最小化的 page.zod.ts +**目标**: 15+ 组件类型,Salesforce FlexiPage 风格区域 + +**组件类型**: +- 记录详情、相关列表 +- 仪表板小部件、报表 +- 指标卡、活动时间线 +- 评论、最近项目 +- 自定义 HTML、Markdown、iframe + +--- + +### 7. 报表分组和小计 +**文件**: `packages/spec/src/ui/report.zod.ts` +**工作量**: 3 天 +**目标**: 高级分析功能 + +**功能**: +- 3 级分组支持 +- 小计函数(sum、avg、count、min、max、median) +- 交叉过滤("有机会" vs "无机会") +- 自定义汇总公式 + +--- + +### 8. AI 对话记忆 +**文件**: `packages/spec/src/ai/conversation.zod.ts` +**工作量**: 3 天 +**功能**: 多轮 AI 对话,令牌预算管理 + +--- + +### 9. AI 成本跟踪 +**文件**: `packages/spec/src/ai/cost.zod.ts` +**工作量**: 3 天 +**功能**: 监控和控制 AI API 成本 + +--- + +## 🟢 中等优先级项目 + +### 10. 游标分页(稳定分页) +**文件**: `packages/spec/src/api/contract.zod.ts` +**工作量**: 2 天 + +### 11. 字段投影(稀疏字段集) +**文件**: `packages/spec/src/api/contract.zod.ts` +**工作量**: 2 天 + +### 12. API 版本控制策略 +**文件**: `packages/spec/src/system/api.zod.ts` +**工作量**: 2 天 + +--- + +## 📅 实施时间线 + +### Q1 2026: 基础与合规(第 1-12 周) + +**Sprint 1-2(第 1-4 周): 审计与安全** 🔴 关键 +- [ ] 审计日志架构(SOX/HIPAA/GDPR 合规) +- [ ] 多租户隔离策略(安全) +- [ ] 工作流动作扩展(SMS、webhook 等) +- [ ] 公式函数库文档 + +**Sprint 3-4(第 5-8 周): UI 增强** 🟡 高优先级 +- [ ] 页面组件架构(FlexiPage 替代) +- [ ] 报表分组和小计 +- [ ] 小部件组件属性扩展 +- [ ] 移动布局配置 + +**Sprint 5-6(第 9-12 周): AI 安全与管理** 🔴 关键 +- [ ] AI 安全防护架构 +- [ ] 对话记忆架构 +- [ ] AI 成本跟踪架构 +- [ ] 工具调用格式标准化 + +### Q2-Q4 2026 +详见 `OPTIMIZATION_ROADMAP.md` + +--- + +## 📊 成功指标 + +| 指标 | 审查前 | Q1 2026 目标 | Q2 目标 | Q3 目标 | Q4 目标 | +|------|--------|-------------|---------|---------|---------| +| **协议完成度** | 75% | 85% | 90% | 95% | 98% | +| **生产就绪模块** | 2/5 | 4/5 | 5/5 | 5/5 | 5/5 | +| **合规就绪** | ❌ | ✅ | ✅ | ✅ | ✅ | +| **AI 安全** | ❌ | ✅ | ✅ | ✅ | ✅ | +| **测试覆盖率** | 70% | 80% | 85% | 90% | 95% | +| **文档页面** | 50 | 100 | 150 | 200 | 250 | + +--- + +## 📚 参考文档 + +已创建以下详细文档: + +1. **[PROTOCOL_REVIEW.md](./PROTOCOL_REVIEW.md)** (38KB) + - 所有 45+ 协议的综合评估 + - 按模块详细分析 + - 与行业标准比较(Salesforce、ServiceNow、Kubernetes) + - 缺口识别和建议 + +2. **[OPTIMIZATION_ROADMAP.md](./OPTIMIZATION_ROADMAP.md)** (34KB) + - Q1-Q4 2026 详细实施计划 + - 每个 Sprint 的具体任务 + - 代码示例和实现指南 + - 验收标准 + +3. **[PRIORITIES.md](./PRIORITIES.md)** (已更新) + - 新增关键优先级 + - 更新的 Sprint 规划 + - 更新的成功指标 + +--- + +## 🎯 立即行动项 + +1. **审查文档**: 利益相关者审查 PROTOCOL_REVIEW.md 和 OPTIMIZATION_ROADMAP.md +2. **优先排序**: 确认 Q1 2026 sprint 工作优先级 +3. **开始实施**: 从审计日志架构开始(最高优先级) + +--- + +## ✅ 审查完成 + +- ✅ 审查了 45+ 协议文件 +- ✅ 识别了 3 个关键阻塞项 +- ✅ 识别了 6 个高优先级项 +- ✅ 识别了 10+ 个中等优先级项 +- ✅ 创建了详细的实施路线图(Q1-Q4 2026) +- ✅ 更新了优先级矩阵 +- ✅ 提供了代码示例和验收标准 + +**下一步**: 等待利益相关者批准,然后开始 Q1 2026 Sprint 1 实施。