* 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>
7.6 KiB
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
.envandPOSTGRES_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+ pnpmv10.28+- Go
v1.26+ - Docker
Important Rules
- The main checkout should use
.env. - A worktree should use
.env.worktree. - Do not copy
.envinto a worktree directory.
Why:
- the current command flow prefers
.envover.env.worktree - if a worktree contains
.env, it can accidentally point back to the main database
Environment Files
Main Checkout
Create .env once:
cp .env.example .env
By default, .env points to:
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:
make worktree-env
That generates values like:
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_DBis unique per worktreePOSTGRES_PORTstays fixed at5432- backend and frontend ports are derived from the worktree path hash
make worktree-envrefuses to overwrite an existing.env.worktree
To regenerate a worktree env file:
FORCE=1 make worktree-env
First-Time Setup
Main Checkout
From the main checkout:
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:
make start-main
Stop the app processes:
make stop-main
This does not stop PostgreSQL.
Worktree
From the worktree directory:
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:
make start-worktree
Stop the worktree app processes:
make stop-worktree
Recommended Daily Workflow
Main Checkout
Use the main checkout when you want a stable local environment for main.
make start-main
make stop-main
make check-main
Feature Worktree
Use a worktree when you want isolated data and separate app ports.
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:
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
- database:
- worktree checkout
- database:
multica_my_feature_702 - backend: generated worktree port such as
18782 - frontend: generated worktree port such as
13702
- database:
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:
make db-up
Stop the shared PostgreSQL container:
make db-down
Important:
make db-downstops the container but keeps the Docker volume- your local databases are preserved
App Lifecycle
Main checkout:
make setup-main
make start-main
make stop-main
make check-main
Worktree:
make worktree-env
make setup-worktree
make start-worktree
make stop-worktree
make check-worktree
Generic targets for the current checkout:
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 setupmake startmake devmake testmake migrate-upmake migrate-downmake check
That logic lives in scripts/ensure-postgres.sh.
Testing
Run all local checks:
make check-main
Or from a worktree:
make check-worktree
This runs:
- TypeScript typecheck
- TypeScript unit tests
- Go tests
- 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:
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:
Missing env file: .env
or:
Missing env file: .env.worktree
then create the expected env file first.
Main checkout:
cp .env.example .env
Worktree:
make worktree-env
Check Which Database a Checkout Uses
Inspect the env file:
cat .env
cat .env.worktree
Look for:
POSTGRES_DBDATABASE_URLPORTFRONTEND_PORT
List All Local Databases in Shared PostgreSQL
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:
make worktree-env
make setup-worktree
make start-worktree
App Stops but PostgreSQL Keeps Running
That is expected.
make stopmake stop-mainmake stop-worktree
only stop backend/frontend processes.
To stop the shared PostgreSQL container:
make db-down
Destructive Reset
If you want to stop PostgreSQL and keep your local databases:
make db-down
If you want to wipe all local PostgreSQL data for this repo:
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-mainormake setup-worktreeagain
Typical Flows
Stable Main Environment
cp .env.example .env
make setup-main
make start-main
Feature Worktree
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
cd ../multica-feature
make start-worktree
Validate Before Pushing
Main checkout:
make check-main
Worktree:
make check-worktree