面向高校实验室 / 教学团队的 Agent 驱动轻量项目管理平台。看板协作、AI 项目助手、资源占用登记、时间线甘特,并支持 Claude Code 等外部程序经 Personal API Token 直接写入。
- 团队与角色:创建/加入团队,admin / teacher / student 三级权限
- 项目看板:里程碑 + 拖拽看板 + 任务增强(描述/完成情况/起止日/后置任务)+ 标签筛选与四维度分组(状态/指派人/优先级/里程碑,各分组下拖拽皆生效)
- 跨项目总览:
/projects聚合我所在全部团队的项目与任务进度 - AI 项目助手:对话式拆解任务,两段式确认后落库(读工具 + 四写兵器草案)
- 资源占用登记:团队共享资源(服务器/算力等)的占用登记与时长汇总,纯登记无审批
- Personal API Token:生成/撤销令牌,供外部程序以本人身份写入
- Agent 写入 API:Claude Code 等携令牌直接添加任务、填写完成情况、登记资源占用
- 时间线甘特:项目内任务按里程碑分组的甘特视图,逾期标红、今日竖线
Next.js 16 (App Router, Turbopack) · React 19 · TypeScript · PostgreSQL 16 + Drizzle ORM · Auth.js v5 (JWT) · Vercel AI SDK v5 (DeepSeek / openai-compatible) · Tailwind CSS v4 · Vitest
docker compose up -d # 启动 Postgres(首次自动建 dev 与 test 两库)
cp .env.example .env # 填入 AUTH_SECRET(openssl rand -base64 32)与 DATABASE_URL
npm install
npm run db:push # 推送 schema 到开发库
npm run db:push:test # 推送 schema 到测试库
npm run dev
scripts/init-test-db.sql仅在 Postgres 数据卷首次初始化时执行。若改过 init 脚本或测试库缺失,需docker compose down -v重建数据卷再up(会清空本地开发数据)。 本机若用 colima 提供 Docker:先colima start。
测试:npm test
docker-compose.prod.yml 编排 db + migrate(自动建表)+ app 三服务,同网络起,无需手动推 schema。
cp .env.example .env
# 填齐生产密钥:
# AUTH_SECRET=$(openssl rand -base64 32)
# POSTGRES_PASSWORD=<强密码> # db 密码,compose 变量插值单一来源
# AGILECAMPUS_URL=https://<对外域名> # 飞书 OAuth 回调据此拼跳转
# DEEPSEEK_API_KEY / FEISHU_APP_ID / FEISHU_APP_SECRET=<真值>
# FEISHU_REDIRECT_URI=https://<对外域名>/api/auth/feishu/callback
# CRON_SECRET=$(openssl rand -hex 32)
nano .env
docker compose -f docker-compose.prod.yml up -d --buildmigrate 服务待 db healthcheck 通过后跑 db:push 建表,成功退出后 app 方启动。app 内 DATABASE_URL 由 compose 指向服务名 db,覆盖 .env 的 localhost 值(无需改 .env)。
定时提醒(临期/逾期私信)须由宿主 crontab 每日打一次 cron 端点:
( crontab -l 2>/dev/null; \
echo '0 9 * * * curl -fsS -X POST http://localhost:3000/api/cron/reminders -H "Authorization: Bearer <CRON_SECRET>" >/dev/null 2>&1' \
) | crontab -NAS 部署:本机
rsync -az --delete --exclude node_modules --exclude .next --exclude .git ./ root@<nas>:/volume1/docker/agilecampus/,再 ssh 上去于该目录执行上述up命令。 飞书应用后台须将FEISHU_REDIRECT_URI加入重定向白名单,绑定方能成。
| 路由 | 说明 |
|---|---|
/teams |
我的团队(创建/加入) |
/teams/[teamId]/members |
成员管理(admin 改角色) |
/teams/[teamId]/projects |
项目列表(admin 创建) |
/teams/[teamId]/resources |
资源占用登记 + 时长统计 |
/teams/[teamId]/labels |
团队标签管理(admin 增删改,成员只读) |
/projects |
所有项目总览(跨团队聚合 + 任务统计) |
/projects/[projectId] |
项目详情:里程碑 + 看板 + 任务 + AI 助手 |
/projects/[projectId]/timeline |
项目时间线甘特 |
/settings/tokens |
个人访问令牌(生成/撤销) |
供 Claude Code 等浏览器之外的程序,以用户身份写入 AgileCampus。
所有 /api/agent/* 端点用 Personal API Token 认证(区别于浏览器 session):
Authorization: Bearer <token>
在网页「设置 → 个人访问令牌」生成,明文只显示一次;库中仅存 sha256 hash。令牌权限等同本人:只能操作有权限的团队/项目,越权返回 403。约定两个环境变量:
AGILECAMPUS_URL— 站点地址,如http://localhost:3000AGILECAMPUS_TOKEN— 令牌明文
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
projectId |
uuid | 是 | 目标项目 |
title |
string | 是 | 任务标题 |
description |
string | 否 | 描述 |
assigneeId |
uuid | 否 | 负责人(须为团队成员) |
startDate |
string | 否 | 起始日 YYYY-MM-DD(供时间线排期) |
dueDate |
string | 否 | 截止日 YYYY-MM-DD |
milestoneId |
uuid | 否 | 里程碑(须属该项目) |
priority |
low|medium|high |
否 | 默认 medium |
curl -X POST "$AGILECAMPUS_URL/api/agent/tasks" \
-H "Authorization: Bearer $AGILECAMPUS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"projectId":"<uuid>","title":"撰写调研问卷","startDate":"2026-07-01","dueDate":"2026-07-08","priority":"high"}'
# → { "id": "...", "title": "撰写调研问卷", "status": "todo" }将任务标记为 done 并附完成说明。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
taskId |
uuid | 是 | 目标任务 |
completionNote |
string | 是 | 完成说明 |
curl -X POST "$AGILECAMPUS_URL/api/agent/tasks/complete" \
-H "Authorization: Bearer $AGILECAMPUS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"taskId":"<uuid>","completionNote":"已跑通全部演武"}'
# → { "id": "...", "status": "done" }| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
teamId |
uuid | 是 | 目标团队 |
resourceName |
string | 是 | 资源名,如 GPU-01 |
purpose |
string | 否 | 用途 |
startTime |
ISO 8601 | 是 | 开始时间,如 2026-07-22T14:00:00Z |
endTime |
ISO 8601 | 否 | 结束时间;省略 = 占用中 |
curl -X POST "$AGILECAMPUS_URL/api/agent/resource-usage" \
-H "Authorization: Bearer $AGILECAMPUS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"teamId":"<uuid>","resourceName":"GPU-01","purpose":"训练模型","startTime":"2026-07-22T14:00:00Z"}'
# → { "id": "...", "resourceName": "GPU-01", "active": true }| 状态 | 含义 |
|---|---|
200 |
成功,返回创建/更新后的精简对象(含 id) |
400 |
请求格式无效(缺字段、类型错、时间非法) |
401 |
令牌缺失、畸形、伪造或已撤销 |
403 |
越权——令牌主人对目标项目/团队无权限 |
500 |
服务器错误,可重试 |
- 令牌库中只存 sha256 hash,明文只在生成时返回一次,泄露即在设置页撤销。
- 外部写入一律不被信任:
token → userId → lib 权限校验,越权由业务层拒绝。
项目内置 .claude/skills/agilecampus/ skill,封装上述端点调用——配置好 AGILECAMPUS_TOKEN 与 AGILECAMPUS_URL 后,即可在 Claude Code 里用自然语言「给项目 X 加任务 Y」「把任务 Z 标记完成」「登记我占用了 GPU-01」。完整契约另见 docs/agent-api.md。
- 设计与作战图:
docs/superpowers/ - Agent 写入 API:
docs/agent-api.md - 技术债备案:
docs/BACKLOG.md