我的项目 API

OctoHz 我的项目 API

接口一览

MethodRoute说明
GET/api/my/projects列表(摘要)
POST/api/my/projects新建
GET/api/my/projects/:id获取索引(轻量);?full=true 获取完整数据
PATCH/api/my/projects/:id部分更新
DELETE/api/my/projects/:id删除
GET/api/my/projects/:id/definition获取 definition 分段
GET/api/my/projects/:id/status获取 status 分段
GET/api/my/projects/:id/ops获取 ops 分段
GET/api/my/projects/:id/decisions获取 decisions 分段
GET/api/my/projects/:id/pitfalls获取 pitfalls 分段
GET/api/my/projects/:id/design获取 design 分段
GET/api/my/projects/:id/data-models获取 data_models 分段
GET/api/my/projects/:id/snapshots历史版本列表
GET/api/my/projects/:id/snapshots/:sid某个历史版本完整内容
POST/api/my/projects/:id/snapshots/:sid恢复至该版本(恢复前自动备份当前)

重要: project ID 只能放 URL,不能放 body。


索引结构

GET /api/my/projects/:id 默认返回轻量索引,每个分段只给摘要和 URL,不含完整数据

{
  "id": 1,
  "name": "项目名",
  "stage": "production",
  "oneliner": "...",
  "updatedAt": "...",
  "sections": {
    "definition":  { "summary": "tech_stack 摘要 | conventions 列表", "url": "/api/my/projects/1/definition" },
    "status":      { "summary": "completed: N · in_progress: N · pending: N", "url": "/api/my/projects/1/status" },
    "ops":         { "summary": "repo · servers(N) · databases(N) · ...", "url": "/api/my/projects/1/ops" },
    "decisions":   { "summary": "N条 — D001 标题 · D002 标题", "url": "/api/my/projects/1/decisions" },
    "pitfalls":    { "summary": "N条 — P001[高] 标题 · ...", "url": "/api/my/projects/1/pitfalls" },
    "design":      { "summary": "colors · buttons(N) · card", "url": "/api/my/projects/1/design" },
    "data_models": { "summary": "N个 — Model1 · Model2", "url": "/api/my/projects/1/data-models" }
  }
}

推荐工作流:先读索引 → 根据任务判断需要哪几节 → 只请求那几个 URL

任务类型建议拉取
修 bug / 接手pitfalls + ops
新功能开发definition + data_models + ops
了解当前进度status
UI 相关design + definition
全量获取?full=true

顶层结构

{
  "id": 1,
  "name": "项目名称",
  "definition": {},
  "decisions": [],
  "pitfalls": [],
  "status": {},
  "ops": {},
  "design": {},
  "dataModels": []
}

POST 支持字段: namedefinitiondecisionspitfallsstatusops

PATCH 额外支持: designdata_models(POST 不接受这两个字段)


⚠️ PATCH 行为说明

顶层字段是局部更新——只发哪个字段就更新哪个字段,其余不变。

但嵌套对象(opsdefinitionstatus)是整体替换,不做深度合并:

# ❌ 危险:只发 ops.nodes,ops 的其余字段(servers、deploy_flow 等)会丢失
curl -s -X PATCH https://octohz.com/api/my/projects/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ops": {"nodes": [...]}}'

# ✅ 正确:先 GET 完整数据,本地合并后整体发
curl -s "https://octohz.com/api/my/projects/1?full=true" \
  -H "Authorization: Bearer $TOKEN" > /tmp/proj.json
# 在 /tmp/proj.json 中修改 ops.nodes,然后整体发回
curl -s -X PATCH https://octohz.com/api/my/projects/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"ops\": $(jq '.ops' /tmp/proj.json)}"

例外decisionspitfalls 是数组,按 id upsert,不受此影响——直接发新条目即可,不会覆盖历史。

可选字段 _note(最多 200 字):填写本次更新的备注,会记录在历史版本里,方便日后回溯。

{ "status": { ... }, "_note": "修复登录 bug 后同步状态" }

definition

{
  "oneliner": "一句话描述",
  "stage": "production",
  "tech_stack": [
    {
      "tech": "Next.js",
      "layer": "frontend",
      "version": "16.2.1",
      "framework": "App Router"
    }
  ],
  "conventions": {
    "styling": "Tailwind v4 utility classes",
    "deploy": "改完后端先 git push,再 SSH 执行部署脚本"
  },
  "estimated_completion": "2026-06"
}
  • oneliner:注意不是 one_liner
  • stage 枚举:development / production / maintenance / running / archived
  • tech_stack 每项:tech(必填)、layer(必填)、version(选填)、framework(选填)、note(选填)、port(选填)
  • layer 常用值:frontend / backend / database / deployment / runtime / plugin / service / proxy / control_plane / vpn_client
  • conventions:key-value 对象,key 自定义,value 为字符串;整体是对象不是数组
  • estimated_completion:选填,"YYYY-MM"null

decisions

[
  {
    "id": "D001",
    "date": "2026-04",
    "title": "决策标题",
    "impact": "影响的文件或模块",
    "status": "active",
    "context": "做这个决策的背景",
    "decision": "具体做了什么决定",
    "rationale": "(选填)更详细的理由"
  }
]
  • id 格式:D001D002 递增
  • date:选填,"YYYY-MM""YYYY-MM-DD"
  • status 常用值:active / deprecated / superseded(服务端不校验枚举,写语义清晰的字符串即可)
  • contextdecision 分开写,不要合并
  • PATCH 行为:按 id upsert——发送的条目与现有数据按 id 合并,字段值为 null 时该字段被删除,不存在的 id 则新增

pitfalls

[
  {
    "id": "P001",
    "date": "2026-04-24",
    "title": "坑的标题",
    "status": "mitigated",
    "severity": "high",
    "condition": "在什么情况下触发",
    "consequence": "触发后会发生什么",
    "solution": "怎么解决或规避",
    "mitigation": "(选填)已采取的缓解措施",
    "description": "(选填)更详细说明"
  }
]
  • id 格式:P001P002 递增
  • date:选填,"YYYY-MM-DD"
  • status 枚举:resolved / mitigated / active / identified
  • severity 枚举:high / medium / low
  • conditionconsequencesolution 是必填核心三件套
  • mitigationdescription:选填
  • PATCH 行为:按 id upsert——同 decisions,按 id 合并,null 值删字段

status

{
  "completed": ["已完成项"],
  "in_progress": ["进行中"],
  "pending": ["待办"],
  "known_issues": ["已知轻量问题"]
}

所有字段都是字符串数组,空时写 []不能写 null


ops

⚠️ PATCH 时整体替换,修改前必须先 GET ?full=true 拿完整 ops,合并后再发。

{
  "repo": "https://github.com/xxx/yyy",
  "servers": [
    {
      "address": "67.230.160.74 / octohz.com",
      "purpose": "生产环境",
      "services": ["Next.js 16", "PostgreSQL"]
    }
  ],
  "env_vars": [
    {
      "key": "DATABASE_URL",
      "hint": "postgresql://user:<pw>@host:5432/db,密码见服务器 .env"
    }
  ],
  "cron_jobs": [],
  "databases": [
    {
      "name": "mydb",
      "type": "PostgreSQL",
      "address": "172.18.0.3:5432",
      "notes": "容器间通信用内网地址"
    }
  ],
  "local_dev": ["Node.js 20+", "npm install", "npm run dev"],
  "onboarding": {
    "summary": "项目一句话介绍",
    "key_files": ["path/to/file — 说明"],
    "first_steps": ["1. 第一步", "2. 第二步"],
    "forbidden_zones": ["禁止做的事"]
  },
  "deploy_flow": ["Step 1: ...", "Step 2: ..."],
  "third_party": [
    {"name": "Resend", "status": "normal", "purpose": "邮件发送"}
  ],
  "dir_structure": {
    "root": "/opt/project",
    "notes": "补充说明",
    "key_paths": [
      {"path": "src/app", "desc": "Next.js 路由"}
    ]
  }
}
  • env_vars 每项用 hint 字段(不是 note / value / scope),不写明文密码
  • databases 本地文件型存储(JSON / safetensors / SQLite 等)也用同一 schema:address 填文件路径(如 ~/.omlx/stats.json),typeJSON file / safetensors 等,notes 补充说明;不要自创 pathnote 字段
  • onboarding对象,不是字符串
  • servers[].address 多个地址用 / 分隔
  • 不涉及的字段(cron_jobsdatabases 等)填 [],不要省略

design(选填,仅 PATCH)

{
  "notes": "整体风格说明",
  "colors": {
    "primary": "#e64831",
    "bg": {"page": "#f4f4f4", "card": "#ffffff"}
  },
  "buttons": [
    {"name": "主操作按钮", "style": "CSS 字符串", "usage": "使用场景"}
  ],
  "card": "卡片的 Tailwind class 字符串"
}

无 UI 的项目留 {}。POST 新建时不支持此字段,需建好后再 PATCH。


dataModels(选填,仅 PATCH)

PATCH body 中字段名为 data_models(snake_case),服务端存储为 dataModels

[
  {
    "name": "User",
    "table": "users",
    "desc": "用户账号",
    "key_fields": ["id", "email", "password"]
  }
]

无数据库的项目留 []。POST 新建时不支持此字段。


历史版本

每次 PATCH 会自动保存当前状态为快照,每个项目最多保留 50 个版本,超出时自动删除最旧的。

# 列表(只含 id、savedAt、note,不含完整数据)
curl -s https://octohz.com/api/my/projects/1/snapshots \
  -H "Authorization: Bearer $TOKEN"
# → [{ "id": 12, "savedAt": "2026-04-27T10:00:00Z", "note": "修复登录 bug" }, ...]

# 查看某个版本完整内容
curl -s https://octohz.com/api/my/projects/1/snapshots/12 \
  -H "Authorization: Bearer $TOKEN"

# 恢复至该版本(无需 body;恢复前自动备份当前状态)
curl -s -X POST https://octohz.com/api/my/projects/1/snapshots/12 \
  -H "Authorization: Bearer $TOKEN"

常见错误速查

错误写法正确写法
one_lineroneliner
conventions: ["字符串"]conventions: {"key": "value"}
env_vars[].noteenv_vars[].hint
databases[].pathdatabases[].address(本地文件路径也填这里)
databases[].notedatabases[].notes(注意末尾有 s)
onboarding: "字符串"onboarding: {summary, key_files, ...}
tech_stack: ["Next.js"]tech_stack: [{tech, layer}]
空字段写 null空字段写 []{}
body 里传 idID 只放 URL
PATCH body 用 dataModelsPATCH body 用 data_models
decisions/pitfalls 全量覆盖id upsert,null 值删字段
PATCH ops 只发部分字段先 GET ?full=true,合并后整体发
curl 示例漏写 Authorization 头所有请求加 -H "Authorization: Bearer $TOKEN"
GET 时写 curl -s GET urlcurl -s url(GET 会被当成第二个 URL)
pitfalls[].severity 用中文("高"/"中"/"低")必须用英文枚举:"high" / "medium" / "low"

分类:Agent 使用教程 链接https://octohz.com/docs?doc=68