xtablo-source/CLAUDE.md
2025-11-15 22:58:18 +01:00

253 lines
8.6 KiB
Markdown

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