# Bangstack Enhanced Schema Implementation Plan

## Overview

This document outlines the enhanced YAML schema with top-level structures for cross-cutting concerns, and the implementation strategy for supporting them.

---

## 1. Enhanced Schema Structure

```typescript
// src/types/workflow.ts - ENHANCED VERSION

export interface Workflow {
  // Metadata
  workflow: WorkflowMetadata;
  technology?: Technology;

  // === CROSS-CUTTING CONCERNS (Top-Level) ===
  testing?: Testing;
  monitoring?: Monitoring;
  security?: Security;
  performance?: Performance;
  i18n?: Internationalization;
  feature_flags?: FeatureFlags;
  access_control?: AccessControl;
  api?: ApiConfiguration;
  deployment?: DeploymentConfiguration;
  analytics?: Analytics;

  // === COMPONENTS (Service-Specific) ===
  stack: StackComponents;

  // === DATA LAYER ===
  models?: Models;
  migrations?: Migrations;

  // === BUSINESS LOGIC ===
  workflows?: WorkflowDefinitions;
  events?: Events;

  // === ENVIRONMENTS ===
  stages?: Stages;

  // === LEGACY/OPTIONAL ===
  documentation?: Documentation;
  environment?: Environment;
}

// =============================================
// TOP-LEVEL TYPES (Cross-Cutting Concerns)
// =============================================

/**
 * Testing Configuration
 * Affects: All components
 * Generator: testing-generator.ts
 */
export interface Testing {
  // Test frameworks
  frameworks?: {
    unit?: TestFrameworkConfig;
    integration?: TestFrameworkConfig;
    e2e?: E2ETestConfig;
    component?: TestFrameworkConfig;
  };

  // Coverage requirements
  coverage?: {
    threshold?: {
      global?: CoverageThreshold;
      per_file?: CoverageThreshold;
    };
    exclude?: string[];
  };

  // Database testing strategy
  database?: {
    strategy: 'testcontainers' | 'sqlite' | 'dedicated' | 'mock';
    reset_strategy?: 'truncate' | 'drop_and_recreate';
    fixtures_path?: string;
  };

  // Worker testing
  workers?: {
    strategy: 'mock_queue' | 'test_redis' | 'in_memory';
    auto_process?: boolean;
  };

  // External API mocking
  external_apis?: {
    strategy: 'msw' | 'nock' | 'mock_server';
    handlers_path?: string;
    mock_definitions?: ExternalApiMock[];
  };

  // CI/CD integration
  ci_cd?: {
    provider?: 'github_actions' | 'gitlab_ci' | 'circle_ci';
    test_on_pr?: boolean;
    test_requirements?: {
      require_passing?: boolean;
      minimum_coverage?: number;
    };
  };

  // Test data
  fixtures?: TestFixtures;
  factories?: FactoryConfig;
}

export interface TestFrameworkConfig {
  framework: 'vitest' | 'jest' | 'mocha' | string;
  config?: Record<string, any>;
}

export interface E2ETestConfig extends TestFrameworkConfig {
  framework: 'playwright' | 'cypress' | string;
  browsers?: string[];
  headless?: boolean;
  demo_mode?: DemoModeConfig;
}

export interface DemoModeConfig {
  enabled: boolean;
  narration?: boolean;
  slow_mo?: number;
  recording?: {
    output_path: string;
    formats?: string[];
  };
}

export interface CoverageThreshold {
  statements?: number;
  branches?: number;
  functions?: number;
  lines?: number;
}

export interface ExternalApiMock {
  service: string;
  base_url: string;
  handlers?: ApiHandler[];
  failure_scenarios?: FailureScenario[];
}

export interface ApiHandler {
  endpoint: string;
  response: {
    status: number;
    body: any;
    delay?: number;
  };
}

export interface FailureScenario {
  name: string;
  endpoint: string;
  response: {
    status: number;
    body: any;
  };
}

export interface TestFixtures {
  path: string;
  database_fixtures?: Record<string, any[]>;
  api_fixtures?: Record<string, any>;
}

export interface FactoryConfig {
  enabled: boolean;
  library?: 'fishery' | 'factory-bot' | string;
  definitions?: FactoryDefinition[];
}

export interface FactoryDefinition {
  model: string;
  factory: string; // Code for factory definition
}

/**
 * Monitoring Configuration
 * Affects: All components
 * Generator: monitoring-generator.ts
 */
export interface Monitoring {
  // Application Performance Monitoring
  apm?: {
    provider: 'datadog' | 'new_relic' | 'app_insights' | string;
    config?: Record<string, any>;
  };

  // Error tracking
  error_tracking?: {
    provider: 'sentry' | 'bugsnag' | 'rollbar' | string;
    config?: Record<string, any>;
    frontend?: boolean;
    backend?: boolean;
  };

  // Logging
  logging?: {
    provider: 'winston' | 'pino' | 'bunyan' | string;
    level: 'debug' | 'info' | 'warn' | 'error';
    transports?: LogTransport[];
  };

  // Distributed tracing
  tracing?: {
    provider: 'jaeger' | 'zipkin' | 'datadog' | string;
    sampling_rate?: number;
  };

  // Metrics
  metrics?: {
    tracked: string[];
    custom_metrics?: MetricDefinition[];
  };

  // Alerting
  alerts?: AlertDefinition[];
}

export interface LogTransport {
  type: 'console' | 'file' | 'http' | string;
  config?: Record<string, any>;
}

export interface MetricDefinition {
  name: string;
  type: 'counter' | 'gauge' | 'histogram';
  description: string;
}

export interface AlertDefinition {
  name: string;
  condition: string;
  channels: string[];
  severity?: 'info' | 'warning' | 'critical';
}

/**
 * Security & Compliance Configuration
 * Affects: Entire application
 * Generator: security-generator.ts
 */
export interface Security {
  // Compliance requirements
  compliance?: {
    regulations: ('gdpr' | 'ccpa' | 'hipaa' | 'soc2' | 'pci_dss')[];
    data_retention?: DataRetentionPolicy;
    gdpr?: GDPRConfig;
  };

  // Encryption
  encryption?: {
    at_rest: boolean;
    in_transit: boolean;
    field_level?: string[]; // Field names to encrypt
  };

  // Audit logging
  audit_logging?: {
    enabled: boolean;
    retention: string; // e.g., "7_years"
    log_all_database_changes?: boolean;
    log_api_requests?: boolean;
  };

  // Content Security Policy
  csp?: {
    enabled: boolean;
    directives?: Record<string, string[]>;
  };

  // Rate limiting (moved from API)
  rate_limiting?: RateLimitingConfig;
}

export interface DataRetentionPolicy {
  [dataType: string]: string; // e.g., { user_data: "7_years" }
}

export interface GDPRConfig {
  right_to_access?: boolean;
  right_to_erasure?: boolean;
  data_portability?: boolean;
  consent_management?: boolean;
}

export interface RateLimitingConfig {
  global?: RateLimit;
  per_user?: Record<string, string>; // tier -> limit
  per_endpoint?: EndpointRateLimit[];
}

export interface RateLimit {
  requests_per_minute?: number;
  burst?: number;
}

export interface EndpointRateLimit {
  path: string;
  limit: string; // e.g., "50/minute"
}

/**
 * Performance Configuration
 * Affects: Architecture decisions
 * Generator: performance-generator.ts
 */
export interface Performance {
  // Frontend optimization
  frontend?: {
    code_splitting?: 'route_based' | 'component_based' | 'manual';
    lazy_loading?: boolean;
    tree_shaking?: boolean;
    bundle_budget?: BundleBudget;
  };

  // Backend optimization
  backend?: {
    caching?: CachingStrategy;
    connection_pooling?: ConnectionPooling;
    query_optimization?: boolean;
  };

  // CDN configuration
  cdn?: {
    provider: 'cloudflare' | 'cloudfront' | 'fastly' | string;
    assets?: string[];
    cache_ttl?: number;
  };

  // Database optimization
  database?: {
    read_replicas?: number;
    sharding?: ShardingConfig;
    indexing_strategy?: 'auto' | 'manual';
  };
}

export interface BundleBudget {
  max_initial?: string; // e.g., "200kb"
  max_total?: string;
}

export interface CachingStrategy {
  strategy: 'redis' | 'memcached' | 'in_memory';
  ttl?: number;
  cache_keys?: string[];
}

export interface ConnectionPooling {
  min: number;
  max: number;
  idle_timeout?: number;
}

export interface ShardingConfig {
  strategy: 'by_tenant' | 'by_date' | 'by_hash';
  shard_count?: number;
}

/**
 * Internationalization Configuration
 * Affects: Entire UI
 * Generator: i18n-generator.ts
 */
export interface Internationalization {
  default_locale: string;
  supported_locales: string[];
  translation_files?: string; // Path to translation files
  fallback_strategy?: 'cascade' | 'default';
  formatting?: {
    dates?: 'locale_specific' | 'iso';
    numbers?: 'locale_specific' | 'standard';
    currency?: 'locale_specific' | 'usd';
  };
  translation_management?: {
    provider?: 'lokalise' | 'crowdin' | 'phrase' | string;
    auto_sync?: boolean;
  };
}

/**
 * Feature Flags Configuration
 * Affects: Application behavior
 * Generator: feature-flags-generator.ts
 */
export interface FeatureFlags {
  provider: 'launchdarkly' | 'split' | 'unleash' | 'custom' | string;
  flags?: FeatureFlag[];
}

export interface FeatureFlag {
  name: string;
  enabled: boolean;
  rollout_percentage?: number;
  rollout_strategy?: 'gradual' | 'immediate';
  targeting?: {
    user_segments?: string[];
  };
  schedule?: RolloutSchedule[];
}

export interface RolloutSchedule {
  date: string;
  percentage: number;
}

/**
 * Access Control Configuration
 * Affects: Security across application
 * Generator: access-control-generator.ts
 */
export interface AccessControl {
  model: 'rbac' | 'abac' | 'rbac_with_abac';
  roles?: Role[];
  policies?: Policy[];
}

export interface Role {
  name: string;
  permissions: Permission[];
}

export interface Permission {
  resource: string;
  actions: string[];
  conditions?: Condition[];
}

export interface Condition {
  field: string;
  operator: 'equals' | 'contains' | 'gt' | 'lt';
  value: any;
}

export interface Policy {
  name: string;
  resource: string;
  action: string;
  rules: PolicyRule[];
}

export interface PolicyRule {
  role?: string;
  condition?: string;
}

/**
 * API Configuration
 * Affects: All API endpoints
 * Generator: api-generator.ts
 */
export interface ApiConfiguration {
  base_path?: string;

  // API Documentation
  documentation?: {
    format: 'openapi' | 'swagger' | 'graphql_schema';
    auto_generate: boolean;
    output?: string;
  };

  // Versioning
  versioning?: {
    strategy: 'url_path' | 'header' | 'query_param';
    deprecation_policy?: DeprecationPolicy;
  };

  // CORS
  cors?: {
    enabled: boolean;
    origins?: string[];
    methods?: string[];
    credentials?: boolean;
  };

  // Global middleware
  middleware?: string[];

  // Endpoints (can also be defined per-component)
  endpoints?: Endpoint[];
}

export interface DeprecationPolicy {
  notice_period: string; // e.g., "90_days"
  sunset_headers: boolean;
}

/**
 * Deployment Configuration
 * Affects: Infrastructure
 * Generator: deployment-generator.ts
 */
export interface DeploymentConfiguration {
  strategy: 'single_region' | 'multi_region' | 'edge';

  // Regions
  regions?: Region[];

  // Edge functions
  edge_functions?: EdgeFunction[];

  // Geo-routing
  geo_routing?: {
    enabled: boolean;
    strategy: 'lowest_latency' | 'closest_region' | 'manual';
  };

  // Disaster recovery
  disaster_recovery?: {
    rpo: string; // Recovery Point Objective
    rto: string; // Recovery Time Objective
    replica_regions?: string[];
    failover: 'automatic' | 'manual';
  };
}

export interface Region {
  name: string;
  primary?: boolean;
  services: string[];
  database_replica?: boolean;
}

export interface EdgeFunction {
  name: string;
  regions: 'all' | string[];
  provider?: 'cloudflare_workers' | 'lambda_edge' | string;
}

/**
 * Analytics Configuration
 * Affects: Event tracking across application
 * Generator: analytics-generator.ts
 */
export interface Analytics {
  provider: 'mixpanel' | 'amplitude' | 'segment' | 'google_analytics' | string;

  // Event tracking
  tracking?: {
    auto_track?: string[];
    custom_events?: CustomEvent[];
  };

  // Funnels
  funnels?: Funnel[];

  // Cohorts
  cohorts?: Cohort[];
}

export interface CustomEvent {
  name: string;
  properties: string[];
}

export interface Funnel {
  name: string;
  steps: FunnelStep[];
}

export interface FunnelStep {
  event: string;
  required?: boolean;
}

export interface Cohort {
  name: string;
  criteria: string;
}

// =============================================
// COMPONENT TYPES (Service-Specific)
// =============================================

// Stack components remain largely the same but with enhanced config options
export interface StackComponents {
  [componentName: string]: StackComponent;
}

export interface StackComponent {
  type: string;
  technology: string;
  config?: ComponentConfig; // Enhanced with service-specific options
  directory?: string;
  dependsOn?: string[];
  components?: Component[];
  endpoints?: Endpoint[];
  tables?: Table[];
  workflows?: ComponentWorkflow[];
  routing?: 'primary_only' | 'context_based' | 'load_balanced';
  primary?: string;
  services?: Record<string, any>;
  expected_dependencies?: ExpectedDependency[];
}

/**
 * Enhanced Component Config
 * Allows service-specific configuration
 */
export interface ComponentConfig extends Record<string, any> {
  // Worker-specific
  jobs?: JobDefinition[];
  queues?: string[];

  // Database-specific
  migrations?: MigrationConfig;
  backup?: BackupConfig;

  // Storage-specific
  image_optimization?: ImageOptimizationConfig;
  video_processing?: VideoProcessingConfig;

  // Search-specific
  indices?: SearchIndex[];

  // Email-specific
  templates?: EmailTemplate[];

  // API-specific
  webhooks?: Webhook[];
}

export interface JobDefinition {
  name: string;
  retry?: {
    attempts: number;
    backoff?: 'exponential' | 'linear' | 'fixed';
    delay?: number;
  };
  timeout?: number;
  priority?: 'low' | 'normal' | 'high' | 'critical';
  schedule?: string; // Cron expression
}

export interface MigrationConfig {
  strategy: 'prisma_migrate' | 'knex' | 'typeorm' | 'custom';
  auto_generate?: boolean;
  version_control?: {
    naming: 'timestamp' | 'sequential' | 'semantic';
  };
}

export interface BackupConfig {
  schedule: string; // Cron expression
  retention: string; // e.g., "30_days"
  strategy: 'full' | 'incremental' | 'continuous';
}

export interface ImageOptimizationConfig {
  formats: string[];
  sizes: string[];
  quality?: number;
}

export interface VideoProcessingConfig {
  transcoding?: {
    profiles: string[];
    format: string;
  };
  thumbnail_generation?: boolean;
}

export interface SearchIndex {
  name: string;
  fields: SearchField[];
  synonyms?: string[][];
  filters?: string[];
}

export interface SearchField {
  name: string;
  boost?: number;
  analyzer?: string;
}

export interface EmailTemplate {
  name: string;
  subject: string;
  template_path: string;
  variables?: string[];
}

export interface Webhook {
  name: string;
  url: string;
  events: string[];
  retry?: {
    attempts: number;
    backoff?: 'exponential' | 'linear';
  };
  signature?: {
    algorithm: string;
    header: string;
  };
}

// ... (rest of existing types remain)
```

---

## 2. Generator Mapping

Each top-level section maps to a specific generator:

```
Top-Level Section        → Generator File                  → Generated Output
======================================================================================
testing                  → testing-generator.ts            → tests/, vitest.config.ts, playwright.config.ts
monitoring               → monitoring-generator.ts         → monitoring/, sentry.config.ts, logger.ts
security                 → security-generator.ts           → middleware/security.ts, helmet config
performance              → performance-generator.ts        → vite.config.ts (optimization), caching.ts
i18n                     → i18n-generator.ts               → locales/, i18n.config.ts
feature_flags            → feature-flags-generator.ts      → lib/feature-flags.ts
access_control           → access-control-generator.ts     → middleware/rbac.ts, policies/
api                      → api-generator.ts                → openapi.json, api-docs/
deployment               → deployment-generator.ts         → docker-compose.yml, k8s/, vercel.json
analytics                → analytics-generator.ts          → lib/analytics.ts, tracking/
```

### Component-Level Generators (Enhanced)

```
Component Config         → Generator                       → Generated Output
======================================================================================
jobs (worker)            → worker-generator.ts             → workers/, bullmq config
migrations (database)    → migration-generator.ts          → prisma/migrations/
webhooks (api)           → webhook-generator.ts            → routes/webhooks/
templates (email)        → email-generator.ts              → emails/templates/
indices (search)         → search-generator.ts             → search/indices/
```

---

## 3. Implementation Strategy

### Phase 1: Core Infrastructure (Week 1-2)

**Goal**: Update schema types and validation

1. Update `src/types/workflow.ts` with new interfaces
2. Create schema validators for each top-level section
3. Update YAML parser to recognize new sections

**Files to Create/Update**:
- `src/types/workflow.ts` - Add new interfaces
- `src/validators/testing-validator.ts`
- `src/validators/monitoring-validator.ts`
- `src/validators/security-validator.ts`
- etc.

### Phase 2: High-Priority Generators (Week 3-4)

**Priority 1 (Critical, Low Effort)**:
1. **Testing Generator** (`src/generators/testing-generator.ts`)
   - Generate vitest.config.ts
   - Generate playwright.config.ts
   - Generate test setup files
   - Generate mock handlers

2. **Monitoring Generator** (`src/generators/monitoring-generator.ts`)
   - Generate Sentry config
   - Generate logger setup
   - Generate error boundaries

3. **API Generator Enhancements** (`src/generators/api-generator.ts`)
   - Generate OpenAPI schema
   - Generate API documentation
   - Add rate limiting middleware

### Phase 3: Medium-Priority Generators (Week 5-6)

**Priority 2 (High Value, Medium Effort)**:
1. **Performance Generator** (`src/generators/performance-generator.ts`)
   - Update Vite config with optimizations
   - Generate caching layer
   - Add bundle analysis

2. **Security Generator** (`src/generators/security-generator.ts`)
   - Generate Helmet config
   - Add RBAC middleware
   - Generate audit logging

3. **Feature Flags Generator** (`src/generators/feature-flags-generator.ts`)
   - Generate feature flag client
   - Add feature flag hooks
   - Generate flag definitions

### Phase 4: Component Enhancements (Week 7-8)

Enhance existing generators to read component-level config:

1. **Worker Generator** - Read `jobs` from component config
2. **Database Generator** - Read `migrations` and `backup` config
3. **Email Generator** - Read `templates` from component config
4. **Storage Generator** - Read `image_optimization` config

### Phase 5: Advanced Features (Week 9-10)

**Priority 3 (Nice to Have)**:
1. **i18n Generator**
2. **Analytics Generator**
3. **Deployment Generator** (multi-region)

---

## 4. Backward Compatibility

Ensure existing workflows continue to work:

```typescript
// src/parsers/workflow-parser.ts

export function parseWorkflow(yaml: any): Workflow {
  // NEW: Top-level sections
  const testing = yaml.testing ? parseTestingConfig(yaml.testing) : undefined;
  const monitoring = yaml.monitoring ? parseMonitoringConfig(yaml.monitoring) : undefined;
  // ... etc

  // EXISTING: Stack components (unchanged)
  const stack = parseStackComponents(yaml.stack);

  // LEGACY: Handle old environment/deployment format
  const deployment = yaml.deployment || migrateLegacyDeployment(yaml);

  return {
    workflow: yaml.workflow,
    testing,
    monitoring,
    stack,
    deployment,
    // ... rest
  };
}
```

---

## 5. Example Usage

### Before (Generic Stack)

```yaml
stack:
  api:
    type: backend
    config:
      # Everything mixed together
      test_framework: vitest
      error_tracking: sentry
      rate_limiting: 1000/min
```

### After (Structured)

```yaml
# Cross-cutting concerns at top level
testing:
  frameworks:
    unit: { framework: vitest }
    e2e: { framework: playwright }
  coverage:
    threshold:
      global: { statements: 80 }

monitoring:
  error_tracking:
    provider: sentry
  apm:
    provider: datadog

api:
  rate_limiting:
    global: 1000/min
  documentation:
    format: openapi
    auto_generate: true

# Components focus on their specific concerns
stack:
  api:
    type: backend
    technology: typescript/express
    endpoints:
      - path: /users
        method: GET
```

---

## 6. Benefits for Implementation

### 1. **Clear Generator Responsibilities**

Each generator has a well-defined scope:
- Testing generator only handles `testing` section
- Monitoring generator only handles `monitoring` section
- No confusion about where code should live

### 2. **Easier Validation**

```typescript
// src/validators/testing-validator.ts
export function validateTestingConfig(testing: Testing): ValidationResult {
  if (testing.frameworks?.unit?.framework === 'vitest') {
    // Ensure vitest-specific config is valid
  }
  // Clear, focused validation
}
```

### 3. **Incremental Implementation**

Can build generators one at a time:
- Week 1: Testing generator ✅
- Week 2: Monitoring generator ✅
- Week 3: Performance generator ✅
- Existing functionality keeps working!

### 4. **Better Documentation**

Each section can have its own documentation:
- `/docs/testing.md` - How to configure testing
- `/docs/monitoring.md` - How to configure monitoring
- Clear, focused docs

### 5. **Easier Testing of Generators**

```typescript
// tests/generators/testing-generator.test.ts
describe('TestingGenerator', () => {
  it('should generate vitest config from testing section', () => {
    const workflow: Workflow = {
      testing: {
        frameworks: { unit: { framework: 'vitest' } }
      }
    };

    const files = testingGenerator.generate(workflow);
    expect(files).toContainFile('vitest.config.ts');
  });
});
```

### 6. **Clear Dependencies**

Generators can declare what they need:
```typescript
// src/generators/testing-generator.ts
export class TestingGenerator {
  // Depends on: workflow.testing, workflow.stack (to know what to test)
  dependencies = ['testing', 'stack'];

  generate(workflow: Workflow): GeneratedFile[] {
    const { testing, stack } = workflow;
    // Clear inputs, clear outputs
  }
}
```

---

## 7. Migration Path for Existing Workflows

For users with existing workflows, provide automatic migration:

```typescript
// src/migrations/migrate-to-v2-schema.ts

export function migrateWorkflow(oldWorkflow: any): Workflow {
  return {
    ...oldWorkflow,

    // Extract testing config from component configs
    testing: extractTestingConfig(oldWorkflow.stack),

    // Extract monitoring from component configs
    monitoring: extractMonitoringConfig(oldWorkflow.stack),

    // Keep stack as-is
    stack: oldWorkflow.stack,
  };
}
```

---

## Next Steps

1. **Create PR with schema updates**
   - Add new interfaces to `workflow.ts`
   - Create validators for each section

2. **Implement testing generator first** (highest priority, clearest value)
   - Tests are critical for any app
   - Clear input/output
   - Immediate value for users

3. **Add examples to stress tests**
   - Update Level 1-6 stress tests with new sections
   - Show best practices

4. **Update documentation**
   - Create guide for each top-level section
   - Migration guide for existing users

Would you like me to start implementing any specific part of this plan?
