- React frontend with Vite + TypeScript - Cloudflare Worker backend with Durable Objects - AI-powered chat moderation via OpenAI - WebSocket-based real-time messaging - XSS prevention, rate limiting, input validation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
87 lines
3.5 KiB
Markdown
87 lines
3.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Real-time chat application with AI-powered moderation. Korean-language community chat ("Anvil Lounge") with an AI bot host (방장) that moderates conversations, answers questions, and provides weather/documentation lookups.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
chat-app/
|
|
├── frontend/ # React SPA (Vite + TypeScript)
|
|
│ └── src/
|
|
│ ├── components/ # ChatRoom, MessageList, MessageInput
|
|
│ ├── hooks/ # useWebSocket (WebSocket client with reconnection)
|
|
│ └── utils/ # sanitize.ts (XSS prevention, markdown→HTML)
|
|
└── worker/ # Cloudflare Worker + Durable Object
|
|
└── src/
|
|
├── index.ts # HTTP router, CORS handling
|
|
├── ChatRoom.ts # Durable Object: WebSocket hub, message persistence
|
|
├── AIManager.ts # OpenAI integration, moderation, tool calling
|
|
├── Context7Client.ts # Documentation lookup API
|
|
├── RateLimiter.ts # In-memory rate limiting
|
|
└── validation.ts # Zod schemas for message validation
|
|
```
|
|
|
|
### Key Design Patterns
|
|
|
|
**Durable Objects with Hibernation API**: `ChatRoom` uses `webSocketMessage()`, `webSocketClose()`, `webSocketError()` handlers instead of event listeners. Session data stored via `ws.serializeAttachment()`.
|
|
|
|
**AI Moderation Flow**: Messages are checked by AI for profanity before broadcast. Detected words are masked (첫 글자 + asterisks). Repeated violations trigger auto-silence via `trackViolation()` → DO storage transaction.
|
|
|
|
**Storage Patterns**: All DO storage operations use transactions for atomicity and retry logic with jitter for resilience.
|
|
|
|
## Development Commands
|
|
|
|
```bash
|
|
# Root-level (npm workspaces)
|
|
npm run dev:worker # Start worker dev server (wrangler)
|
|
npm run dev:frontend # Start Vite dev server (localhost:5173)
|
|
npm run build:worker # Build worker
|
|
npm run build:frontend # Build frontend (tsc + vite)
|
|
npm run deploy:worker # Deploy to Cloudflare Workers
|
|
npm run deploy:frontend # Deploy to Cloudflare Pages
|
|
|
|
# Type checking
|
|
cd worker && npx tsc --noEmit
|
|
cd frontend && npx tsc --noEmit
|
|
|
|
# Worker secrets
|
|
wrangler secret put OPENAI_API_KEY
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
| Endpoint | Description |
|
|
|----------|-------------|
|
|
| `GET /api/rooms/:roomId/websocket` | WebSocket upgrade for chat |
|
|
| `GET /api/rooms/:roomId/users` | List users in room |
|
|
| `GET /api/health` | Health check |
|
|
|
|
## WebSocket Message Types
|
|
|
|
**Client → Server**: `{ type: "message", content: string }` or `{ type: "rename", name: string }`
|
|
|
|
**Server → Client**: `message`, `join`, `leave`, `userList`, `history`, `error`
|
|
|
|
## Configuration Alignment
|
|
|
|
Frontend `config.ts` and backend `validation.ts` must stay in sync:
|
|
- `maxMessageLength`: 2000 characters
|
|
- `maxUserNameLength`: 50 characters
|
|
|
|
## Security Considerations
|
|
|
|
- XSS prevention: `sanitize.ts` uses DOMPurify + custom URL validation (`isUrlSafe()`) to block encoded `javascript:` attacks
|
|
- API key redaction: `sanitizeErrorForLogging()` in AIManager.ts strips credentials from error logs
|
|
- CORS: Strict origin allowlist in `index.ts` (includes Pages preview deployments)
|
|
- Input validation: All WebSocket messages validated with Zod schemas before processing
|
|
|
|
## External Services
|
|
|
|
- **OpenAI API**: Chat completions with function calling (weather, docs, hosting info, silence user)
|
|
- **Open-Meteo API**: Weather data (no API key required)
|
|
- **Context7 API**: Documentation lookup for technical questions
|