rdev/ai-lookup/features/composable-monorepo.md

5.4 KiB

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.

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