# 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