Merge remote-tracking branch 'origin/main' into feature/multi-agent-backend

Resolve conflicts:
- CLAUDE.md: merge feature-based frontend docs from main with comprehensive
  architecture docs from HEAD
- Makefile: merge .PHONY targets from both branches
- settings/page.tsx: keep Context field using main's Label component
- auth-context.test.tsx: accept main's deletion (moved to features/auth/)
- cmd/daemon/daemon.go: accept HEAD's deletion (moved to internal/daemon/)
- daemon/client.go: port requestError type and isWorkspaceNotFoundError from
  main's old daemon into the new internal/daemon package

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-03-24 17:53:24 +08:00
commit 0b7de54052
75 changed files with 2513 additions and 2570 deletions

View file

@ -18,6 +18,56 @@ Multica is an AI-native task management platform — like Linear, but with AI ag
- `apps/web/` — Next.js 16 frontend (App Router)
- `packages/` — Shared TypeScript packages (ui, types, sdk, store, hooks, utils)
### Web App Structure (`apps/web/`)
The frontend uses a **feature-based architecture** with three layers:
```
apps/web/
├── app/ # Routing layer (thin shells — import from features/)
├── features/ # Business logic, organized by domain
├── shared/ # Cross-feature utilities (api client)
```
**`app/`** — Next.js App Router pages. Route files should be thin: import and re-export from `features/`. Layout components and route-specific glue (redirects, auth guards) live here. Shared layout components (e.g. `app-sidebar`) stay in `app/(dashboard)/_components/`.
**`features/`** — Domain modules, each with its own components, hooks, stores, and config:
| Feature | Purpose | Exports |
|---|---|---|
| `features/auth/` | Authentication state | `useAuthStore`, `AuthInitializer` |
| `features/workspace/` | Workspace, members, agents | `useWorkspaceStore`, `useActorName` |
| `features/issues/` | Issue components and config | Icons, pickers, status/priority config |
| `features/realtime/` | WebSocket connection | `WSProvider`, `useWSEvent` |
**`shared/`** — Code used across multiple features. Currently only `api.ts` (SDK singleton).
### State Management
- **Zustand** for global client state (`features/auth/store.ts`, `features/workspace/store.ts`).
- **React Context** only for connection lifecycle (`WSProvider` in `features/realtime/`).
- **Local `useState`** for component-scoped UI state (forms, modals, filters).
- Do not use React Context for data that can be a zustand store.
**Store conventions:**
- One store per feature domain. Import via `useAuthStore(selector)` or `useWorkspaceStore(selector)`.
- Stores must not call `useRouter` or any React hooks — keep navigation in components.
- Cross-store reads use `useOtherStore.getState()` inside actions (not hooks).
- Dependency direction: `workspace``auth`, `realtime``auth`, `issues``workspace`. Never reverse.
### Import Aliases
Use `@/` alias (maps to `apps/web/`):
```typescript
import { api } from "@/shared/api";
import { useAuthStore } from "@/features/auth";
import { useWorkspaceStore } from "@/features/workspace";
import { useWSEvent } from "@/features/realtime";
import { StatusIcon } from "@/features/issues/components";
```
Within a feature, use relative imports. Between features or to shared, use `@/`.
### Data Flow
```
@ -63,10 +113,10 @@ Assignees are polymorphic — can be a member or an agent. `assignee_type` + `as
```bash
# One-click setup & run
make setup # First-time: install deps, start DB, migrate
make seed # Optional: load example data
make setup # First-time: ensure shared DB, create app DB, migrate
make start # Start backend + frontend together
make stop # Stop everything
make stop # Stop app processes for the current checkout
make db-down # Stop the shared PostgreSQL container
# Frontend
pnpm install
@ -93,8 +143,8 @@ pnpm --filter @multica/web exec vitest run src/path/to/file.test.ts
pnpm exec playwright test e2e/tests/specific-test.spec.ts
# Infrastructure
docker compose up -d # Start PostgreSQL
docker compose down # Stop PostgreSQL
make db-up # Start shared PostgreSQL
make db-down # Stop shared PostgreSQL
```
### Worktree Support
@ -120,14 +170,18 @@ make start-worktree # Start using .env.worktree
## UI/UX Rules
- Prefer `packages/ui` shadcn components over custom implementations.
- Do not introduce extra state (useState, context, reducers) unless explicitly required by the design.
- **shadcn official components**`packages/ui/src/components/ui/` — keep this directory clean; install missing components via `npx shadcn add`, do not mix in business code.
- **Shared business components & utils**`packages/ui/src/components/common/` — reusable project-level UI components (e.g. ActorAvatar) and shared utilities live here.
- **Feature-specific components**`features/<domain>/components/` — issue icons, pickers, and other domain-bound UI live inside their feature module, not in `packages/ui`.
- Use shadcn design tokens for styling (e.g. `bg-primary`, `text-muted-foreground`, `text-destructive`). Avoid hardcoded color values (e.g. `text-red-500`, `bg-gray-100`).
- Do not introduce extra state (useState, context, reducers) unless explicitly required by the design. Prefer zustand stores for shared state over React Context.
- Pay close attention to **overflow** (truncate long text, scrollable containers), **alignment**, and **spacing** consistency.
- When unsure about interaction or state design, ask — the user will provide direction.
## Testing Rules
- **TypeScript**: Vitest. Mock external/third-party dependencies only.
- **Go**: Standard `go test`. Use testcontainers or test database for DB tests.
- **Go**: Standard `go test`. Tests should create their own fixture data in a test database.
## Commit Rules
@ -146,7 +200,9 @@ make start-worktree # Start using .env.worktree
make check # Runs all checks: typecheck, unit tests, Go tests, E2E
```
For individual checks during development:
Run verification only when the user explicitly asks for it.
For targeted checks when requested:
```bash
pnpm typecheck # TypeScript type errors only
pnpm test # TS unit tests only (Vitest)