Multica Docs

Contributing

Set up a local Multica development environment, run tests, and submit changes using the repository conventions.

Multica is a Go backend and pnpm monorepo. The simplest way to start locally is make dev; it prepares the environment, database, and migrations for the current checkout, then starts Web and API.

Requirements

  • Node.js 22
  • pnpm 10.28.2
  • Go 1.26.6
  • Docker Engine or Docker Desktop
  • Git and Make

Treat the root package.json, server/go.mod, and CI workflows as the source of truth for versions.

First start

git clone https://github.com/multica-ai/multica.git
cd multica
make dev

The primary checkout uses .env. If the file does not exist, make dev creates it from .env.example, then starts the shared PostgreSQL instance, installs dependencies, runs migrations, and starts API and Web.

Default addresses:

Web: http://localhost:3000
API: http://localhost:8080

The fixed local verification code comes from the development configuration. Do not use a local .env for an internet-facing deployment.

Developing in a worktree

The repository supports running the primary checkout and multiple worktrees at the same time. They share one PostgreSQL container but use separate databases and ports.

git worktree add ../multica-feature -b feat/my-change main
cd ../multica-feature
make setup-worktree
make start-worktree

make setup-worktree generates .env.worktree; the database name and ports are derived from the path. To start it again:

make start-worktree

To stop Web and API for the current worktree:

make stop-worktree

You may also run make dev directly. The script detects a worktree through its .git file and selects .env.worktree.

Different worktrees share the PostgreSQL container, not the database. Do not start a new Compose project for every worktree. Check POSTGRES_DB, PORT, and FRONTEND_PORT in .env.worktree first.

Common commands

Full workflow

make up               # Start this checkout's environment (C=api,web,daemon,desktop)
make status           # Show what is running and prove it is this environment
make list             # List every environment on this machine
make down             # Stop the processes, keep the database
make destroy          # Stop, then drop the database and free the slot
make gc               # Collect expired or directory-less environments
make dev              # Prepare and start the current checkout in the foreground
make check            # Run the complete local verification workflow
make build            # Build the server, CLI, and migrate binaries

make up treats an environment as a named object: it allocates the API, Web and Desktop renderer ports, database name and CLI profile under a lock and records them in ~/.multica/dev/, so two checkouts cannot land on the same slot without one of them being told. It verifies the database through DATABASE_URL and the backend through GET /health, which reports pid, commit and started_at — a 200 alone would also come from a leftover process on the same port. make destroy removes the database, CLI profile, daemon workspaces, Desktop userData and registry entry; a failed deletion keeps the registry entry for retry. Temporary environments are collected best-effort on the next make up after their TTL.

Frontend

pnpm install
pnpm dev:web
pnpm dev:desktop
pnpm build
pnpm typecheck
pnpm lint
pnpm test

Root commands exclude Mobile by default. Mobile has separate scripts and CI; read apps/mobile/CLAUDE.md before changing it.

Backend

make server
make daemon
make test
make migrate-up
make migrate-down
make sqlc

To run a CLI command from source:

make cli ARGS="issue list"

Changing frontend features

Place features needed by both Web and Desktop according to responsibility:

  1. Put API types, queries, mutations, and platform-independent logic in packages/core/.
  2. Put foundational UI in packages/ui/; it must not depend on business code.
  3. Put business pages and components in packages/views/.
  4. Keep Next.js, Electron, and routing adapters in the corresponding app.
  5. Wire shared pages into both Web and Desktop.

TanStack Query owns server data. Zustand owns client state such as filters, drafts, and layout. See Project architecture and the root CLAUDE.md for the exact boundary.

When adding or changing an API, update the zod schema in packages/core/api/ and add parsing tests for missing fields, unknown enum values, and malformed data.

Changing the database

Migrations live in server/migrations/, and queries live in server/pkg/db/queries/.

  1. Use the next unused numeric prefix and create both .up.sql and .down.sql.
  2. Do not add database foreign keys, cascade deletes, or cascade updates. Enforce relationships and cleanup in the application layer.
  3. Every new index must use CREATE INDEX CONCURRENTLY or CREATE UNIQUE INDEX CONCURRENTLY.
  4. Put each concurrent index in a migration file containing only that statement.
  5. Run make sqlc after changing queries and commit the generated changes in server/pkg/db/generated/.
  6. Do not edit sqlc-generated files directly.

Use an application transaction in the service layer when multiple writes must succeed or roll back together.

Test locations

ChangeTest location
Shared business logic, queries, storespackages/core/*.test.ts
Shared pages and componentspackages/views/*.test.tsx
Web or Desktop platform wiringCorresponding apps/* directory
End-to-end workflowse2e/*.spec.ts
Backend*_test.go in the relevant Go package

Run the check closest to the change first, then expand the scope. For a Docs-only change:

pnpm --filter @multica/docs typecheck

For shared frontend changes:

pnpm typecheck
pnpm test

For backend changes:

make test

Before submitting:

make check

make check runs TypeScript typechecking and unit tests, Go tests, and Playwright E2E. CI also builds and lints according to the changed scope and runs platform- or installer-specific tests.

Resetting the current development database

When you need clean data, reset the database named by the current checkout's environment file:

make stop
make db-reset
make start

make db-reset drops and recreates the current POSTGRES_DB and refuses to connect to a remote database. Before running it, check .env or .env.worktree and confirm the target database.

Before submitting

  • Read the root CLAUDE.md and relevant nested instructions.
  • Change only the scope required by the task.
  • Write code comments in English.
  • Do not commit .env, tokens, build artifacts, or local paths.
  • Use conventional commits such as feat(scope), fix(scope), or docs.
  • Describe behavior changes and the verification commands actually run in the PR.

Next steps