Files
chat-app/CLAUDE.md
kappa 554c578345 Initial commit: Anvil Lounge chat application
- 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>
2026-01-19 10:17:27 +09:00

3.5 KiB

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

# 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