multica/LOCAL_DEVELOPMENT.md
LinYushen b5674869ed
fix(auth): enforce auth on daemon API routes (#224)
* fix(auth): enforce auth middleware and workspace membership on daemon API routes

Daemon routes were registered without the Auth middleware, meaning the
server accepted unauthenticated requests to register runtimes, claim
tasks, etc. The daemon client already sends a Bearer token — the server
just wasn't validating it.

- Split /api/daemon routes: pairing-session endpoints stay public (used
  before the daemon has a token), all others now require Auth middleware
- Add workspace membership check in DaemonRegister so only workspace
  members can register runtimes
- Update test to include X-User-ID header matching the new auth requirement

Closes MUL-90

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(daemon): remove dead pairing-session feature

The daemon pairing flow was never completed — the daemon authenticates
via CLI config token, not pairing sessions. Remove all related code:

- Delete daemon_pairing.go handler (4 unused handlers)
- Remove pairing routes from router.go (3 public + 1 protected)
- Delete /pair/local page + test from frontend
- Remove DaemonPairingSession types and API client methods
- Add migration 029 to drop daemon_pairing_session table
- Update LOCAL_DEVELOPMENT.md to reflect actual auth flow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 16:13:58 +08:00

461 lines
7.6 KiB
Markdown

# Local Development Guide
This guide documents the intended local development workflow for Multica.
It covers:
- first-time setup
- day-to-day development in the main checkout
- isolated worktree development
- the shared PostgreSQL model
- testing and verification
- troubleshooting and destructive reset options
## Development Model
Local development uses one shared PostgreSQL container and one database per checkout.
- the main checkout usually uses `.env` and `POSTGRES_DB=multica`
- each Git worktree uses its own `.env.worktree`
- every checkout connects to the same PostgreSQL host: `localhost:5432`
- isolation happens at the database level, not by starting a separate Docker Compose project
- backend and frontend ports are still unique per worktree
This keeps Docker simple while still isolating schema and data.
## Prerequisites
- Node.js `v20+`
- `pnpm` `v10.28+`
- Go `v1.26+`
- Docker
## Important Rules
- The main checkout should use `.env`.
- A worktree should use `.env.worktree`.
- Do not copy `.env` into a worktree directory.
Why:
- the current command flow prefers `.env` over `.env.worktree`
- if a worktree contains `.env`, it can accidentally point back to the main database
## Environment Files
### Main Checkout
Create `.env` once:
```bash
cp .env.example .env
```
By default, `.env` points to:
```bash
POSTGRES_DB=multica
POSTGRES_PORT=5432
DATABASE_URL=postgres://multica:multica@localhost:5432/multica?sslmode=disable
PORT=8080
FRONTEND_PORT=3000
```
### Worktree
Generate `.env.worktree` from inside the worktree:
```bash
make worktree-env
```
That generates values like:
```bash
POSTGRES_DB=multica_my_feature_702
POSTGRES_PORT=5432
PORT=18782
FRONTEND_PORT=13702
DATABASE_URL=postgres://multica:multica@localhost:5432/multica_my_feature_702?sslmode=disable
```
Notes:
- `POSTGRES_DB` is unique per worktree
- `POSTGRES_PORT` stays fixed at `5432`
- backend and frontend ports are derived from the worktree path hash
- `make worktree-env` refuses to overwrite an existing `.env.worktree`
To regenerate a worktree env file:
```bash
FORCE=1 make worktree-env
```
## First-Time Setup
### Main Checkout
From the main checkout:
```bash
cp .env.example .env
make setup-main
```
What `make setup-main` does:
- installs JavaScript dependencies with `pnpm install`
- ensures the shared PostgreSQL container is running
- creates the application database if it does not exist
- runs all migrations against that database
Start the app:
```bash
make start-main
```
Stop the app processes:
```bash
make stop-main
```
This does not stop PostgreSQL.
### Worktree
From the worktree directory:
```bash
make worktree-env
make setup-worktree
```
What `make setup-worktree` does:
- uses `.env.worktree`
- ensures the shared PostgreSQL container is running
- creates the worktree database if it does not exist
- runs migrations against the worktree database
Start the worktree app:
```bash
make start-worktree
```
Stop the worktree app processes:
```bash
make stop-worktree
```
## Recommended Daily Workflow
### Main Checkout
Use the main checkout when you want a stable local environment for `main`.
```bash
make start-main
make stop-main
make check-main
```
### Feature Worktree
Use a worktree when you want isolated data and separate app ports.
```bash
git worktree add ../multica-feature -b feat/my-change main
cd ../multica-feature
make worktree-env
make setup-worktree
make start-worktree
```
After that, day-to-day commands are:
```bash
make start-worktree
make stop-worktree
make check-worktree
```
## Running Main and Worktree at the Same Time
This is a first-class workflow.
Example:
- main checkout
- database: `multica`
- backend: `8080`
- frontend: `3000`
- worktree checkout
- database: `multica_my_feature_702`
- backend: generated worktree port such as `18782`
- frontend: generated worktree port such as `13702`
Both checkouts use:
- the same PostgreSQL container
- the same PostgreSQL port: `5432`
But they do not share application data, because each uses a different database.
## Command Reference
### Shared Infrastructure
Start the shared PostgreSQL container:
```bash
make db-up
```
Stop the shared PostgreSQL container:
```bash
make db-down
```
Important:
- `make db-down` stops the container but keeps the Docker volume
- your local databases are preserved
### App Lifecycle
Main checkout:
```bash
make setup-main
make start-main
make stop-main
make check-main
```
Worktree:
```bash
make worktree-env
make setup-worktree
make start-worktree
make stop-worktree
make check-worktree
```
Generic targets for the current checkout:
```bash
make setup
make start
make stop
make check
make dev
make test
make migrate-up
make migrate-down
```
These generic targets require a valid env file in the current directory.
## How Database Creation Works
Database creation is automatic.
The following commands all ensure the target database exists before they continue:
- `make setup`
- `make start`
- `make dev`
- `make test`
- `make migrate-up`
- `make migrate-down`
- `make check`
That logic lives in `scripts/ensure-postgres.sh`.
## Testing
Run all local checks:
```bash
make check-main
```
Or from a worktree:
```bash
make check-worktree
```
This runs:
1. TypeScript typecheck
2. TypeScript unit tests
3. Go tests
4. Playwright E2E tests
Notes:
- Go tests create their own fixture data
- E2E tests create their own workspace and issue fixtures
- the check flow starts backend/frontend only if they are not already running
## Local Codex Daemon
Run the local daemon:
```bash
make daemon
```
The daemon authenticates using the CLI's stored token (`multica login`).
It registers runtimes for all watched workspaces from the CLI config.
## Troubleshooting
### Missing Env File
If you see:
```text
Missing env file: .env
```
or:
```text
Missing env file: .env.worktree
```
then create the expected env file first.
Main checkout:
```bash
cp .env.example .env
```
Worktree:
```bash
make worktree-env
```
### Check Which Database a Checkout Uses
Inspect the env file:
```bash
cat .env
cat .env.worktree
```
Look for:
- `POSTGRES_DB`
- `DATABASE_URL`
- `PORT`
- `FRONTEND_PORT`
### List All Local Databases in Shared PostgreSQL
```bash
docker compose exec -T postgres psql -U multica -d postgres -At -c "select datname from pg_database order by datname;"
```
### Worktree Is Accidentally Using the Main Database
Check whether the worktree contains `.env`.
It should not.
The safe worktree setup is:
```bash
make worktree-env
make setup-worktree
make start-worktree
```
### App Stops but PostgreSQL Keeps Running
That is expected.
- `make stop`
- `make stop-main`
- `make stop-worktree`
only stop backend/frontend processes.
To stop the shared PostgreSQL container:
```bash
make db-down
```
## Destructive Reset
If you want to stop PostgreSQL and keep your local databases:
```bash
make db-down
```
If you want to wipe all local PostgreSQL data for this repo:
```bash
docker compose down -v
```
Warning:
- this deletes the shared Docker volume
- this deletes the main database and every worktree database in that volume
- after that you must run `make setup-main` or `make setup-worktree` again
## Typical Flows
### Stable Main Environment
```bash
cp .env.example .env
make setup-main
make start-main
```
### Feature Worktree
```bash
git worktree add ../multica-feature -b feat/my-change main
cd ../multica-feature
make worktree-env
make setup-worktree
make start-worktree
```
### Return to a Previously Configured Worktree
```bash
cd ../multica-feature
make start-worktree
```
### Validate Before Pushing
Main checkout:
```bash
make check-main
```
Worktree:
```bash
make check-worktree
```