|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +LetterSpace is an open source, self-hosted newsletter platform. It's a pnpm monorepo with Turbo for task orchestration. |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +### Development |
| 12 | + |
| 13 | +```bash |
| 14 | +pnpm dev # Run all dev servers (Turbo) |
| 15 | +pnpm build # Build all projects |
| 16 | +pnpm lint # Lint all projects |
| 17 | +pnpm format # Format with Prettier |
| 18 | +``` |
| 19 | + |
| 20 | +### Backend-specific |
| 21 | + |
| 22 | +```bash |
| 23 | +pnpm --filter backend dev # Run backend only |
| 24 | +pnpm --filter backend test # Run tests (Vitest) |
| 25 | +pnpm --filter backend generate # Prisma codegen |
| 26 | +pnpm --filter backend migrate:dev # Dev migrations |
| 27 | +``` |
| 28 | + |
| 29 | +### Database |
| 30 | + |
| 31 | +```bash |
| 32 | +pnpm --filter backend prisma db seed # Seed database |
| 33 | +cd apps/backend && pnpm prisma migrate reset --force # Reset and reseed |
| 34 | +``` |
| 35 | + |
| 36 | +### Release Process |
| 37 | + |
| 38 | +```bash |
| 39 | +./scripts/release.sh # Bumps patch version (default) |
| 40 | +./scripts/release.sh minor # Bumps minor version |
| 41 | +./scripts/release.sh major # Bumps major version |
| 42 | +``` |
| 43 | + |
| 44 | +The script bumps version in `package.json`, creates a git tag, and pushes it. GitHub Actions builds Docker images and creates a release from `RELEASE_NOTES.md`. |
| 45 | + |
| 46 | +## Architecture |
| 47 | + |
| 48 | +### Monorepo Structure |
| 49 | + |
| 50 | +- `apps/backend` - Express + TRPC backend (Bun/Node.js) |
| 51 | +- `apps/web` - Vite + React dashboard (PWA) |
| 52 | +- `apps/landing-page` - Next.js marketing site |
| 53 | +- `apps/docs` - Nextra documentation |
| 54 | +- `packages/ui` - Shared Shadcn UI components |
| 55 | +- `packages/shared` - Shared TypeScript types |
| 56 | +- `packages/eslint-config` - Shared ESLint config |
| 57 | + |
| 58 | +### Backend Architecture |
| 59 | + |
| 60 | +TRPC routers in `apps/backend/src/router/`: |
| 61 | +- Each domain (user, campaign, subscriber, etc.) has its own directory |
| 62 | +- Pattern: `router.ts` (definition), `mutation.ts` (writes), `query.ts` (reads) |
| 63 | + |
| 64 | +Key entry points: |
| 65 | +- `apps/backend/src/app.ts` - Express app setup, middleware, routes |
| 66 | +- `apps/backend/src/trpc.ts` - TRPC context and auth |
| 67 | +- `apps/backend/src/cron/` - Scheduled jobs (email sending, maintenance) |
| 68 | + |
| 69 | +Endpoints: |
| 70 | +- `/trpc/*` - TRPC RPC endpoints |
| 71 | +- `/api/*` - REST API (Swagger documented) |
| 72 | +- `/t/:id` - Link tracking redirect |
| 73 | +- `/img/:id/img.png` - Email open tracking pixel |
| 74 | + |
| 75 | +### Frontend Architecture |
| 76 | + |
| 77 | +React Router app in `apps/web/src/`: |
| 78 | +- `app.tsx` - Route definitions |
| 79 | +- `pages/` - Page components matching routes |
| 80 | +- TRPC client with React Query for data fetching |
| 81 | +- Token auth via cookies |
| 82 | + |
| 83 | +### Database |
| 84 | + |
| 85 | +Prisma ORM with PostgreSQL. Schema at `apps/backend/prisma/schema.prisma`. |
| 86 | + |
| 87 | +Key models: User, Organization (multi-tenancy), Subscriber, List, Campaign, Template, Webhook. |
| 88 | + |
| 89 | +## Tech Stack |
| 90 | + |
| 91 | +- **Backend**: Express, TRPC, Prisma, PostgreSQL, Bun/Node.js 22+ |
| 92 | +- **Frontend**: React 19, Vite, React Router, Shadcn UI, TailwindCSS |
| 93 | +- **Shared**: TypeScript (strict), Zod, React Hook Form |
| 94 | + |
| 95 | +## Code Style |
| 96 | + |
| 97 | +- Adhere to existing code patterns in the codebase |
| 98 | +- Minimal comments |
| 99 | +- Component files: kebab-case (e.g., `user-profile.tsx`) |
| 100 | +- Component exports: PascalCase (e.g., `export const UserProfile`) |
| 101 | +- Colocate types/data with components when only used by that component |
| 102 | + |
| 103 | +## Development Notes |
| 104 | + |
| 105 | +- Email sending is disabled in development (`NODE_ENV=development`) - cron jobs skip and mailer returns mock responses |
| 106 | +- Backend tests use `.env.test` for configuration |
| 107 | +- Webhook transformers run in QuickJS sandbox with configurable memory limits |
0 commit comments