# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What This Project Does KOC LOOP is a content distribution & data collection platform for KOC (Key Opinion Consumer) operations teams. It runs on **vinext** (Vite-based Next.js 16 on Cloudflare Workers + Pages) with Cloudflare D1 (SQLite) and R2 storage. The platform manages: task creation from Feishu (飞书) spreadsheets, content distribution to KOC partners, publishing to Xiaohongshu (小红书), and automated data collection (likes/comments/collects) via MCP-based metrics scraping. ## Two Applications ### 1. Admin App (`app/`) — Main dashboard - Server-rendered admin UI at root (`/`), protected by ChatGPT Sign-In + admin email check - Heavy client-side SPA in `app/admin-app.tsx` (a single ~59KB component with all dashboard state/views) - API routes under `app/api/` for CRUD, Feishu import, data collection, image upload ### 2. KOC Portal (`koc-portal/`) — External task portal - Independent Next.js app (separate `package.json`) for external KOC collaborators - KOCs can claim tasks, view assigned content, and submit publish URLs/screenshots - Does NOT connect directly to the database — uses the admin app's API ## Tech Stack - **Framework**: Next.js 16 + React 19 + TypeScript - **Build/Runtime**: vinext 0.0.50 (Vite 8 plugin → Cloudflare Workers/Pages) - **Database**: Cloudflare D1 (SQLite via Drizzle ORM 0.45) - **Storage**: Cloudflare R2 for uploads/screenshots - **Styling**: Tailwind CSS 4 - **Cron**: Cloudflare Workers cron (daily 02:00 UTC / 10:00 CST) ## Database Schema (7 tables in `db/schema.ts`) | Table | Purpose | |-------|---------| | `partners` | KOC partners/groups (name, owner, stats) | | `tasks` | Campaign tasks (brand, quantity, due date, Feishu source) | | `contents` | Content items (title, body, images, linked to task) | | `accounts` | Xiaohongshu accounts scraped from publish links | | `claims` | Partner claims on task content | | `delegation_bundles` | Delegation bundles with share tokens | | `distributions` | Content-to-partner assignments (publish URL, metrics, collection status) | | `collection_runs` | Scheduled metrics collection run log | Schema is maintained both via Drizzle (`db/schema.ts`) and imperative migrations in `lib/mvp-db.ts:ensureSchema()`. The imperative path is the source of truth for production — Drizzle migrations are optional. ## Key Libraries - `lib/mvp-db.ts` — Raw D1 helpers, schema bootstrapping, seed data, `getDashboardData()` - `lib/collection-service.ts` — Scheduled metrics collection orchestration - `lib/mcp-collection-client.ts` — MCP-based client for scraping Xiaohongshu public metrics - `lib/feishu-client.ts` — Feishu API client (spreadsheet/wiki/doc reading) - `lib/account-enrichment-service.ts` — Backfill account profiles from Xiaohongshu - `lib/admin-auth.ts` — Admin email/token authentication - `lib/partner-utils.ts` / `lib/publish-url.ts` — URL extraction helpers - `lib/date-utils.ts` — Date formatting (Shanghai timezone) ## Worker (`worker/index.ts`) The Cloudflare Worker entry point handles: 1. `fetch` — Image optimization proxy at `/_vinext/image`, delegates everything else to vinext app router 2. `scheduled` — Daily cron: ensures DB schema, runs scheduled collections, backfills account profiles > Note: 在私有化部署(Node + MySQL)里实际调度走 `lib/scheduler.ts` 的 `node-cron`,每天 09:00 Asia/Shanghai 跑同一套 `runDailyJob`(采集 + 账号资料补全 + 企业微信催办)。Cloudflare Worker 入口仅用于原线上版本。 ## API Routes (`app/api/`) - `action/route.ts` — Central admin action endpoint: create task from Feishu, dashboard data, collect metrics, batch operations, account backfill, 企业微信测试 / 状态查询 / 绑定外部联系人 / 客户群同步与企业群发(半自动,群主确认后送达) - `partner/route.ts` — Partner-facing API (claim, delegation, distribution) - `bootstrap/route.ts` — Seed database with demo data - `upload/route.ts` — Generic file upload to R2 - `partner-upload/route.ts` — Partner screenshot upload (CORS-enabled) - `partner-image/route.ts` — Partner image serving (CORS-enabled) - `content-image-upload/route.ts` — Content image upload - `creator-screenshot/route.ts` — Creator screenshot upload - `resources-import/route.ts` — 批量导入 KOC 账号资源(Excel/CSV) - `resources-insert/route.ts` — 单条新增 KOC 账号资源(表单) ## Environment Variables (`.dev.vars`) ``` KOC_PORTAL_URL — URL of the koc-portal app ADMIN_ALLOWED_EMAIL — ChatGPT email allowed for admin access ADMIN_INTERNAL_TOKEN — Shared secret for API-to-API auth AI_TOOL_CENTER_MCP_URL — MCP endpoint for XHS data collection AI_TOOL_CENTER_MCP_KEY — MCP API key FEISHU_APP_ID — Feishu custom app credentials FEISHU_APP_SECRET — Feishu app secret WECOM_CORP_ID — 企业微信企业 ID(自建应用消息推送用,可选) WECOM_AGENT_ID — 企业微信自建应用 AgentId(可选) WECOM_SECRET — 企业微信自建应用 Secret(可选) WECOM_ROBOT_WEBHOOK — 企业微信群机器人 webhook(当日催办汇总,可选) WECOM_NOTIFY_DUE_DAYS — 临期阈值,默认 3,取值 1–30(可选) WECOM_NOTIFY_ENABLED — 企业微信通知总开关,默认 true(可选) ``` ## Commands ```bash # Admin app (root of repo) npm run dev # Start local dev server npm run build # Build for production npm test # Build + run integration tests npm run lint # ESLint check npm run db:generate # Generate Drizzle SQL migration # KOC Portal (koc-portal/) cd koc-portal && npm run dev -- --port 3000 # Start on port 3000 cd koc-portal && npm run build cd koc-portal && npm test # Tests use `node --test` (Node built-in test runner), live in tests/ node --test tests/date-utils.test.mjs # Run a single test ``` ## Build System - `vinext` replaces the Next.js build pipeline with Vite - `@cloudflare/vite-plugin` provides D1/R2/cron local bindings - Vite config at root resolves bindings from `.openai/hosting.json` - Custom `build/sites-vite-plugin.ts` copies `.openai/` and `drizzle/` into `dist/` for deployment - The `koc-portal/` subdirectory has its own identical build setup (separate `vite.config.ts`, `build/sites-vite-plugin.ts`) # This is NOT the Next.js you know This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices. This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.