# Composable Monorepo Templates

**Last Updated:** 2026-01-30
**Confidence:** High (Planned)

## Summary

Composable Monorepo Templates evolve rdev's project scaffolding from single templates to full monorepo architecture. Every project starts with the **skeleton** (monorepo base), with **component templates** (services, workers, apps, cli) added via API calls. Deployment can target the whole monorepo or individual components.

**Terminology:** "skeleton" = monorepo base code; "platform" = rdev itself. See [terminology.md](../terminology.md).

**Key Facts:**
- `POST /projects` creates monorepo skeleton (not single template)
- `POST /projects/{id}/components` adds services/workers/apps/cli (code) or postgres/redis (infrastructure)
- **Infrastructure provisioning:** `type: postgres` creates CockroachDB database, `type: redis` creates Redis cache
- **Automatic credential injection:** Components deployed after infrastructure get `DATABASE_URL`, `REDIS_URL` as env vars
- Convention-based discovery: `services/*/`, `workers/*/`, `apps/*/`, `cli/*/`
- Optional `component.yaml` per component for ports, dependencies, build order
- Shared `pkg/` from Aeries chassis + Colix patterns (8+ packages including queue, auth, database, realtime)
- Deployment supports whole-monorepo or individual-component targets
- **CI is template-provided** - skeleton has `.woodpecker.yml.tmpl`, components have `.woodpecker.step.yml.tmpl`

**Critical Design Decision:**
CI/CD configuration MUST come from templates, never AI-generated. Claude Code produces invalid
Woodpecker YAML when generating from scratch (broken YAML anchor syntax).

**File Pointers:**
- Plan: `tmp/template-monorepo-plan.md`
- Current templates: `internal/adapter/templates/templates/`
- Port: `internal/port/template_provider.go`

## How It Works

### Project Creation Flow

```
POST /projects {"name": "acme"}
  ↓
Creates monorepo skeleton:
  - CLAUDE.md, README.md, Procfile
  - docker-compose.yml, go.work, .golangci.yml
  - .woodpecker.yml (template-provided CI)
  - scripts/ (discover, install, quality, dev)
  - pkg/ (8 shared packages from Aeries + Colix)
  - .claude/ (guides, skills, commands)
```

### Component Addition Flow

```
POST /projects/acme/components {"type": "service", "name": "auth-api"}
  ↓
Creates services/auth-api/:
  - cmd/server/main.go
  - internal/, Makefile, Dockerfile
  - component.yaml (port, deps)
  ↓
Auto-updates:
  - Procfile (add service entry)
  - go.work (add module)
  - CLAUDE.md (add routing)
  - .woodpecker.yml (add build step for component)
```

### Monorepo Structure

```
acme/
├── CLAUDE.md                    # AI router
├── Procfile                     # Local dev (auto-updated)
├── docker-compose.yml           # Local services
├── go.work                      # Go workspace (auto-updated)
├── scripts/                     # Discovery scripts
├── pkg/                         # Shared packages (8 total)
├── services/auth-api/           # Go API component
├── workers/email-worker/        # Background worker component
├── apps/dashboard/              # Frontend component
└── cli/acme-cli/                # CLI tool component
```

## Shared Packages (pkg/)

Combines best patterns from Aeries (chassis) and Colix (modular):

| Package | Source | Purpose |
|---------|--------|---------|
| `app/` | Aeries chassis | Service bootstrapper |
| `middleware/` | Colix | HTTP middleware (CORS, recovery, request_id, logger) |
| `httpcontext/` | Colix | Type-safe context helpers |
| `httpresponse/` | Aeries+Colix | JSON helpers + envelope pattern |
| `httpvalidation/` | Colix | Request validation |
| `logging/` | Both | Structured logging (slog + env detection) |
| `config/` | Aeries | Configuration via viper |
| `httpclient/` | Both | Resilient HTTP client with retry |

## Component Types

| Type | Directory | Template | Identifier |
|------|-----------|----------|------------|
| Service | `services/` | service | `Makefile` or `go.mod` |
| Worker | `workers/` | worker | `Makefile` or `go.mod` |
| App | `apps/` | app-astro, app-react, app-nextjs | `package.json` |
| CLI | `cli/` | cli | `Makefile` or `go.mod` |
| Postgres | `infra/postgres` | (provisioned) | CockroachDB database |
| Redis | `infra/redis` | (provisioned) | Redis cache with ACL |

## Infrastructure Provisioning

When you add `type: postgres` or `type: redis`:

1. **Database (postgres):** Creates CockroachDB database + user, stores `DATABASE_URL` in credential store
2. **Cache (redis):** Creates Redis ACL user with scoped prefix, stores `REDIS_URL` and `REDIS_PREFIX`

**Credential Injection:** When code components (service, worker, app) are deployed, the system automatically fetches stored credentials and injects them as K8s secrets → env vars.

**File Pointers:**
- Provisioning: `internal/service/component_infra.go`
- Credential injection: `internal/service/component_deploy.go:fetchProjectCredentials()`

## Template Migration

| Current Template | New Location | Component Type |
|------------------|--------------|----------------|
| `go-api` | `components/service/` | `services/*` |
| `astro-landing` | `components/app-astro/` | `apps/*` |
| `default` | Becomes skeleton | N/A |

## Related Topics

- [Template Provider](../services/template-provider.md) - Current template system
- [Project Service](../services/project-service.md) - Project lifecycle
- [Build Orchestration](./build-orchestration.md) - Component builds
