Files
growqr-backend/README.md
sai karthik ff0bf5e5f0 Wire production stack: Clerk + Postgres + Anthropic + per-user containers
Brings the backend from a scaffold to a working end-to-end MVP — real auth,
persistent actor registry, Anthropic tool-use loop in the Grow Agent, and
per-user Gitea+OpenCode provisioning. Also adds the client-facing
architecture diagram under docs/architecture.html.
2026-05-19 22:17:40 +05:30

117 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GrowQR — backend + frontend
A multi-agent platform where every user gets a private Grow Agent (Rivet Kit actor) that orchestrates sub-agents and owns a per-user OpenCode + Gitea Docker stack. See `docs/PRD.md` for the product spec.
## What's wired up
- **Auth**: Clerk (frontend + backend JWT verification).
- **DB**: Postgres + Drizzle (users, actor registry, container mappings, repos, OpenCode sessions, events).
- **Actors**: Rivet Kit — `growAgent` per user (master) and `subAgent` (worker), with a real Anthropic Claude tool-use loop.
- **Per-user containers**: Gitea (memory repo) + OpenCode (workflow execution), spawned via `dockerode`, with admin user + access token bootstrap, ports allocated from a managed pool, lifecycle reconciled on backend boot.
- **Frontend**: Next.js 16 with `@clerk/nextjs` for auth and `rivetkit/client` for direct actor connections + event streaming.
- **Tool surface available to the Grow Agent**: `spawn_sub_agent`, `commit_memory`, `read_memory`, `list_memory`.
## One-time setup
You need three external accounts before running:
1. **Clerk** — create an app at https://dashboard.clerk.com → copy the publishable + secret keys.
2. **Anthropic** — create an API key at https://console.anthropic.com.
3. **Docker** — Docker Desktop (or any daemon `dockerode` can reach via `/var/run/docker.sock`).
Then:
```bash
# Backend env
cp .env.example .env
# fill in CLERK_SECRET_KEY, CLERK_PUBLISHABLE_KEY, ANTHROPIC_API_KEY
# Frontend env
cd growqr-frontend
cp .env.example .env.local
# fill in NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY
cd ..
```
## Running
```bash
# 1. Start Postgres + Rivet engine (per-user OpenCode/Gitea containers are
# spawned dynamically by the backend when a user signs in).
docker compose up -d postgres rivet-engine
# 2. Install + migrate
npm install
npm run db:migrate
# 3. Backend
npm run dev # http://localhost:4000
# 4. Frontend (separate terminal)
cd growqr-frontend
npm install
npm run dev # http://localhost:3000
```
Open http://localhost:3000, sign up, verify your email, and the home page will:
1. Mirror your Clerk user into Postgres.
2. Spawn your dedicated Gitea + OpenCode containers (first run pulls images — ~2040s).
3. Connect the Grow Agent chat to your dedicated Rivet actor.
4. Stream agent + sub-agent events back to the UI.
## Architecture
```
Browser
│ Clerk JWT
Next.js (3000) ──fetch──▶ /users/bootstrap, /users/me (Hono on 4000)
└─Rivet client──▶ /api/rivet/* (Hono → registry.handler)
Grow Agent actor (one per user)
├─ Anthropic (Opus 4.7 + tool use)
├─ commit_memory ────▶ Gitea container (per user)
└─ spawn_sub_agent ────▶ OpenCode container (per user)
(multiplexed sessions)
```
## Useful commands
```bash
npm run typecheck # backend
npm run db:generate # diff schema → new migration
npm run db:studio # browse Postgres via Drizzle Studio
cd growqr-frontend
npx tsc --noEmit # frontend types
npm run lint
```
## Troubleshooting
- **"missing bearer token"** from `/users/bootstrap` — Clerk session not attached. Sign out and back in.
- **`Gitea did not become ready`** during provisioning — Gitea takes 1020s on first pull. Wait, then `POST /actors/provision` (the frontend retries via polling).
- **OpenCode container exits immediately** — check `OPENCODE_IMAGE`. The compose env passes `Cmd: ["serve", ...]`; if you swap to a different image, ensure it exposes the `opencode serve` HTTP surface on `:4096`.
- **`No free ports in USER_PORT_RANGE`** — bump `USER_PORT_RANGE_END` in `.env` or stop unused user stacks via `POST /actors/stop`.
## PRD status
All MVP items in `docs/PRD.md` §9 are implemented:
- [x] User auth (Clerk)
- [x] Actor registry (Postgres + Rivet)
- [x] One Grow Agent Rivet Kit actor per user
- [x] Sub-agent registration under the Grow Agent
- [x] Per-user Gitea Docker + memory repo
- [x] Memory commits into the user's Gitea
- [x] Per-user OpenCode Docker + session API
- [x] Message endpoint from frontend to Grow Agent (via Rivet)
- [x] Event stream from agent to frontend (via Rivet broadcast)
- [x] Frontend: login, master chat, sub-agent progress, channel-style logs
Payments and the full quest/pathway runner are deferred to v2 (PRD §10).