This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
TaskMan is a full-stack task management application built as a monorepo with separate backend (Express + Prisma + PostgreSQL) and frontend (React + Vite) services.
# Development
npm run dev # Start dev server with tsx watch
npm run build # Compile TypeScript to dist/
npm start # Run compiled server
# Database
npm run prisma:generate # Generate Prisma client
npm run prisma:migrate # Create and apply new migration
npm run prisma:migrate:deploy # Deploy migrations (production)
npm run prisma:studio # Open Prisma Studio GUI
npm run prisma:seed # Seed database with test data
# Testing
npm test # Run all tests with Jest
npm test -- --testPathPattern=auth # Run a single test suite (e.g., auth.test.ts)
npm test -- --testNamePattern="login" # Run tests matching a name pattern
# NODE_OPTIONS=--experimental-vm-modules is required (included in npm test script)
# Linting
npm run lint # Check for lint errors
npm run lint:fix # Auto-fix lint errors# Development
npm run dev # Start Vite dev server
npm run build # Build for production
npm run preview # Preview production build
# Testing
npm test # Run Vitest tests
npm run test:watch # Run tests in watch mode
npm run coverage # Generate coverage report
# Run a single test file:
npx vitest run src/components/SomeComponent.test.tsx
# Type checking & linting
npm run type-check # TypeScript type checking
npm run lint # Check for lint errors
npm run lint:fix # Auto-fix lint errorsdocker-compose up # Start all services (postgres, backend, frontend)
docker-compose up postgres # Start only PostgreSQL
docker-compose down # Stop all services- Authentication: JWT tokens stored in HTTP-only cookies (
auth_token). Also supports API key authentication viaX-API-Keyheader withtaskman_prefix - Dual auth paths: Cookie/Bearer JWT (primary) and API key (for integrations)
- Authorization: Role-based access control (OWNER > ADMIN > MEMBER > VIEWER) at project level
- Validation: All inputs validated with Zod schemas
- Real-time: Socket.io for WebSocket connections, authenticated via JWT from cookie
- Error handling: Centralized error handler with
AppErrorclass - Rate limiting: API key-specific rate limiting middleware
- Routes: Organized by feature in
src/routes/, mounted insrc/app.ts - Middleware: Authentication, error handling, rate limiting, and RBAC in
src/middleware/ - Database: Prisma ORM with PostgreSQL, schema in
prisma/schema.prisma
- State management: Zustand stores in
src/store/(auth, layout, timer, density, theme, socket, etc.) - Data fetching: TanStack React Query with API client in
src/lib/api.ts - Routing: React Router v6 — pages include Dashboard, Tasks, Check-in (
/checkin), Agent Queue (/agents) - Real-time: Socket.io client in
src/lib/socket.tswith hooks insrc/hooks/ - Styling: Tailwind CSS with theme system and density settings
- Animations: Framer Motion with performance optimizations
- Key components:
DelegateModal(AI agent delegation),DomainPicker(domain selection),ProgressOverview,WeekView
Key models:
- User: Authentication and profile (with XP, level, streak fields)
- Project: Container for tasks with team members
- Task: Core entity with status, priority, assignments, dependencies
- ProjectMember: Project membership with roles
- RecurringTask: Template for generating recurring tasks
- TimeEntry: Time tracking with start/end/duration
- Comment: Threaded comments on tasks with @mentions
- ActivityLog: Audit trail for task changes
- Tag/TaskTag: Project-scoped tags for tasks
- CustomFieldDefinition/CustomFieldValue: Extensible task metadata
- Attachment: File uploads linked to tasks
- TaskDependency: Task blocking relationships
- Notification: User notifications
- ApiKey/Webhook/WebhookLog: API integration features
- Achievement/UserAchievement: Gamification badges
- UserQuest/UserSkill/XPLog/StreakProtectionLog: Gamification progression
- Domain/TaskDomain: User-scoped life/work areas (e.g. Coding, Marketing); auto-seeded with 5 defaults on first fetch
- DailyCheckin: Daily check-in records (priorities, energy level, blockers, focus domains)
- AgentDelegation: AI agent task delegation with status tracking (QUEUED → IN_PROGRESS → COMPLETED/FAILED)
- Backend: Jest with ts-jest, supertest for API testing, ~440 tests across 24 suites
- Test database:
taskapp_testatpostgresql://taskapp:taskapp_secret@localhost:5432/taskapp_test - Test pattern:
beforeAllfor setup, create users via API endpoints,--runInBand --forceExitflags - Windows note: Set env vars separately (not inline Unix-style)
- Coverage: Suites include Auth, Projects, Tasks, Time tracking, Comments, Analytics, Domains, Checkins, Agents, Webhooks, WebSocket, Gamification, etc.
- Socket.io server initialized in
src/index.tsviainitializeSocket() - Authentication: JWT extracted from cookie on connection
- Rooms: User-specific (
user:<userId>) and task-specific (task:<taskId>) - Events: Real-time updates for tasks, comments, notifications, agent status (
agent:status) - Client hooks:
useSocket,useTaskSocketin frontend
- Non-critical operation (try-catch, no throw)
- Logs all task changes (create, update, delete, status changes)
- Also logs comment and dependency changes
- Stored in
ActivityLogmodel with user, task, action, field, oldValue, newValue
- Routes use per-route
authenticatemiddleware (notrouter.use) to avoid catching unrelated/api/*paths - Supports threaded replies via
parentId - Markdown rendering support
- @mentions trigger notifications
- Real-time updates via WebSocket
PORT=4000
DATABASE_URL=postgresql://taskapp:taskapp_secret@postgres:5432/taskapp?schema=public
JWT_SECRET=your-secret-key-here
JWT_EXPIRES_IN=7d
CORS_ORIGIN=http://localhost:5173
NODE_ENV=development
RESEND_API_KEY=re_... # Email delivery (forgot-password, etc.)
FRONTEND_URL=http://localhost:5173 # Used for reset-password links
# Stripe (required for billing features):
STRIPE_SECRET_KEY=sk_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_PRO_MONTHLY=price_...
STRIPE_PRICE_PRO_ANNUAL=price_...
STRIPE_PRICE_TEAM_MONTHLY=price_...
STRIPE_PRICE_TEAM_ANNUAL=price_...Important:
- Use
postgresas hostname in Docker Compose (service name),localhostfor local development JWT_SECRETis REQUIRED - server will refuse to start without itCORS_ORIGINsupports comma-separated origins for multi-service deployments
VITE_API_URL=http://localhost:4000- Create route file in
backend/src/routes/[feature].ts - Use
authenticatemiddleware for protected routes - Validate inputs with Zod schemas
- Import and mount in
src/app.ts - Add tests in
backend/tests/
- Modify
prisma/schema.prisma - Run
npm run prisma:migrate(creates migration + generates client) - Windows Prisma DLL issue: If dev server is running, you may get DLL lock errors. Types still work from migration step, but restart dev server if needed.
- Update TypeScript types and routes accordingly
- Define event in socket server (
backend/src/lib/socket.ts) - Emit events from route handlers after DB updates
- Add socket listener in frontend (
src/hooks/useSocket.tsoruseTaskSocket.ts) - Update Zustand store or React Query cache
- Plans:
PlanTierenum —FREE,PRO,TEAM(stored onUser.plan) - Stripe:
backend/src/lib/stripe.ts(SDK);backend/src/routes/billing.ts(checkout session, customer portal, webhook) - Webhook: requires raw body — mounted with
express.raw()BEFOREexpress.json()inapp.ts - Middleware chain:
authenticate→loadPlan→requirePlan('PRO', 'TEAM')orrequireQuota('agentDelegations')loadPlan: attachesreq.userPlanfrom DBrequirePlan(...tiers): blocks if user's plan not in listrequireQuota(feature): checks usage againstPLAN_LIMITS(does NOT increment — increment after success viaincrementUsage())requireProjectRole(...roles): project-level RBAC gate — readsreq.params.projectId(or.id), fetches membership, rejects non-members and wrong roles with 403; attachesreq.projectMembershipon success
- Usage tracking:
backend/src/lib/usage.ts—incrementUsage(),getUsage(),checkFeatureAccess() - Gated features: AI delegation, API keys, webhooks (all require PRO/TEAM)
- Frontend:
/billingroute →BillingPage.tsx;UpgradePromptcomponent for in-app gates;PlanBadgeshows current plan
When running tests, linting, or pre-commit hooks reveals failures — regardless of whether they were caused by the current change set:
- Never disclaim them away — phrases like "pre-existing, not caused by my changes" are a red flag. They shift attention away from a real problem.
- Never bypass or sidestep checks — NEVER unstage files, skip hooks (
--no-verify), or narrow the commit scope just to avoid errors. If a pre-commit hook fails, the correct response is to fix the errors, not dodge them. This is the highest-priority rule in this section. - Always log them — open a task (via the TaskCreate tool) describing the failure, root cause if known, and affected files. This ensures it is tracked and not forgotten.
- Fix them when in scope — if the error is fixable without large scope expansion (e.g., a lint error, a broken Jest config), fix it in the same session before committing. Report what was done.
- Escalate when out of scope — if the fix would balloon scope, create the task, note it in the commit message, and tell the user explicitly. Do not commit until the user acknowledges the error. Even if the commit itself would pass, the error must be surfaced.
The goal is: no error silently disappears behind a disclaimer, a narrowed staging area, or a skipped hook.
- Main branch:
main - Feature branches:
claude/[feature-name]-[hash]prefix for PR branches - When resolving conflicts between implementation and test PRs: prefer the implementation that was co-designed with tests
- Commits use descriptive messages, often include "Co-Authored-By: Claude Sonnet 4.6"
When running npm run prisma:migrate on Windows with dev server running, you may encounter DLL lock errors. The Prisma client types are still generated and usable, but you may need to restart the dev server to clear the lock.
Before running tests:
- Start PostgreSQL:
docker compose up -d postgres - Create test database:
CREATE DATABASE taskapp_test; - Deploy migrations:
cd backend && DATABASE_URL=postgresql://taskapp:taskapp_secret@localhost:5432/taskapp_test npx prisma migrate deploy - Run tests with proper env vars
Mobile browsers may have cross-origin cookie issues (ITP/SameSite). Backend supports fallback Bearer token authentication via Authorization: Bearer <token> header.
Backend: Node.js, TypeScript, Express, Prisma, PostgreSQL, Socket.io, JWT, bcrypt, Zod, Jest Frontend: React 18, TypeScript, Vite, Zustand, TanStack Query, React Router, Tailwind CSS, Framer Motion, Socket.io-client, dnd-kit DevOps: Docker, Docker Compose, Railway (deployment platform)