# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands - `npm run dev` — Start local dev server (Wrangler) - `npm run deploy` — Deploy to Cloudflare Workers (`wrangler deploy`) - `npm test` — Run tests with Vitest (Cloudflare Workers pool) - `npm run cf-typegen` — Regenerate TypeScript types from Wrangler config ## Architecture Telegram bot for the CosMoe photography platform (`https://cos.cx/api/v1`), deployed as a Cloudflare Worker with a 1-minute cron trigger. ### Entry points (`src/index.ts`) - **fetch handler** — Receives Telegram webhooks, creates a grammy `Bot`, registers commands via `setupCommands()`, delegates to `webhookCallback`. - **scheduled handler** — Runs every minute via cron. Checks for new events and pushes notifications to all registered users. ### Command routing (`src/command/index.ts`) `setupCommands()` wires grammy commands, conversation plugins, regex-based `hears` handlers, and `callbackQuery` handlers. The `conversations` plugin uses KV-backed storage for multi-step flows (login). Bot commands: `start`, `login`, `events`, `history`, `logout` Pattern handlers: `/event_{id}`, `/book_{eventId}_{slotIndex}`, `/cancel_{bookingId}` Callback queries: cancel confirmation, coupon selection ### Handlers (`src/command/handlers/`) Each is a standalone async function. Most follow the pattern: authenticate user from KV → call CosMoe API → format and reply. ### API client (`src/client/cosmoe.ts`) `CosmoeClient` wraps the CosMoe REST API. Auth uses `user_id` + `token` passed as URL params (GET) or FormData (POST). Credentials are stored per-user in `COSMOE_CREDENTIALS` KV keyed by Telegram user ID. ### Scheduler (`src/scheduler/index.ts`) Tracks notified event IDs in `COSMOE_STORAGE` KV to avoid duplicate notifications. Iterates all credential keys to broadcast to every registered user. ### KV namespaces - `COSMOE_CREDENTIALS` — Per-user auth tokens (keyed by Telegram user ID) - `COSMOE_STORAGE` — Conversation state and scheduler data ## Key conventions - All user-facing text is Chinese. - Beijing timezone (UTC+8) is hardcoded for date comparisons in handlers and scheduler. - Formatting: Prettier with tabs, single quotes, 140 char width. - TypeScript: ES2024, strict mode, Bundler module resolution. - The `Env` interface is defined separately in `src/command/index.ts`; handlers receive `env` as an untyped `any` parameter. - Tests use `@cloudflare/vitest-pool-workers` for the Workers runtime.