feat: 任务发布到企微客户群(企业群发)与资源库单条新增

- 任务中心新增「发布到企微群」:同步客户群清单(wecom_group_chats)、
  按群主分组创建企业群发任务(add_msg_template)、发送记录落库
  wecom_group_pushes,迁移 mysql/0009;lib/wecom-client.ts 补
  listCustomerGroupChats/createGroupMsgTemplate
- KOC 资源库支持单条新增:app/api/resources-insert + lib/resource-write,
  拆出资源写入公共逻辑供导入复用;0008 补合作方外部联系人字段
- 环境变量示例补企微凭证与 SEED_DEMO_DATA;next.config 增加
  allowedDevOrigins;CLAUDE.md 补充项目说明
- .gitignore 排除 .codegraph/ 与 .ipynb_checkpoints/
This commit is contained in:
ABAPPLO
2026-08-20 15:16:18 +08:00
parent 8f7ea0558d
commit 9697b5890d
22 changed files with 3695 additions and 449 deletions

132
CLAUDE.md Normal file
View File

@@ -0,0 +1,132 @@
# 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取值 130可选
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`)
<!-- BEGIN:nextjs-agent-rules -->
# 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.
<!-- END:nextjs-agent-rules -->