# 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.