# KOC LOOP

KOC 内容分发与数据回收闭环。`main` 分支运行于标准 Next.js Node.js、MySQL 8、Nginx 和本地持久化文件存储。

## Prerequisites

- Node.js `>=22.13.0`
- MySQL `>=8.0`（本地完整运行）

## Quick Start

```bash
npm install
npm run db:migrate
npm run dev
npm run build
```

复制 `.env.self-hosted.example` 为 `.env.self-hosted`，设置 `DATABASE_URL` 或 `MYSQL_*` 连接信息。飞书动态导入需要：

- `FEISHU_APP_ID`
- `FEISHU_APP_SECRET`

飞书自建应用需开通电子表格读取、知识库节点读取和云文档素材下载权限，
并将应用添加到目标知识库或电子表格的文档应用中。

后台登录首次启动还需要配置：

- `SUPER_ADMIN_USERNAME`：唯一的超级管理员登录账号
- `SUPER_ADMIN_PASSWORD`：超级管理员初始密码，至少 8 位
- `ADMIN_INTERNAL_TOKEN`：自动采集等内部任务使用的服务密钥
- `KOC_MCP_API_KEY`：Agent 调用 KOC LOOP MCP 使用的独立 Bearer 密钥

系统首次登录时创建唯一的超级管理员。后续管理员和普通用户均由“用户管理”页面创建，普通用户不能访问 KOC 资源库。

完整私有化部署请看 [KOC LOOP 私有化部署指南](docs/KOC%20LOOP%20私有化部署指南.md)。Docker Compose 会启动 Nginx、KOC 服务和 MySQL；外部领取页与后台使用同一域名下的 `/koc/` 路径。

## 后台账号与角色

- 超级管理员：唯一系统管理员，可管理管理员和普通用户。
- 管理员：可访问全部业务模块，可创建和重置普通用户账号。
- 普通用户：可使用工作台、任务、内容分发和数据回收，不可查看或导出 KOC 资源库。

后台不提供注册、找回密码和普通用户个人改密。密码重置统一由管理员在后台完成。

## KOC 资源导入

超级管理员和管理员可在“KOC资源”页面下载标准 Excel 模板，批量导入已有资源。模板只需填写账号主页；账号名称、账号 ID、IP 属地、粉丝数、性别、简介、标签和合作来源均可选填。多个标签使用逗号分隔，每个账号最多 5 个标签。

- 单次最多导入 10,000 个账号，支持 `.xlsx` 和 `.csv`，文件不超过 20MB。
- 当前自动解析支持小红书账号主页；上传后先展示新增、更新和异常数据。异常行会跳过，其余有效账号可以正常导入。
- 按“平台 + 账号主页”去重；解析出相同小红书号时也会更新已有账号。
- 重复账号更新公开资料和合作来源，不产生两份资源。
- 大批量导入会先写入资源库，再在后台逐步补全缺失的公开资料。
- KOC 使用手机号或微信号领取任务后，系统会把该值写入“当前联系人”；原“合作来源”继续保留渠道信息。
- 导入的标签、当前联系人和合作来源会进入资源搜索或导出结果。

## KOC 批量回填 Excel

KOC 领取端支持导出和上传批量回填表。视频任务只生成“序号、标题、笔记内容、视频、发布链接、笔记截图、数据分析截图”列，不生成“图片”列。视频链接通过当前公网域名生成，下载接口返回可播放的 `.mp4` 附件。

反向代理部署必须正确传递 `Host`、`X-Forwarded-Host` 和 `X-Forwarded-Proto`，并把 `APP_ORIGIN` 配置为实际公网地址；不要填写 `localhost` 或容器内部地址。

## Agent MCP

生产地址：

```text
https://你的-KOC-LOOP-后台域名/api/mcp
```

MCP 使用独立的 `KOC_MCP_API_KEY` 鉴权，请通过请求头发送：

```text
Authorization: Bearer <KOC_MCP_API_KEY>
```

创建分发任务使用 `create_distribution_task`，参数如下：

- `feishu_url`：飞书 Wiki 或电子表格链接；多工作表时必须带目标 `sheet` 参数
- `task_name`：任务名称
- `due_date`：北京时间截止日期，格式 `YYYY-MM-DD`
- `brand_project`：可选，品牌或项目名称；未提供时记录为“未设置项目”

成功后返回任务 ID、笔记数量和 KOC 领取链接。完全相同的任务参数重复调用时，返回已经存在的任务，避免 Agent 重试产生重复任务。

同时开放以下运营工具：

- 任务：`task_list`、`task_get`
- 数据回收：`recovery_list`、`recovery_export`
- 数据采集：`collection_plan_set`、`collection_run_due`、`collection_collect_now`、`collection_retry_failed`
- KOC 资源：`resource_search`、`resource_get`、`resource_backfill_profile`、`resource_export`

`recovery_export` 和 `resource_export` 返回 15 分钟有效的安全下载链接。链接不包含 MCP 密钥；任务数据导出会继续把笔记原图、发布截图和创作者截图直接嵌入 Excel。

在支持远程 MCP 的 Agent 中添加：

```json
{
  "mcpServers": {
    "koc-loop": {
      "url": "https://你的-KOC-LOOP-后台域名/api/mcp",
      "headers": {
        "Authorization": "Bearer ${KOC_LOOP_MCP_API_KEY}"
      }
    }
  }
}
```

使用示例：

```text
用这个飞书表格创建发布任务：<飞书链接>。
任务名“8月骑手招募”，截止时间 2026-08-20。
创建后把 KOC 领取链接发给我。
```

密钥不要写入仓库、对话内容或 URL 查询参数，生产环境通过站点密钥管理配置。

## Useful Commands

- `npm run dev`: start local development
- `npm run build`: 验证标准 Next.js Node.js 生产构建
- `npm test`: 构建并执行业务与私有化架构测试
- `npm run db:generate`: generate Drizzle migrations after schema changes
- `npm run db:migrate`: 应用 MySQL 增量迁移
- `npm run db:check`: 检查 MySQL 连接
- `npm run db:import-json -- <file>`: 导入 D1 JSON 数据
- `npm run storage:import -- <dir>`: 导入 R2 对象目录

## Learn More

- [Next.js Self-Hosting](https://nextjs.org/docs/app/guides/self-hosting)
- [Drizzle MySQL Guide](https://orm.drizzle.team/docs/get-started-mysql)
