1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Project Overview
6
7This is an ATProto OAuth application monorepo with separate frontend and backend packages. The backend is an XRPC server built with Elysia, and the frontend is built with React Router v7 (SSR) handling OAuth authentication.
8
9**Current Status**: Core functionality implemented. OAuth authentication working on client-side (SSR), XRPC server operational, post creation and storage functional. This is a full-stack ATProto microblogging application with ATProto-native architecture.
10
11## Monorepo Structure
12
13This project is organized as a Bun workspace monorepo:
14
15```
16watproto/
17├── packages/
18│ ├── server/ # XRPC API server (ATProto endpoints, post storage)
19│ │ ├── src/ # Server source code
20│ │ │ ├── db/ # Database migrations and schema
21│ │ │ └── lib/ # XRPC server, ID resolver, utilities
22│ │ ├── data/ # SQLite database files
23│ │ ├── CLAUDE.md # Server-specific documentation
24│ │ └── package.json # Server dependencies
25│ ├── client/ # React Router v7 frontend (SSR with OAuth)
26│ │ ├── app/ # React Router application code
27│ │ │ ├── routes/ # File-based routes (login, editor, oauth)
28│ │ │ ├── components/ # React components (Header, PostFeed, etc.)
29│ │ │ └── lib/ # OAuth client, XRPC client, DB, utilities
30│ │ ├── data/ # SQLite database (OAuth state storage)
31│ │ ├── CLAUDE.md # Client-specific documentation
32│ │ └── package.json # Client dependencies
33│ └── lexicon/ # ATProto lexicon type definitions
34│ ├── types/ # Generated TypeScript types
35│ ├── index.ts # Lexicon exports
36│ └── package.json # Package configuration
37├── lexicons/ # ATProto lexicon schemas (JSON)
38├── lex.config.js # Lexicon generation configuration
39├── lexicons.json # Lexicon metadata
40├── package.json # Workspace root configuration
41├── tsconfig.root.json # Base TypeScript configuration
42├── CLAUDE.md # This file (monorepo-wide documentation)
43└── README.md # Project setup and usage instructions
44```
45
46**Current Architecture**:
47```
48React Router Frontend (SSR) - packages/client
49 ├── OAuth Client (ATProto OAuth flow)
50 ├── Session Management (SQLite state DB)
51 └── XRPC Client
52 ↓ XRPC calls (ATProto RPC protocol)
53XRPC Server - packages/server
54 ├── Post Storage (public/private posts, tags)
55 ├── Account Management
56 └── ID Resolution
57 ↓ ATProto operations
58ATProto Network
59```
60
61## Common Commands
62
63### Typical Development Workflow
641. **Terminal 1** (Server): `cd packages/server && bun run dev`
652. **Terminal 2** (Client): `cd packages/client && bun run dev`
663. **Access**: Open http://127.0.0.1:5173 in browser
67
68### Workspace Commands (from root)
69- `bun install` - Install dependencies for all packages
70- `bun run dev` - Start both server and client in development mode
71- `bun run dev:server` - Start server only (port 3000)
72- `bun run dev:client` - Start client only (port 5173)
73- `bun run build` - Build client for production
74- `bun run typecheck` - Type check all packages
75- `bun run lex` - Generate TypeScript types from ATProto lexicons
76
77### Server Commands (from packages/server)
78- `bun run dev` - Start development server with hot reload on port 3000
79- `bun run start` - Start production server
80- `bun run debug` - Start server with Bun debugger
81- `bun run db:codegen` - Regenerate database schema types from database
82- `bun run db:migrate` - Run database migrations manually
83- `bun run typecheck` - Run TypeScript type checking
84
85### Client Commands (from packages/client)
86- `bun run dev` - Start development server with hot reload (port 5173)
87- `bun run build` - Build production bundle
88- `bun run start` - Start production server
89- `bun run lint` - Run ESLint
90- `bun run typecheck` - Run TypeScript type checking
91
92## Architecture
93
94### Core Stack
95
96**Backend (packages/server)**:
97- **Runtime**: Bun
98- **Web Framework**: Elysia (type-safe, fast web framework)
99- **Protocol**: XRPC (ATProto RPC) via @atcute/xrpc-server
100- **Database**: SQLite with Kysely query builder
101- **Features**: Post storage, account management, ID resolution
102- **TypeScript**: Strict mode enabled with path aliases
103
104**Frontend (packages/client)**:
105- **Runtime**: Bun
106- **Framework**: React Router v7 (file-based routing, SSR)
107- **OAuth**: ATProto OAuth Client (Node implementation) - runs in SSR
108- **Database**: SQLite for OAuth session state (server-side)
109- **Protocol**: XRPC client via @atcute/client
110- **Identity Resolution**: @atcute/identity-resolver + @atcute/identity (DID/handle resolution)
111- **UI Library**: React 19
112- **Styling**: Tailwind CSS v4 + DaisyUI
113- **Build Tool**: Vite
114- **TypeScript**: Strict mode enabled with path aliases
115
116**Shared (packages/lexicon)**:
117- **Purpose**: ATProto lexicon type definitions
118- **Generator**: @atcute/lex-cli
119- **Source**: Lexicon schemas in `lexicons/` directory
120
121**Deployment Strategy**:
122- Client: SSR deployment (Vercel, Netlify with SSR, Cloudflare Pages)
123 - Note: Requires SSR support due to OAuth and database
124- Server: Node/Bun hosting (Fly.io, Railway, etc.)
125- Communication: XRPC protocol (not REST)
126
127### OAuth Flow Architecture
128
129**Client implements ATProto OAuth in SSR** (see `packages/client/CLAUDE.md` for details):
1301. **Login**: User visits `/login` route, enters handle
1312. **OAuth Flow**: React Router SSR initiates OAuth with ATProto
1323. **Callback**: `/oauth/$` route handles callback, stores session in SQLite
1334. **Session**: Session stored in client's database (data/state.db)
1345. **Protected Routes**: Loader functions check session before rendering
135
136**Architecture Notes**:
137- OAuth client runs in React Router's SSR layer (Node.js context)
138- Session state stored in SQLite database on client server
139- Uses @atproto/oauth-client-node for ATProto OAuth flow
140- XRPC client uses authenticated sessions for API calls to server
141
142### Database Architecture
143
144**Server Database** (`packages/server/data/`):
145- **Location**: SQLite with WAL mode
146- **Tables**:
147 - `accounts` - User accounts with DID, handle, metadata
148 - `public_posts` - Public posts visible to all
149 - `private_posts` - Private posts for account holders
150 - `tags` - Tag associations for posts
151- **Details**: See `packages/server/CLAUDE.md` for full schema
152
153**Client Database** (`packages/client/data/`):
154- **Location**: SQLite database for OAuth state
155- **Purpose**: Store OAuth sessions, states, and tokens
156- **Implementation**: Managed by @atproto/oauth-client-node
157- **Details**: See `packages/client/CLAUDE.md` for session management
158
159### Environment Variables
160
161**Server** (`packages/server/.env.local`):
162- `PORT` - Server port (default: 3000)
163- `DATABASE_URL` - SQLite database path (default: ':memory:')
164- `SERVICE_DID` - DID that points to this service (required)
165
166**Client** (`packages/client/.env.local`):
167- `CLIENT_URL` - Client URL (optional)
168- `API_URL` - XRPC server API URL (required, e.g., http://localhost:3000)
169- `DEFAULT_PDS_URL` - Default PDS URL for OAuth (required)
170- `DB_PATH` - SQLite database path (default: './data/state.db')
171- `PORT` - Client server port (default: 5173)
172- `AUTH_SECRET` - Secret for session encryption (required)
173- `KEYSERVER_DID` - DID that poins to a [Keyserver](https://tangled.org/@djara.dev/atp-keyserver) for encryption / decryption (required)
174
175## Package-Specific Documentation
176
177For detailed implementation information, refer to the package-specific CLAUDE.md files:
178
179- **Server**: `packages/server/CLAUDE.md`
180 - XRPC server implementation
181 - Database patterns and migrations
182 - Post storage and retrieval
183 - Social graph (follow relationships)
184 - Profile management (wafrn-specific + caching)
185 - Account management (operational data)
186 - ID resolution
187
188- **Client**: `packages/client/CLAUDE.md`
189 - React Router v7 routing patterns
190 - OAuth authentication flow (SSR)
191 - XRPC client integration
192 - Component architecture
193 - Session management
194 - Styling with Tailwind CSS + DaisyUI
195
196- **Lexicon**: `packages/lexicon/`
197 - ATProto lexicon type definitions
198 - Generated from schemas in `lexicons/` directory
199 - Shared types across server and client
200
201## Working with the Monorepo
202
203### Adding New Features
204
205**Backend API Endpoint**:
2061. Navigate to `packages/server`
2072. Create route handler in `src/` (or add to existing routes)
2083. Test with `bun run dev`
2094. See `packages/server/CLAUDE.md` for patterns
210
211**Frontend Feature**:
2121. Navigate to `packages/client`
2132. Create route in `app/routes/` (file-based routing)
2143. Create components in `app/components/`
2154. Test with `bun run dev`
2165. See `packages/client/CLAUDE.md` for patterns
217
218### Path Aliases
219
220The monorepo uses TypeScript path aliases for cleaner imports:
221
222**Configured in `tsconfig.root.json`:**
223- `@api/*` → `packages/server/src/*` - Server internal imports
224- `@www/*` → `packages/client/app/*` - Client internal imports
225
226**Server Usage** (`packages/server`):
227```typescript
228import { db } from '@api/db/db'
229import env from '@api/lib/env'
230import { createOrUpdateAccount } from '@api/lib/account'
231import { xrpcServer } from '@api/lib/xrpcServer'
232```
233
234**Client Usage** (`packages/client`):
235```typescript
236// Client internal imports
237import { Header } from '@www/components/Header'
238import { xrpcClient } from '@www/lib/xrpcClient'
239
240// Import server types (type-only imports)
241import type { Account } from '@api/db/schema'
242```
243
244**Lexicon Usage** (both packages):
245```typescript
246import { Watproto } from '@watproto/lexicon'
247```
248
249**Benefits:**
250- Clean, consistent import paths across the monorepo
251- No relative path traversal (`../../..`)
252- Type sharing between packages via workspace dependencies
253- Vite and Bun automatically resolve these paths
254
255**Note:** Lexicon package is a workspace dependency used by both server and client.
256
257## Current Features & Future Expansion
258
259### Implemented
260- ✅ ATProto OAuth authentication (client-side SSR)
261- ✅ Session management with SQLite
262- ✅ XRPC server and client
263- ✅ Post creation and storage (public and private)
264- ✅ Post deletion (transactional, removes post and associated tags)
265- ✅ Tag system for posts
266- ✅ User authentication flow
267- ✅ UI components
268 - Header, PostFeed, UserMenu
269 - GlobalSpinner (navigation state feedback)
270 - Delete post button (visible to post authors only)
271- ✅ Lexicon type generation
272- ✅ Social graph (follow relationships)
273 - Follow/unfollow operations with transaction-safe count updates
274 - Follower and following list queries (returns DIDs for batch enrichment)
275 - Denormalized follow counts for fast profile queries
276 - Federation-friendly (no foreign key constraints)
277- ✅ Profile system (separated architecture)
278 - Operational account data (roles, status, moderation)
279 - Wafrn-specific profile customization (HTML bio, custom fields)
280 - Optional standard profile caching for performance
281 - Batch profile queries for efficient rendering
282
283### Planned Features
284- **Job Queue & Workers**: Background processing for posts, firehose consumption, timelines
285- **Real-time Features**: WebSocket support for notifications and live updates
286- **Media Upload**: Image and video upload with ATProto blob storage
287- **Timeline Algorithm**: Personalized feed ranking and filtering
288- **Search**: Full-text search for posts and user profiles
289- **Multi-Account Support**: Support being logged in to more than one account at the same time
290
291See package-specific CLAUDE.md files for detailed implementation plans.
292
293## Getting Started with your local copy
294
2951. **Clone and install**:
296 ```bash
297 git clone <repo-url>
298 cd watproto
299 bun install
300 ```
301
3022. **Configure environment variables**: use the examples in this file
303
3043. **Start development**:
305 ```bash
306 # Terminal 1: Start server
307 cd packages/server
308 bun run dev
309
310 # Terminal 2: Start client
311 cd packages/client
312 bun run dev
313 ```
314
3154. **Access the application**:
316 - Client: http://127.0.0.1:5173
317 - Server API: http://localhost:4000
318 - API Docs: http://localhost:4000/openapi
319
320## Troubleshooting
321
322- **Port conflicts**: Change `PORT` in server .env.local or client will use next available port
323- **CORS errors**: Ensure server CORS is configured to allow client origin
324- **Type errors**: Run `bun install` at root to sync workspace dependencies
325- **Database issues**: If your local `packages/server/data/*.db*` files do not have important information you can just delete them and restart your server. Database files will be created from scratch.
326
327For package-specific issues, see the CLAUDE.md file in that package.