"use strict";
/**
 * Extended Workflow Schema
 * Extends event-driven schema with complete specifications for code generation
 *
 * This schema includes everything needed to generate:
 * - Database schema and migrations
 * - Backend API with all endpoints
 * - Frontend application with pages and components
 * - Tests for all layers
 * - Complete documentation
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.DocumentationIntentSchema = exports.DocumentationSchema = exports.TechnologySchema = exports.DesignThemeSchema = exports.UIFormSchema = exports.UIPageSchema = exports.APIEndpointSchema = exports.RelationshipSchema = exports.DataModelSchema = exports.FieldDefinitionSchema = exports.FieldTypeSchema = exports.ComponentEventConfigSchema = exports.EventDefinitionSchema = exports.ExtendedWorkflowSchema = void 0;
const zod_1 = require("zod");
/**
 * Event Definition Schema
 * Defines events that can be emitted and consumed throughout the application
 */
const EventDefinitionSchema = zod_1.z.object({
    description: zod_1.z.string().min(1),
    payload: zod_1.z.record(zod_1.z.string(), zod_1.z.enum(['string', 'number', 'boolean', 'array', 'object', 'date'])),
});
exports.EventDefinitionSchema = EventDefinitionSchema;
/**
 * Stack Component Event Config
 * Defines which events a stack component emits or consumes
 */
const ComponentEventConfigSchema = zod_1.z.object({
    emits: zod_1.z.array(zod_1.z.string()).default([]), // Events this component emits
    consumes: zod_1.z.array(zod_1.z.string()).default([]), // Events this component consumes
});
exports.ComponentEventConfigSchema = ComponentEventConfigSchema;
/**
 * Field Type Schema
 * Defines database field types in a database-agnostic way
 */
const FieldTypeSchema = zod_1.z.enum([
    'uuid',
    'string',
    'text',
    'integer',
    'decimal',
    'boolean',
    'timestamp',
    'date',
    'time',
    'json',
    'array',
    'enum',
]);
exports.FieldTypeSchema = FieldTypeSchema;
/**
 * API Access Control Schema
 * Controls who can read/write fields via API
 */
const APIAccessControlSchema = zod_1.z.object({
    read_roles: zod_1.z.array(zod_1.z.string()).optional(), // Roles that can read this field/relation
    write_roles: zod_1.z.array(zod_1.z.string()).optional(), // Roles that can write this field/relation
    include_by_default: zod_1.z.boolean().default(false), // Include in API responses by default
    queryable: zod_1.z.boolean().default(true), // Can be included via ?include=field_name
});
/**
 * Field Definition Schema
 * Complete specification for a data model field
 */
const FieldDefinitionSchema = zod_1.z.object({
    type: FieldTypeSchema,
    required: zod_1.z.boolean().default(false),
    unique: zod_1.z.boolean().default(false),
    default: zod_1.z.any().optional(),
    max_length: zod_1.z.number().optional(), // For string types
    min_length: zod_1.z.number().optional(),
    precision: zod_1.z.number().optional(), // For decimal types
    scale: zod_1.z.number().optional(),
    enum_values: zod_1.z.array(zod_1.z.string()).optional(), // For enum types
    foreign_key: zod_1.z.string().optional(), // References another model
    description: zod_1.z.string().optional(),
    // Form and UI control
    system_field: zod_1.z.boolean().default(false), // System-managed fields (created_at, id, etc.) - excluded from forms
    exclude_from_forms: zod_1.z.boolean().default(false), // Explicitly exclude from generated forms
    form_widget: zod_1.z.string().optional(), // Custom form widget (e.g., "rich-text-editor", "image-upload")
    // API access control for individual fields
    api_access: APIAccessControlSchema.optional(), // Control who can read/write this field via API
});
exports.FieldDefinitionSchema = FieldDefinitionSchema;
/**
 * Index Schema
 * Database indexes for performance
 */
const IndexSchema = zod_1.z.object({
    fields: zod_1.z.array(zod_1.z.string()).min(1),
    unique: zod_1.z.boolean().default(false),
    name: zod_1.z.string().optional(),
});
/**
 * Data Model Schema
 * Defines database tables/collections
 */
const DataModelSchema = zod_1.z.object({
    description: zod_1.z.string().optional(),
    fields: zod_1.z.record(zod_1.z.string(), FieldDefinitionSchema),
    indexes: zod_1.z.array(IndexSchema).optional(),
    timestamps: zod_1.z.boolean().default(true), // Auto-add created_at/updated_at
    soft_delete: zod_1.z.boolean().default(false), // Add deleted_at for soft deletes
});
exports.DataModelSchema = DataModelSchema;
/**
 * Relationship Schema
 * Defines relationships between models
 */
const RelationshipSchema = zod_1.z.object({
    type: zod_1.z.enum(['one_to_one', 'one_to_many', 'many_to_many']),
    from: zod_1.z.string(), // Model name
    to: zod_1.z.string(), // Model name
    through: zod_1.z.string().optional(), // For many_to_many join table
    foreign_key: zod_1.z.string().optional(), // Custom foreign key name
    inverse: zod_1.z.boolean().default(true), // Create inverse relationship (e.g., User.tasks from Task.user_id)
    api_access: APIAccessControlSchema.optional(), // Control API exposure
    description: zod_1.z.string().optional(),
});
exports.RelationshipSchema = RelationshipSchema;
/**
 * API Endpoint Schema
 * Explicit API endpoint definitions (optional - can be inferred from workflows)
 */
const APIEndpointSchema = zod_1.z.object({
    path: zod_1.z.string().min(1),
    method: zod_1.z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']),
    component: zod_1.z.string().min(1), // Must reference a component
    description: zod_1.z.string().optional(),
    // Authentication and authorization
    auth: zod_1.z.enum(['required', 'none']).default('required'),
    roles: zod_1.z.array(zod_1.z.string()).optional(), // REQUIRED if auth: required (e.g., ['admin', 'user'])
    exclude_roles: zod_1.z.array(zod_1.z.string()).optional(), // Roles that cannot access (e.g., ['guest'])
    ownership: zod_1.z.object({
        enabled: zod_1.z.boolean(),
        field: zod_1.z.string().optional(), // Field to check ownership (default: user_id or id)
        override_roles: zod_1.z.array(zod_1.z.string()).optional(), // Roles that bypass ownership check (e.g., ['admin', 'superadmin'])
    }).optional(),
    params: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(), // Path/query params
    body: zod_1.z.string().optional(), // Model name for request body
    response: zod_1.z.string().optional(), // Model name or type for response
    emits: zod_1.z.string().optional(), // Event emitted on success
}).superRefine((data, ctx) => {
    // Validate: if auth is required, roles must be specified
    if (data.auth === 'required' && !data.roles && !data.ownership) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: `Endpoint '${data.method} ${data.path}' has auth: required but no roles specified. Must explicitly define roles (can be empty array []).`,
            path: ['roles'],
        });
    }
});
exports.APIEndpointSchema = APIEndpointSchema;
/**
 * Form Field Schema
 * UI form field specifications
 */
const FormFieldSchema = zod_1.z.object({
    name: zod_1.z.string().min(1),
    type: zod_1.z.enum(['text', 'email', 'password', 'number', 'select', 'checkbox', 'textarea', 'date', 'file']),
    label: zod_1.z.string().min(1),
    placeholder: zod_1.z.string().optional(),
    validation: zod_1.z.string().optional(), // e.g., "required|email|min:8"
    options: zod_1.z.array(zod_1.z.object({ value: zod_1.z.string(), label: zod_1.z.string() })).optional(), // For select fields
    default: zod_1.z.any().optional(),
});
/**
 * UI Form Schema
 * Form definitions for data entry
 */
const UIFormSchema = zod_1.z.object({
    id: zod_1.z.string().min(1),
    title: zod_1.z.string().optional(),
    model: zod_1.z.string().optional(), // Associated data model
    fields: zod_1.z.array(FormFieldSchema),
    submit_label: zod_1.z.string().default('Submit'),
    on_submit: zod_1.z.string().optional(), // Event to emit
});
exports.UIFormSchema = UIFormSchema;
/**
 * Custom Layout Schema
 * For complex layout structures beyond presets
 */
const CustomLayoutSchema = zod_1.z.object({
    type: zod_1.z.enum(['grid', 'flex', 'masonry', 'custom']),
    config: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(), // Layout-specific config (columns, gap, etc.)
    responsive: zod_1.z.boolean().default(true),
    breakpoints: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(), // Responsive breakpoints
});
/**
 * UI Page Schema
 * Page definitions (optional - can be inferred from workflows)
 */
const UIPageSchema = zod_1.z.object({
    path: zod_1.z.string().min(1),
    title: zod_1.z.string().min(1),
    layout: zod_1.z.enum(['grid', 'list', 'detail', 'form', 'dashboard', 'custom']).optional(),
    custom_layout: CustomLayoutSchema.optional(), // For complex layouts like masonry
    auth: zod_1.z.enum(['required', 'optional', 'none']).default('required'),
    components: zod_1.z.array(zod_1.z.string()).optional(), // List of component IDs to include
    data_source: zod_1.z.string().optional(), // API endpoint to fetch data from
});
exports.UIPageSchema = UIPageSchema;
/**
 * Color Scale Schema (Tailwind/Radix style)
 * Full color palette with shades 50-950
 */
const ColorScaleSchema = zod_1.z.object({
    50: zod_1.z.string(),
    100: zod_1.z.string(),
    200: zod_1.z.string(),
    300: zod_1.z.string(),
    400: zod_1.z.string(),
    500: zod_1.z.string(), // Base shade
    600: zod_1.z.string(),
    700: zod_1.z.string(),
    800: zod_1.z.string(),
    900: zod_1.z.string(),
    950: zod_1.z.string(),
});
/**
 * Typography Scale Schema
 * Define heading and text styles
 */
const TypographyScaleSchema = zod_1.z.object({
    h1: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    }),
    h2: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    }),
    h3: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    }),
    h4: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    }),
    h5: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    }),
    h6: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    }),
    body: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
    }),
    body_bold: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
    }).optional(),
    small: zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
    }),
    // Custom typography variants (optional)
    custom: zod_1.z.record(zod_1.z.string(), zod_1.z.object({
        size: zod_1.z.string(),
        weight: zod_1.z.string(),
        line_height: zod_1.z.string().optional(),
        letter_spacing: zod_1.z.string().optional(),
    })).optional(),
});
/**
 * Component Style Schema
 * Per-component styling (radius, spacing, shadows, etc.)
 */
const ComponentStyleSchema = zod_1.z.object({
    radius: zod_1.z.string().optional(), // e.g., "8px", "0.5rem", "md"
    padding: zod_1.z.string().optional(),
    margin: zod_1.z.string().optional(),
    shadow: zod_1.z.string().optional(), // e.g., "sm", "md", "lg", or custom shadow
    border: zod_1.z.string().optional(),
    // Component can define custom properties
    custom: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
});
/**
 * Design Theme Schema
 * Complete design system configuration
 */
const DesignThemeSchema = zod_1.z.object({
    // Full color palette (Tailwind/Radix style)
    colors: zod_1.z.object({
        // Semantic colors (map to palette)
        brand: zod_1.z.string(), // e.g., "blue-600" or specific hex
        primary: zod_1.z.string(), // e.g., "blue-600"
        secondary: zod_1.z.string().optional(),
        accent: zod_1.z.string().optional(),
        success: zod_1.z.string(), // e.g., "green-600"
        warning: zod_1.z.string(), // e.g., "amber-600"
        error: zod_1.z.string(), // e.g., "red-600"
        info: zod_1.z.string().optional(),
        // Neutral colors
        background: zod_1.z.string(), // e.g., "gray-50"
        foreground: zod_1.z.string(), // e.g., "gray-950"
        muted: zod_1.z.string().optional(), // e.g., "gray-100"
        muted_foreground: zod_1.z.string().optional(), // e.g., "gray-500"
        // Full color palette (all colors with shades 50-950)
        palette: zod_1.z.object({
            gray: ColorScaleSchema.optional(),
            red: ColorScaleSchema.optional(),
            orange: ColorScaleSchema.optional(),
            amber: ColorScaleSchema.optional(),
            yellow: ColorScaleSchema.optional(),
            lime: ColorScaleSchema.optional(),
            green: ColorScaleSchema.optional(),
            emerald: ColorScaleSchema.optional(),
            teal: ColorScaleSchema.optional(),
            cyan: ColorScaleSchema.optional(),
            sky: ColorScaleSchema.optional(),
            blue: ColorScaleSchema.optional(),
            indigo: ColorScaleSchema.optional(),
            violet: ColorScaleSchema.optional(),
            purple: ColorScaleSchema.optional(),
            fuchsia: ColorScaleSchema.optional(),
            pink: ColorScaleSchema.optional(),
            rose: ColorScaleSchema.optional(),
            // Allow custom color scales
            custom: zod_1.z.record(zod_1.z.string(), ColorScaleSchema).optional(),
        }).optional(),
    }),
    // Typography system
    typography: zod_1.z.object({
        font_family: zod_1.z.string(), // Base font family
        heading_font: zod_1.z.string().optional(), // Optional separate font for headings
        mono_font: zod_1.z.string().optional(), // Monospace font for code
        scale: TypographyScaleSchema,
    }),
    // Spacing scale (optional - uses Tailwind defaults if not specified)
    spacing: zod_1.z.object({
        xs: zod_1.z.string().optional(), // e.g., "4px"
        sm: zod_1.z.string().optional(), // e.g., "8px"
        md: zod_1.z.string().optional(), // e.g., "16px"
        lg: zod_1.z.string().optional(), // e.g., "24px"
        xl: zod_1.z.string().optional(), // e.g., "32px"
        custom: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
    }).optional(),
    // Border radius scale
    radius: zod_1.z.object({
        none: zod_1.z.string().optional(),
        sm: zod_1.z.string().optional(),
        md: zod_1.z.string().optional(),
        lg: zod_1.z.string().optional(),
        xl: zod_1.z.string().optional(),
        full: zod_1.z.string().optional(),
        custom: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
    }).optional(),
    // Shadow scale
    shadows: zod_1.z.object({
        sm: zod_1.z.string().optional(),
        md: zod_1.z.string().optional(),
        lg: zod_1.z.string().optional(),
        xl: zod_1.z.string().optional(),
        custom: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
    }).optional(),
    // Per-component styling overrides
    components: zod_1.z.record(zod_1.z.string(), ComponentStyleSchema).optional(),
    // Icon library
    icons: zod_1.z.object({
        library: zod_1.z.enum(['lucide', 'heroicons', 'feather', 'phosphor', 'tabler', 'custom']),
        custom_path: zod_1.z.string().optional(), // For custom icon libraries
    }).optional(),
});
exports.DesignThemeSchema = DesignThemeSchema;
/**
 * Development Tools Schema
 * Tools and endpoints for development/testing
 */
const DevelopmentToolsSchema = zod_1.z.object({
    enabled: zod_1.z.boolean().default(true),
    // Database reset/seed operations (bypasses API, direct DB access)
    database_operations: zod_1.z.object({
        reset: zod_1.z.boolean().default(true), // Enable database reset endpoint
        seed: zod_1.z.boolean().default(true), // Enable database seed endpoint
        truncate: zod_1.z.boolean().default(true), // Enable truncate tables endpoint
    }).optional(),
    // Testing helpers
    test_data_generator: zod_1.z.boolean().default(true), // Generate test fixtures
    // Development-only API endpoints
    dev_endpoints: zod_1.z.object({
        health_check: zod_1.z.boolean().default(true),
        database_status: zod_1.z.boolean().default(true),
        clear_cache: zod_1.z.boolean().default(true),
    }).optional(),
});
/**
 * Documentation Intent Schema
 * Declarative documentation generation - specify WHAT, not HOW
 */
const DocumentationIntentSchema = zod_1.z.object({
    type: zod_1.z.enum(['tutorial', 'methodology', 'troubleshooting', 'api_reference', 'setup_guide', 'best_practices', 'architecture']),
    scope: zod_1.z.string().optional(),
    topics: zod_1.z.array(zod_1.z.string()).optional(),
    includeExamples: zod_1.z.boolean().optional().default(false),
    includeCommonIssues: zod_1.z.boolean().optional().default(false),
    audience: zod_1.z.enum(['user', 'developer', 'both']).optional().default('developer'),
    overwrite: zod_1.z.enum(['always', 'if-missing', 'never']).optional().default('always'),
    outputPath: zod_1.z.string().optional(),
});
exports.DocumentationIntentSchema = DocumentationIntentSchema;
/**
 * Documentation Schema
 * Supports both intent-based (declarative) and literal (legacy) approaches
 */
const DocumentationSchema = zod_1.z.object({
    intents: zod_1.z.array(DocumentationIntentSchema).optional(),
    // Legacy literal documentation (deprecated)
    user_docs: zod_1.z.array(zod_1.z.any()).optional(),
    developer_docs: zod_1.z.array(zod_1.z.any()).optional(),
    customSections: zod_1.z.array(zod_1.z.any()).optional(),
});
exports.DocumentationSchema = DocumentationSchema;
/**
 * Technology Stack Schema
 * Specifies concrete technologies to use
 * Made flexible to allow for different technology choices
 */
const TechnologySchema = zod_1.z.object({
    frontend: zod_1.z.object({
        framework: zod_1.z.string().optional(),
        language: zod_1.z.string().optional(),
        styling: zod_1.z.string().optional(),
        state_management: zod_1.z.string().optional(),
    }).optional(),
    backend: zod_1.z.object({
        framework: zod_1.z.string().optional(),
        language: zod_1.z.string().optional(),
        orm: zod_1.z.string().optional(),
        directory: zod_1.z.string().optional(), // Custom output directory for backend
    }).optional(),
    database: zod_1.z.string().optional(), // Simplified to string for flexibility
    cache: zod_1.z.object({
        provider: zod_1.z.string(), // e.g., 'upstash-redis', 'redis', 'memcached'
        use: zod_1.z.enum(['local', 'cloud']).optional(), // Deployment location
        options: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(), // Provider-specific options
    }).optional(),
    testing: zod_1.z.object({
        unit: zod_1.z.string().optional(),
        e2e: zod_1.z.string().optional(),
    }).optional(),
    // Development tools (optional - enabled by default in local/dev stages)
    development: DevelopmentToolsSchema.optional(),
}).passthrough(); // Allow additional properties for future extensibility
exports.TechnologySchema = TechnologySchema;
/**
 * Extended Workflow Schema
 * Defines extended workflow with additional fields for code generation
 * Note: This is a permissive schema that allows EventDriven fields + extended fields
 */
exports.ExtendedWorkflowSchema = zod_1.z.object({
    // Technology choices (OPTIONAL - but recommended)
    technology: TechnologySchema.optional(),
    // Events (OPTIONAL - enables event-driven architecture)
    events: zod_1.z.record(zod_1.z.string(), EventDefinitionSchema).optional(),
    // Data models (OPTIONAL - required for database generation)
    models: zod_1.z.record(zod_1.z.string(), DataModelSchema).optional(),
    // Relationships between models (OPTIONAL - helps with complex relations)
    relationships: zod_1.z.array(RelationshipSchema).optional(),
    // Design system (OPTIONAL - uses defaults if not provided)
    design: zod_1.z.object({
        theme: DesignThemeSchema.optional(),
        component_library: zod_1.z.string().optional(), // e.g., "shadcn/ui", "headlessui"
    }).optional(),
    // API endpoints (OPTIONAL - inferred from workflows if not provided)
    api: zod_1.z.object({
        base_path: zod_1.z.string().default('/api'),
        endpoints: zod_1.z.array(APIEndpointSchema).optional(),
    }).optional(),
    // UI specifications (OPTIONAL - inferred from workflows if not provided)
    ui: zod_1.z.object({
        pages: zod_1.z.array(UIPageSchema).optional(),
        forms: zod_1.z.array(UIFormSchema).optional(),
        navigation: zod_1.z.array(zod_1.z.object({
            label: zod_1.z.string(),
            path: zod_1.z.string(),
            icon: zod_1.z.string().optional(),
            auth: zod_1.z.enum(['required', 'optional', 'none']).default('required'),
        })).optional(),
    }).optional(),
    // Authentication (OPTIONAL)
    auth: zod_1.z.object({
        enabled: zod_1.z.boolean().default(true),
        provider: zod_1.z.enum(['local', 'auth0', 'firebase', 'supabase', 'clerk']).optional(),
        strategies: zod_1.z.array(zod_1.z.enum(['email', 'google', 'github', 'microsoft'])).optional(),
    }).optional(),
    // Documentation (OPTIONAL - intent-based declarative documentation)
    documentation: DocumentationSchema.optional(),
}).passthrough().superRefine((data, ctx) => {
    // Additional validation beyond the base schema
    // Validate model references in relationships
    if (data.relationships && data.models) {
        const modelNames = new Set(Object.keys(data.models));
        data.relationships.forEach((rel, index) => {
            if (!modelNames.has(rel.from)) {
                ctx.addIssue({
                    code: zod_1.z.ZodIssueCode.custom,
                    message: `Relationship references undefined model '${rel.from}'`,
                    path: ['relationships', index, 'from'],
                });
            }
            if (!modelNames.has(rel.to)) {
                ctx.addIssue({
                    code: zod_1.z.ZodIssueCode.custom,
                    message: `Relationship references undefined model '${rel.to}'`,
                    path: ['relationships', index, 'to'],
                });
            }
        });
    }
    // Validate foreign key references in models
    if (data.models) {
        Object.entries(data.models).forEach(([modelName, model]) => {
            Object.entries(model.fields).forEach(([fieldName, field]) => {
                if (field.foreign_key) {
                    if (!Object.keys(data.models).includes(field.foreign_key)) {
                        ctx.addIssue({
                            code: zod_1.z.ZodIssueCode.custom,
                            message: `Field '${fieldName}' in model '${modelName}' references undefined model '${field.foreign_key}'`,
                            path: ['models', modelName, 'fields', fieldName, 'foreign_key'],
                        });
                    }
                }
            });
        });
    }
    // Validate API endpoint components exist
    if (data.api?.endpoints) {
        const componentNames = new Set(data.components ? Object.keys(data.components) : []);
        // Get valid roles from User model
        const userModel = data.models?.User;
        const validRoles = new Set();
        if (userModel) {
            const roleField = userModel.fields.role;
            if (roleField && roleField.type === 'enum' && roleField.enum_values) {
                roleField.enum_values.forEach((role) => validRoles.add(role));
            }
        }
        data.api.endpoints.forEach((endpoint, index) => {
            // Validate component exists (only if components are defined)
            if (componentNames.size > 0 && !componentNames.has(endpoint.component)) {
                ctx.addIssue({
                    code: zod_1.z.ZodIssueCode.custom,
                    message: `API endpoint '${endpoint.method} ${endpoint.path}' references undefined component '${endpoint.component}'`,
                    path: ['api', 'endpoints', index, 'component'],
                });
            }
            // Validate roles exist in User model
            if (validRoles.size > 0) {
                endpoint.roles?.forEach((role) => {
                    if (!validRoles.has(role)) {
                        ctx.addIssue({
                            code: zod_1.z.ZodIssueCode.custom,
                            message: `API endpoint '${endpoint.method} ${endpoint.path}' uses role '${role}' which is not defined in User model's role field. Valid roles: ${Array.from(validRoles).join(', ')}`,
                            path: ['api', 'endpoints', index, 'roles'],
                        });
                    }
                });
                endpoint.exclude_roles?.forEach((role) => {
                    if (!validRoles.has(role)) {
                        ctx.addIssue({
                            code: zod_1.z.ZodIssueCode.custom,
                            message: `API endpoint '${endpoint.method} ${endpoint.path}' excludes role '${role}' which is not defined in User model's role field. Valid roles: ${Array.from(validRoles).join(', ')}`,
                            path: ['api', 'endpoints', index, 'exclude_roles'],
                        });
                    }
                });
                endpoint.ownership?.override_roles?.forEach((role) => {
                    if (!validRoles.has(role)) {
                        ctx.addIssue({
                            code: zod_1.z.ZodIssueCode.custom,
                            message: `API endpoint '${endpoint.method} ${endpoint.path}' ownership override uses role '${role}' which is not defined in User model's role field. Valid roles: ${Array.from(validRoles).join(', ')}`,
                            path: ['api', 'endpoints', index, 'ownership', 'override_roles'],
                        });
                    }
                });
            }
        });
    }
    // Validate UI form models exist
    if (data.ui?.forms && data.models) {
        const modelNames = new Set(Object.keys(data.models));
        data.ui.forms.forEach((form, index) => {
            if (form.model && !modelNames.has(form.model)) {
                ctx.addIssue({
                    code: zod_1.z.ZodIssueCode.custom,
                    message: `Form '${form.id}' references undefined model '${form.model}'`,
                    path: ['ui', 'forms', index, 'model'],
                });
            }
        });
    }
    // Validate event references in API endpoints
    if (data.api?.endpoints && data.events) {
        const definedEvents = new Set(Object.keys(data.events));
        data.api.endpoints.forEach((endpoint, index) => {
            if (endpoint.emits && !definedEvents.has(endpoint.emits)) {
                ctx.addIssue({
                    code: zod_1.z.ZodIssueCode.custom,
                    message: `API endpoint '${endpoint.method} ${endpoint.path}' emits undefined event '${endpoint.emits}'. Define this event in the events section.`,
                    path: ['api', 'endpoints', index, 'emits'],
                });
            }
        });
    }
    // Warn about events that are never emitted or consumed
    if (data.events) {
        const definedEvents = new Set(Object.keys(data.events));
        const emittedEvents = new Set();
        const consumedEvents = new Set();
        // Collect emitted events from API endpoints
        if (data.api?.endpoints) {
            data.api.endpoints.forEach((endpoint) => {
                if (endpoint.emits) {
                    emittedEvents.add(endpoint.emits);
                }
            });
        }
        // Check for events that are defined but never emitted (informational warning)
        definedEvents.forEach((eventName) => {
            if (!emittedEvents.has(eventName) && !consumedEvents.has(eventName)) {
                // This is just a warning, not an error - events might be used in future
                // We'll add this as a console.warn in the parser, not as a validation issue
            }
        });
    }
});
//# sourceMappingURL=extended-workflow-schema.js.map