# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Common Commands

### Development
```bash
pnpm install                  # Install dependencies
pnpm dev                      # Run all apps in development
pnpm dev:main                 # Run main app only (port 5173)
pnpm dev:external             # Run external booking widget (port 5174)
pnpm dev:api                  # Run API server (port 8080)
```

### Building
```bash
pnpm build                    # Build all apps
pnpm build:apps               # Build apps only (packages are source-only)
pnpm build:staging            # Build main app for staging
pnpm build:prod               # Build main app for production
```

### Testing
```bash
pnpm test                     # Run all tests
pnpm test:watch               # Run tests in watch mode
pnpm test:api                 # Run API tests only
cd apps/main && pnpm test     # Run tests for specific package
```

### Quality Checks
```bash
pnpm lint                     # Check all packages with Biome
pnpm lint:fix                 # Fix linting issues
pnpm typecheck                # Type check everything
pnpm format                   # Format code
```

### Cleanup
```bash
pnpm clean                    # Clean all build artifacts and caches
```

## Architecture Overview

### Monorepo Structure
This is a Turborepo-based monorepo with three main apps and shared packages:

- **apps/main** (`@xtablo/main`): Primary authenticated dashboard with tablos, planning, events, chat, and notes
- **apps/external** (`@xtablo/external`): Public booking widget (embeddable/floating modes)
- **apps/api** (`@xtablo/api`): Hono-based REST API serving both frontend apps
- **packages/shared** (`@xtablo/shared`): React contexts, hooks, API client, React Query setup
- **packages/ui** (`@xtablo/ui`): Radix UI + Tailwind component library
- **packages/shared-types** (`@xtablo/shared-types`): Pure TypeScript types (zero runtime dependencies)

### Source-Only Packages
The `@xtablo/shared` and `@xtablo/ui` packages are **source-only** - they export TypeScript directly without a build step. Changes are instantly reflected via Vite's HMR. There's no need to rebuild or watch these packages during development.

## Key Architectural Patterns

### State Management
1. **React Query** (TanStack Query v5): Primary tool for server state
   - 5-minute default cache time
   - Hierarchical query keys: `["tablos"]`, `["tablos", id]`, `["tablo-files", tabloId]`
   - Targeted cache invalidation on mutations

2. **Zustand**: Global client state, especially user context
   - User fetched via React Query, stored in Zustand for app-wide access
   - Two hooks: `useUser()` (throws if no session) and `useMaybeUser()` (returns null)

### Authentication & Sessions
- **Supabase Auth** with JWT tokens
- `SessionContext` listens to `supabase.auth.onAuthStateChange()`
- API validates JWT from Authorization header
- Passwordless flow generates temporary accounts (`is_temporary: true`)
- Protected routes use `useMaybeUser()` to check authentication

### API Architecture
- **Framework**: Hono (edge-runtime compatible)
- **Middleware Manager**: Singleton pattern (`initializeMiddleware()` called once, reused)
- **Router Order**: Public routes first → middleware applied (supabase → stream/r2/email) → authenticated routes
- **Key Routers**:
  - `public.ts`: Unauthenticated endpoints
  - `authRouter.ts`: Requires authentication
  - `maybeAuthRouter.ts`: Optional authentication
  - `tablo.ts`, `tablo_data.ts`: Core business logic
  - `stripe.ts`: Payment webhooks and operations

### Database & Types
- **Supabase PostgreSQL** with auto-generated types
- Generate types: `npx supabase gen types typescript > packages/shared-types/src/database.types.ts`
- **Type hierarchy**: `database.types.ts` (auto-generated) → domain types (nulls removed) → API responses
- **@xtablo/shared-types**: Zero-dependency package for all types
- Frontend uses direct Supabase client: `supabase.from("table").select()`
- API uses service role key to bypass RLS when needed

### Data Fetching Patterns
1. **Direct Supabase queries**: `useQuery()` → `supabase.from("table").select().eq(...)`
2. **API calls**: `useQuery()` → `api.get("/api/v1/...")` with Bearer token
3. **File operations**: Specialized hooks (`useUploadTabloFile`, `useDeleteTabloFile`) with automatic cache invalidation

### Routing
- **Main app**: Two route sets
  - `publicRoutes`: Auth pages, legal pages (outside UserStoreProvider)
  - `routes`: Protected app routes (inside UserStoreProvider)
- **Protected routes**: Component checks `useMaybeUser()`, redirects to landing if unauthenticated
- **External app**: Query params control mode (`?mode=embed&eventTypeId=...`)

### Component Organization
- Modals: `*Modal.tsx`
- Sections: `*Section.tsx`
- Cards: `*Card.tsx`
- Tests co-located: `*.test.tsx`
- Shared UI in `@xtablo/ui`
- Business logic hooks in `@xtablo/shared`

## External Integrations

### Stream Chat
- Chat provider wraps routes
- Users authenticate with `streamToken` from API

### Stripe
- Webhooks: `/api/v1/stripe-webhook`
- Sync engine keeps Supabase ↔ Stripe in sync
- See `docs/STRIPE_*.md` for detailed documentation

### Storage
- Files stored in Cloudflare R2 (S3-compatible)
- AWS S3 SDK for uploads/downloads
- File metadata in database

### Observability
- **Frontend**: Datadog RUM
- **API**: dd-trace for APM

## Build & Deployment

### Turborepo
- Caches build outputs intelligently
- Tasks run in parallel when possible
- Filter specific apps: `turbo build --filter=@xtablo/main`

### Deployments
- **Main app**: Cloudflare Workers (Vite build)
- **API**: Google Cloud Run (TypeScript compiled)
- **Config**: Centralized in API, secrets from Google Secret Manager

### Environment-Specific Builds
```bash
pnpm build:staging    # Uses .env.staging
pnpm build:prod       # Uses .env.production
```

## Development Conventions

### Query Keys
Use hierarchical naming for proper cache invalidation:
```typescript
["tablos"]                    // List of tablos
["tablos", tabloId]           // Single tablo
["tablo-files", tabloId]      // Files for a tablo
```

### Hook Patterns
All hooks return consistent shapes:
```typescript
// Queries
const { data, isLoading, error } = useMyQuery()

// Mutations
const { mutate, isPending } = useMyMutation()
```

### Error Handling
- Errors display as toast messages via `toast.add()`
- Use friendly, user-facing error messages
- Log technical details for debugging

### Loading States
Three levels of loading feedback:
1. Route level: `ProtectedRoute` shows spinner
2. Feature level: React Query `isLoading`
3. Action level: Button `disabled` during mutation

### Type Safety
- No circular dependencies between packages
- API only imports from `@xtablo/shared-types`
- Frontend apps can import from all shared packages

## Adding New Features

1. **Define types** in `@xtablo/shared-types` or update database schema
2. **Add API endpoint** in `apps/api/src/routers/`
3. **Create React Query hook** in shared or app-specific hooks
4. **Build UI component** using the hook and `@xtablo/ui` components
5. **Add route** to `apps/main/src/lib/routes.tsx` if needed

## Testing Strategy

### API Tests
- Vitest with test environment setup
- Mock Supabase client for database operations
- Test middleware and routers independently
- See `docs/API_TESTS.md` and `docs/MIDDLEWARE_TESTS.md`

### Frontend Tests
- Vitest + React Testing Library + happy-dom
- Test components in isolation
- Mock React Query hooks for integration tests
- Run with `pnpm test` or `pnpm test:watch`

## Important Notes

### Type Generation
After database schema changes, regenerate types:
```bash
npx supabase gen types typescript > packages/shared-types/src/database.types.ts
```

### Cache Issues
If you encounter stale builds or weird caching:
```bash
pnpm clean
rm -rf node_modules/.cache
pnpm install
pnpm build
```

### IDE TypeScript
If VS Code shows type errors but build works:
- Cmd+Shift+P → "TypeScript: Restart TS Server"
- Check `pnpm typecheck` passes
- Ensure package TypeScript configs are valid

### Docker Development
The project includes Docker configurations for deployment:
- See `docs/DOCKER_*.md` for Docker build optimization
- API Dockerfile uses multi-stage builds with pnpm
- Cloud Build configurations in `docs/CLOUD_BUILD_*.md`

## Documentation

Extensive documentation available in `/docs`:
- `DEVELOPMENT.md`: Comprehensive development guide
- `API_*.md`: API testing and integration
- `STRIPE_*.md`: Stripe integration details
- `AUTH_*.md`: Authentication patterns
- `DOCKER_*.md`: Docker and deployment
- `CLOUD_BUILD_*.md`: GCP Cloud Build setup

For questions about architecture decisions or detailed implementation notes, check the docs folder first.
