# Bangstack Event-Driven Schema Design

## Design Decisions

### 1. Events Are Global, Defined Once
**Decision**: Events are first-class entities defined at the top level.
**Reason**: Events represent system-wide contracts. Multiple components emit/consume the same events, so they must be defined centrally to avoid duplication and ensure consistency.

### 2. Components Auto-Wire Based on Emit/Consume
**Decision**: Components declare what events they emit and consume. The system automatically generates the wiring.
**Reason**: Manual wiring defeats the purpose of "automatic awareness." If a component consumes `payment_selected`, it should automatically receive that event from any component that emits it.

### 3. Workflows Are High-Level, Events Are Low-Level
**Decision**: Workflows describe actor journeys at a high level. The actions within workflows emit/consume events for component communication.
**Reason**: Workflows are for human understanding (business process). Events are for system communication (technical implementation). Keep them separate but linked.

### 4. Stack Maps Components to Services
**Decision**: The Stack section maps abstract components to concrete services.
**Reason**: A component like "payment_processor" is abstract. It could be implemented by Stripe, PayPal, Klarna, or all three. The stack defines which services implement which components.

## Schema Structure

```yaml
# ============================================================================
# EVENTS: System-wide event definitions (communication contracts)
# ============================================================================
events:
  payment_selected:
    description: User selects a payment method
    payload:
      method: string        # paypal, klarna, stripe
      amount: number
      currency: string

  order_created:
    description: Order is successfully created
    payload:
      order_id: string
      customer_id: string
      total: number
      payment_method: string
      items: array

  product_added_to_cart:
    description: Product added to shopping cart
    payload:
      product_id: string
      quantity: number
      price: number

# ============================================================================
# COMPONENTS: Logical parts of the system (emit/consume events)
# ============================================================================
components:
  checkout:
    description: Handles checkout and payment processing
    emits:
      - payment_selected
      - order_created
    consumes:
      - product_added_to_cart

  order_management:
    description: Manages order lifecycle
    emits:
      - order_created
      - order_updated
      - order_shipped
    consumes:
      - payment_selected
      - order_created

  email_system:
    description: Sends transactional emails
    emits:
      - email_sent
    consumes:
      - order_created
      - payment_selected
      - order_shipped

  analytics:
    description: Tracks user behavior and business metrics
    emits: []
    consumes:
      - payment_selected
      - order_created
      - product_added_to_cart
      - email_sent

  inventory:
    description: Manages product inventory
    emits:
      - inventory_updated
      - low_stock_alert
    consumes:
      - order_created
      - order_cancelled

# ============================================================================
# ACTORS: Who/what performs actions
# ============================================================================
actors:
  customer:
    type: human
    description: End user purchasing products

  admin:
    type: human
    description: Store administrator

  inventory_sync:
    type: system
    description: Background process syncing inventory
    schedule: "*/15 * * * *"  # Every 15 minutes

# ============================================================================
# WORKFLOWS: Step-by-step processes actors perform
# ============================================================================
workflows:
  customer_checkout:
    actor: customer
    description: Customer browses products and completes purchase
    steps:
      - id: browse_catalog
        action: view_products
        component: catalog

      - id: add_item
        action: add_to_cart
        component: cart
        emits: product_added_to_cart

      - id: view_cart
        action: review_cart
        component: cart

      - id: choose_payment
        action: select_payment_method
        component: checkout
        emits: payment_selected
        choices:
          - paypal
          - klarna
          - stripe

      - id: complete_purchase
        action: submit_order
        component: checkout
        depends_on: [choose_payment]
        emits: order_created
        on_success: redirect_to_confirmation
        on_failure: show_error

# ============================================================================
# STACK: Maps abstract components to concrete services
# ============================================================================
stack:
  checkout:
    services:
      stripe:
        type: payment_processor
        config:
          api_version: "2023-10-16"

      paypal:
        type: payment_processor
        config:
          mode: production

      klarna:
        type: payment_processor
        config:
          region: US

  order_management:
    services:
      shopify:
        type: oms
        config:
          store_url: "{{ env.SHOPIFY_STORE }}"

  email_system:
    services:
      sendgrid:
        type: email_provider
        config:
          api_key: "{{ env.SENDGRID_API_KEY }}"

  analytics:
    services:
      mixpanel:
        type: analytics
        config:
          project_token: "{{ env.MIXPANEL_TOKEN }}"

# ============================================================================
# ACTIONS: Specific tasks that can be performed
# ============================================================================
actions:
  add_to_cart:
    description: Add product to shopping cart
    component: cart
    emits: product_added_to_cart
    inputs:
      - product_id: string
      - quantity: number

  select_payment_method:
    description: Choose how to pay
    component: checkout
    emits: payment_selected
    inputs:
      - method: string
      - amount: number

  submit_order:
    description: Finalize and submit order
    component: checkout
    emits: order_created
    consumes: payment_selected
    inputs:
      - cart_id: string
      - shipping_address: object

# ============================================================================
# STAGES: Environment configurations
# ============================================================================
stages:
  development:
    domain: localhost:3000
    database: postgres://localhost/app_dev

  staging:
    domain: staging.myapp.com
    database: "{{ secrets.STAGING_DB_URL }}"

  production:
    domain: myapp.com
    database: "{{ secrets.PROD_DB_URL }}"
```

## How Automatic Propagation Works

### Example: Adding Klarna

**Before:**
```yaml
stack:
  checkout:
    services:
      stripe: {...}
      paypal: {...}
```

**After:**
```yaml
stack:
  checkout:
    services:
      stripe: {...}
      paypal: {...}
      klarna: {...}  # ← Added
```

**What Happens:**
1. System sees `checkout` component has new service
2. Looks up what events `checkout` emits: `payment_selected`, `order_created`
3. Looks up what components consume those events:
   - `order_management` consumes `payment_selected` → regenerates to handle Klarna orders
   - `email_system` consumes `payment_selected` → regenerates templates to mention Klarna
   - `analytics` consumes `payment_selected` → regenerates tracking for Klarna
   - `inventory` consumes `order_created` → already handles all payment methods
4. Regenerates all affected components
5. Runs tests for the checkout workflow
6. Updates documentation to include Klarna

### Example: New Workflow Creates New Connections

**Adding:** "Admin cancels an order"

```yaml
workflows:
  admin_cancel_order:
    actor: admin
    steps:
      - action: cancel_order
        component: order_management
        emits: order_cancelled  # ← New event
```

**What Happens:**
1. New event `order_cancelled` is added to events
2. System identifies components that should probably consume it:
   - `inventory` (restore stock)
   - `email_system` (notify customer)
   - `analytics` (track cancellations)
   - `checkout` (process refund)
3. Prompts: "Should these components react to order_cancelled?"
4. You confirm
5. System updates component definitions and regenerates

## Code Generation Strategy

### Generated Event Infrastructure

```typescript
// Generated: src/events/types.ts
export type PaymentSelectedEvent = {
  type: 'payment_selected'
  payload: {
    method: 'paypal' | 'klarna' | 'stripe'
    amount: number
    currency: string
  }
}

export type OrderCreatedEvent = {
  type: 'order_created'
  payload: {
    order_id: string
    customer_id: string
    total: number
    payment_method: string
    items: any[]
  }
}

export type SystemEvent =
  | PaymentSelectedEvent
  | OrderCreatedEvent
  | ProductAddedToCartEvent
  // ... all events
```

```typescript
// Generated: src/events/bus.ts
class EventBus {
  private handlers: Map<string, Function[]> = new Map()

  emit(event: SystemEvent) {
    const handlers = this.handlers.get(event.type) || []
    handlers.forEach(handler => handler(event))
  }

  on(eventType: string, handler: Function) {
    const handlers = this.handlers.get(eventType) || []
    handlers.push(handler)
    this.handlers.set(eventType, handlers)
  }
}

export const eventBus = new EventBus()
```

### Generated Component Code

```typescript
// Generated: src/components/analytics/index.ts
import { eventBus } from '../../events/bus'

export class Analytics {
  constructor() {
    // Auto-wired based on YAML consumes declaration
    eventBus.on('payment_selected', this.trackPaymentSelected)
    eventBus.on('order_created', this.trackOrderCreated)
    eventBus.on('product_added_to_cart', this.trackAddToCart)
  }

  private trackPaymentSelected(event: PaymentSelectedEvent) {
    mixpanel.track('Payment Method Selected', {
      method: event.payload.method,
      amount: event.payload.amount
    })
  }

  private trackOrderCreated(event: OrderCreatedEvent) {
    mixpanel.track('Order Created', {
      order_id: event.payload.order_id,
      total: event.payload.total,
      payment_method: event.payload.payment_method
    })
  }
}
```

```typescript
// Generated: src/components/checkout/index.ts
import { eventBus } from '../../events/bus'
import { Stripe } from './services/stripe'
import { PayPal } from './services/paypal'
import { Klarna } from './services/klarna'  // ← Auto-added when klarna added to stack

export class Checkout {
  private paymentMethods = {
    stripe: new Stripe(),
    paypal: new PayPal(),
    klarna: new Klarna()  // ← Auto-added
  }

  async selectPayment(method: string, amount: number) {
    // Emit event - all consumers automatically notified
    eventBus.emit({
      type: 'payment_selected',
      payload: { method, amount, currency: 'USD' }
    })
  }

  async submitOrder(cartId: string) {
    const order = await this.createOrder(cartId)

    // Emit event - all consumers automatically notified
    eventBus.emit({
      type: 'order_created',
      payload: {
        order_id: order.id,
        customer_id: order.customer_id,
        total: order.total,
        payment_method: order.payment_method,
        items: order.items
      }
    })

    return order
  }
}
```

## Benefits of This Design

1. **Automatic Awareness**: Components know about changes through events, not hardcoded references
2. **Loose Coupling**: Components don't know about each other, only about events
3. **Easy Extension**: Add new components by declaring what events they consume
4. **Auditable**: All system communication is visible in event definitions
5. **Testable**: Events are explicit contracts that can be tested
6. **Documentation**: Event flow documents how the system works

## What Gets Generated

From this YAML, Bangstack generates:

1. **Event types and infrastructure** (TypeScript interfaces, event bus)
2. **Component scaffolding** (auto-wired to emit/consume declared events)
3. **Service integrations** (Stripe, Klarna, etc. based on stack)
4. **Tests** (verify events are emitted, workflows complete)
5. **Documentation** (event flow diagrams, component relationships)
6. **Analytics tracking** (auto-track all events)
7. **Monitoring** (log all events for debugging)

## The Key Insight

**Connectiveness comes from events, not from components knowing about each other.**

When you add Klarna, you don't update 10 files. You update the stack, and the event system ensures all consumers of `payment_selected` automatically handle the new payment method.

This is the architecture that enables automatic awareness.
