# E-commerce API Platform Example

A complete e-commerce backend API demonstrating Bangstack's infrastructure service management, version tracking, and multi-environment deployment.

## What This Example Demonstrates

- **Multiple Services**: Redis (caching/sessions), Queue (async jobs), Email (notifications)
- **Multi-Component Stack**: API server and background worker
- **Environment Progression**: Local → Staging → Production
- **Version Management**: Track infrastructure changes across versions
- **Dependency Verification**: Ensure code matches declared dependencies

## Architecture Overview

```
┌─────────────┐
│   Clients   │
└──────┬──────┘
       │
   ┌───▼────┐      ┌──────────┐
   │  API   │─────►│  Redis   │ (Sessions, Cart Cache)
   │ Server │      └──────────┘
   └───┬────┘
       │
       │         ┌──────────┐
       ├────────►│  Queue   │
       │         └─────┬────┘
       │               │
       │         ┌─────▼────┐      ┌──────────┐
       │         │  Worker  │─────►│  Email   │
       │         └──────────┘      └──────────┘
       │
   ┌───▼────────┐
   │ PostgreSQL │
   └────────────┘
```

## Quick Start

### 1. Generate Infrastructure

```bash
# Navigate to this example
cd examples/ecommerce-api

# Generate the complete stack
bang generate ecommerce.workflow.yaml
```

This creates:
- `api/` - Express API server with Redis and Queue clients
- `worker/` - Background job processor
- `docker-compose.yml` - Local development environment
- `.github/workflows/` - CI/CD pipelines
- `.bangstack/manifest.json` - Version tracking manifest

### 2. Start Local Development

```bash
# Start infrastructure services
docker-compose up -d

# Install dependencies
cd api && npm install
cd ../worker && npm install

# Run database migrations
cd api && npm run migrate

# Start the API server
npm run dev

# In another terminal, start the worker
cd worker && npm run dev
```

### 3. Verify Setup

```bash
# Check that everything is correctly configured
bang verify ecommerce.workflow.yaml
```

## Example Use Cases

### Use Case 1: Adding a New Service

Let's say we want to add SMS notifications via Twilio:

**Step 1**: Update the workflow

```yaml
# Add to api.expected_dependencies
- service: sms
  usage: Order status SMS notifications
  required: false

# Add to stages.production.services
sms:
  provider: twilio
  connection: "{{secrets.TWILIO_API_KEY}}"
  description: Twilio SMS for notifications
```

**Step 2**: Verify the change

```bash
bang verify ecommerce.workflow.yaml
```

This will warn you that:
- ⚠️ New service `sms` detected but no client implementation exists
- 💡 Recommend: Implement SMS service integration in api component

**Step 3**: Generate the client code

```bash
bang generate ecommerce.workflow.yaml
```

This generates `api/src/services/sms-client.ts` with Twilio integration.

**Step 4**: Create a version

```bash
# Commit your changes
git add .
git commit -m "Add SMS notifications via Twilio"

# Create version tag
bang version create 1.1.0 -w ecommerce.workflow.yaml

# Push to remote
git push origin 1.1.0
```

### Use Case 2: Removing an Unused Service

You decide Redis caching isn't necessary:

**Step 1**: Remove from workflow

```yaml
# Remove redis from api.expected_dependencies
# Remove redis from stages.*.services
```

**Step 2**: Verify the change

```bash
bang verify ecommerce.workflow.yaml
```

This will warn you that:
- ⚠️ Service `redis` removed but client files still exist
- 💡 Recommend: Remove `redis-client.ts` or update imports

**Step 3**: Update your code

```bash
# Remove redis client file
rm api/src/services/redis-client.ts

# Remove imports in your routes
# Update session handling to use alternative
```

**Step 4**: Verify again

```bash
bang verify ecommerce.workflow.yaml
# ✅ No issues found - ready to generate
```

**Step 5**: Create version

```bash
git add .
git commit -m "Remove Redis dependency, use in-memory sessions"
bang version create 2.0.0 -w ecommerce.workflow.yaml
```

### Use Case 3: Rolling Back a Change

Something broke in production after adding a feature:

```bash
# Check available versions
bang version list

# Compare versions to see what changed
bang version diff 1.0.0 2.0.0

# Rollback to stable version
bang version rollback 1.0.0

# This checks out the old workflow and warns about:
# - Services that will be removed
# - Dependencies that changed
# - Files that may be affected
```

## Version Management Workflow

This example demonstrates a complete version management workflow:

### Development Flow

```bash
# 1. Make infrastructure changes in workflow file
vim ecommerce.workflow.yaml

# 2. Verify changes before committing
bang verify ecommerce.workflow.yaml

# 3. Fix any warnings (add/remove clients, update code)
# 4. Verify again until clean
bang verify ecommerce.workflow.yaml

# 5. Generate updated code
bang generate ecommerce.workflow.yaml

# 6. Test locally
npm test

# 7. Commit and create version
git add .
git commit -m "feat: add payment service integration"
bang version create 1.2.0 -w ecommerce.workflow.yaml

# 8. Push to trigger CI/CD
git push origin 1.2.0
```

### CI/CD Integration

The generated GitHub Actions workflow automatically:

1. **On PR**: Runs `bang verify` to catch dependency mismatches
2. **On Push**: Runs tests and builds
3. **On Tag**: Deploys to staging/production based on version

## Project Structure

```
ecommerce-api/
├── ecommerce.workflow.yaml       # Infrastructure definition
├── api/                           # Express API server
│   ├── src/
│   │   ├── routes/               # API endpoints
│   │   ├── services/             # Business logic
│   │   │   ├── redis-client.ts   # Generated Redis client
│   │   │   ├── queue-client.ts   # Generated Queue client
│   │   │   └── email-client.ts   # Generated Email client
│   │   ├── models/               # Database models
│   │   └── index.ts              # Server entry point
│   ├── package.json
│   └── tsconfig.json
├── worker/                        # Background job processor
│   ├── src/
│   │   ├── jobs/                 # Job handlers
│   │   ├── services/
│   │   │   ├── queue-client.ts   # Generated Queue client
│   │   │   └── email-client.ts   # Generated Email client
│   │   └── index.ts              # Worker entry point
│   ├── package.json
│   └── tsconfig.json
├── docker-compose.yml             # Local infrastructure
├── .env.example                   # Environment template
├── .github/
│   └── workflows/
│       └── ci.yml                # Generated CI/CD pipeline
└── .bangstack/
    └── manifest.json             # Version tracking manifest
```

## Environment Variables

### Local Development

```bash
# .env
DATABASE_URL=postgresql://localhost:5432/ecommerce_dev
REDIS_URL=redis://localhost:6379
SMTP_HOST=localhost
SMTP_PORT=1025
```

### Staging

```bash
STAGING_DATABASE_URL=<heroku-postgres-url>
STAGING_REDIS_URL=<upstash-redis-url>
STAGING_SENDGRID_API_KEY=<sendgrid-key>
```

### Production

```bash
PRODUCTION_DATABASE_URL=<production-db-url>
PRODUCTION_REDIS_URL=<production-redis-url>
PRODUCTION_SENDGRID_API_KEY=<sendgrid-key>
```

## Common Patterns

### Adding Authentication

```typescript
// api/src/services/redis-client.ts is already generated
import { redisClient } from './services/redis-client';

// Use for session storage
app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
}));
```

### Queueing Background Jobs

```typescript
// api/src/routes/orders.ts
import { queueClient } from '../services/queue-client';

app.post('/orders', async (req, res) => {
  const order = await Order.create(req.body);

  // Queue order processing
  await queueClient.add('process-order', {
    orderId: order.id,
    customerId: req.user.id,
  });

  res.json(order);
});
```

### Processing Jobs

```typescript
// worker/src/jobs/process-order.ts
import { queueClient } from '../services/queue-client';
import { emailClient } from '../services/email-client';

queueClient.process('process-order', async (job) => {
  const { orderId, customerId } = job.data;

  // Process payment, update inventory, etc.
  await processPayment(orderId);
  await updateInventory(orderId);

  // Send confirmation email
  await emailClient.send({
    to: customer.email,
    subject: 'Order Confirmed',
    body: `Your order #${orderId} has been confirmed!`,
  });
});
```

## Testing

```bash
# Run all tests
npm test

# Test with infrastructure
docker-compose up -d
npm run test:integration

# Verify infrastructure configuration
bang verify ecommerce.workflow.yaml
```

## Deployment

### Staging Deployment

```bash
# Deploy to staging
git checkout develop
git merge feature-branch
git push origin develop

# This triggers:
# 1. CI tests
# 2. Build Docker images
# 3. Deploy to staging environment
```

### Production Deployment

```bash
# Create production version
git checkout main
git merge develop
bang version create 2.0.0 -w ecommerce.workflow.yaml
git push origin 2.0.0

# This triggers:
# 1. Full test suite
# 2. Security scans
# 3. Build and tag Docker images
# 4. Deploy to production
```

## Troubleshooting

### Issue: "Unexpected dependency found"

```bash
# You're importing a service not declared in workflow
bang verify ecommerce.workflow.yaml
# ⚠️ Unexpected dependency 'stripe' found in api component

# Solution: Add to workflow
# api.expected_dependencies:
#   - service: stripe
#     usage: Payment processing
```

### Issue: "Missing dependency"

```bash
# You declared a service but haven't implemented it
bang verify ecommerce.workflow.yaml
# ⚠️ Missing dependency 'email' - expected but not detected

# Solution: Import and use the generated client
# import { emailClient } from './services/email-client';
```

### Issue: "Orphaned client files"

```bash
# You removed a service but the client file still exists
bang verify ecommerce.workflow.yaml
# ⚠️ File 'redis-client.ts' exists but service removed

# Solution: Remove the file and update imports
# rm api/src/services/redis-client.ts
```

## Learn More

- [Bangstack Documentation](../../README.md)
- [Version Management Guide](../../README.md#-version-management)
- [CI/CD Integration](../../README.md#-cicd-integration)
- [More Examples](../)

## Next Steps

1. Try modifying the workflow to add a new service
2. Run `bang verify` to see what changes
3. Generate code and test it
4. Create a version tag
5. Explore other examples in the `examples/` directory
