draftgo-cli 3.0.0 → 3.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +67 -17
  2. package/package.json +13 -8
  3. package/resources/skill/SKILL.md +118 -22
  4. package/resources/skill/core/architecture.md +4 -24
  5. package/resources/skill/core/modules.md +14 -4
  6. package/resources/skill/init/SKILL.md +3 -4
  7. package/resources/skill/practices/anti-patterns.md +14 -4
  8. package/resources/skill/practices/best-practices.md +25 -6
  9. package/resources/skill/practices/dev-declaration.md +23 -3
  10. package/resources/skill/pull/SKILL.md +9 -1
  11. package/resources/skill/push/SKILL.md +103 -68
  12. package/resources/skill/quickref/api-endpoints.md +63 -41
  13. package/resources/skill/quickref/api.json +5084 -4975
  14. package/resources/skill/quickref/app-api.md +4 -14
  15. package/resources/skill/rules/dev-workflow.md +154 -57
  16. package/resources/skill/rules/frontend.md +569 -21
  17. package/resources/skill/rules/parallel.md +10 -10
  18. package/resources/skill/scripts/__pycache__/draftgo_pull.cpython-312.pyc +0 -0
  19. package/resources/skill/scripts/__pycache__/draftgo_push.cpython-312.pyc +0 -0
  20. package/resources/skill/scripts/draftgo_delete.py +0 -2
  21. package/resources/skill/scripts/draftgo_init.py +15 -3
  22. package/resources/skill/scripts/draftgo_pull.py +154 -87
  23. package/resources/skill/scripts/draftgo_push.py +363 -174
  24. package/resources/skill/specs/custom-services.md +199 -0
  25. package/resources/skill/specs/data.md +195 -5
  26. package/resources/skill/specs/db-relations.md +227 -0
  27. package/resources/skill/specs/runtime.md +30 -0
  28. package/resources/skill/specs/security.md +3 -3
  29. package/resources/skill/specs/ui-protocol.md +79 -48
  30. package/resources/skill/story/SKILL.md +2 -7
  31. package/src/cli.js +9 -0
  32. package/src/commands/api.js +59 -0
  33. package/src/commands/autoPush.js +41 -0
  34. package/src/commands/check.js +27 -17
  35. package/src/commands/delete.js +6 -4
  36. package/src/commands/deploy.js +31 -0
  37. package/src/commands/doctor.js +1 -1
  38. package/src/commands/help.js +27 -9
  39. package/src/commands/init.js +17 -2
  40. package/src/commands/map.js +18 -7
  41. package/src/commands/new.js +20 -17
  42. package/src/commands/sync.js +10 -3
  43. package/src/commands/update.js +15 -56
  44. package/src/commands/upgrade.js +52 -0
  45. package/src/commands/verifyUi.js +199 -0
  46. package/src/index.js +12 -1
  47. package/src/localdev/compose.js +8 -1
  48. package/src/platforms.js +3 -3
  49. package/src/projectConfig.js +11 -1
  50. package/src/projectMap.js +274 -39
  51. package/src/skill.js +113 -29
  52. package/src/updateCheck.js +37 -5
  53. package/resources/skill/quickref/dg-components.md +0 -198
@@ -6,10 +6,11 @@ read_when: 开发过程中做决策时 · Code Review 时
6
6
 
7
7
  ## 服务设计
8
8
 
9
- - **优先用平台能力**:动态 DB → 自定义服务 → 外部 API,按复杂度递进,不要绕过平台直接硬编码
9
+ - **优先用平台能力**:动态 DB → 自定义服务,按复杂度递进,不要绕过平台直接硬编码
10
10
  - **db_meta 先于代码**:操作动态 DB 前先读 `.draftgo/db_meta/index.json`,不要硬编码 type 值
11
11
  - **权限跟数据一起设计**:创建 db_meta 时同时设计 `permission` 字段,不要事后补
12
12
  - **schema_validation 开启**:动态 DB 数据写入时建议开启 `schema_validation: 1`,及早发现数据问题
13
+ - **关联一致性放在 schema**:A 被 B 引用时,优先在 B 的真实引用字段配置 `ref.onDelete`,不要让前端连续请求多个删除接口来模拟级联
13
14
 
14
15
  ## 页面开发
15
16
 
@@ -17,25 +18,43 @@ read_when: 开发过程中做决策时 · Code Review 时
17
18
  - **四态必须都有**:加载态(dg-skeleton)/ 空态(明确文案 + 操作入口)/ 错误态(Toast + 重试)/ 成功态
18
19
  - **初始渲染不能空白**:先展示骨架屏,再异步填数据;不能因为网络延迟导致整页白屏
19
20
  - **新页面必须绑定入口**:导航栏 / 首页模块 / 后台菜单 / 相关页面按钮至少一个;只建文件不绑入口不算完成
21
+ - **导航先复刻再改**:顶部导航和管理端侧边栏通常先基于现有内置导航资源复制/改造,再补业务路由和视觉优化
22
+ - **导航状态要完整**:导航通常同时考虑未登录、已登录、管理员可见性,以及收起/展开状态;普通用户不显示管理后台入口
23
+ - **业务先判断管理端**:案例、新闻、产品、订单、预约、资料等内容优先判断前台展示、管理端维护和同一份真实数据
24
+ - **业务后台按域拆分**:运营日常使用的后台能力优先做业务域管理页并注册到后台侧边栏;`/admin/db` 保留给底层通用数据能力
25
+ - **首页先定定位**:首页通常先按官网介绍、品牌门面和入口聚合设计,除非用户明确要“进入即使用”
26
+ - **先补关键角色路径**:优先明确前台用户和管理员/运营从哪里进入、在哪里操作、怎么回到结果页;简单改动不必机械画全量地图
27
+ - **新系统先落轻量 PRD**:新系统/新板块/新模块先在 `.draftgo/Task/` 写清页面清单、功能清单、数据、入口和验收证据,再开始实现
28
+ - **功能先对齐意图**:新功能先确认“解决谁的什么问题”,再谈页面数、数据源和后台;不要直接跳到实现细节
29
+ - **体验优先本地化**:弹窗/抽屉尽量去滚动条,涉及下拉选项样式时优先做自定义弹层菜单,避免系统默认下拉样式;动效可合理使用本地 GSAP,但不要抢可用性
30
+ - **FilterPill + Popover 筛选胶囊**:列表页筛选推荐这个组合——胶囊按钮触发浮层,浮层内放筛选表单/选项;不阻塞操作,视觉轻量,适合多条件筛选;参考 admin-pages.html 的 `.filter-popover-wrapper` + `.filter-popover` 实现(胶囊按钮 + 独立浮层)
31
+ - **FilterPill + Popove 展开式筛选行**:另一种常见模式——工具栏右侧放"展开筛选"按钮,点击后筛选条件直接展开在工具栏下方;适合筛选项少且固定场景;参考 admin-notices.html 的 `filterOpen && h('div', { className: 'pg-filter-row' }, ...)` 实现(Antd Select 下拉,展开行内横排)
20
32
 
21
33
  ## API 调用
22
34
 
23
35
  - **统一信封消费**:始终检查 `res.code !== 200`,再从 `res.data` 取载荷;不要假设 200
24
- - **分页参数显式传**:列表请求必须传 `page` + `page_size`,超 10000 条后端拒绝
25
- - **外部 API App.callApi**:不要在页面里写 API Key / Bearer,认证由管理端注册、后端注入
36
+ - **按场景选择分页**:列表请求不传 `page` / `page_size` 会全量返回且无上限;页面表格、管理后台和大数据量场景应显式传 `page` + `page_size`
37
+ - **第三方调用走自定义服务**:不要在页面里写 API Key / Bearer;在 Go 服务端用 `ctx.HTTP` 请求并通过 route 暴露受控端点
26
38
 
27
39
  ## 资源路径
28
40
 
29
- - **静态资源用本地路径**:`/assets/tailwindcss.js`、`/assets/fontawesome/css/all.min.css`、`/assets/icons/{name}.svg`
41
+ - **静态资源用本地路径**:`/assets/tailwindcss.js`、`/assets/fontawesome/css/all.min.css`、`/assets/icons/{name}.svg`、`/assets/vendor/html2canvas/html2canvas.min.js`
30
42
  - **图标用内置库**:先查 `/assets/icons/manifest.json`,已有的直接用,不要引外部图标
31
43
 
32
44
  ## 主题适配
33
45
 
34
- - **颜色全用语义 token**:`var(--dg-accent)`、`var(--dg-bg-surface)` 等,避免亮暗切换时颜色失效
35
- - **品牌色 / 图表色例外**:需要同时提供 `[data-theme="dark"]` 选择器覆盖,且确保对比度达 WCAG AA
46
+ - **优先系统主题配色**:默认使用 `var(--dg-accent)`、`var(--dg-bg-surface)` 等语义 token,继承当前浅色 / 深色主题
47
+ - **自主配色要双模式**:页面不搭配、品牌要求、用户明确指定或图表需要时可自定义,但必须提供浅色与深色两套变量或覆盖
48
+ - **品牌色 / 图表色例外**:仍要确保两种模式下对比度达 WCAG AA,避免亮暗切换后颜色失效
36
49
 
37
50
  ## 推送收尾
38
51
 
39
52
  - **修改页面同时推导航**:如果页面新增了导航入口,导航 HTML 也要一起 push
40
53
  - **changelog 按影响写**:影响可见功能、跨资源、已发布时写 `.draftgo/changelog.md`,纯小修可跳过
41
54
  - **用 draftgo check 验收**:涉及路由、入口绑定的改动,用 `draftgo check` 确认没有悬空入口
55
+
56
+ ## 规则分层
57
+
58
+ - **高频高代价规则**:优先内联到必经路径,不要只放在按需读文件里
59
+ - **低频明确触发规则**:保留外链,但必须写出触发条件
60
+ - **低频低代价规则**:保持外链即可
@@ -14,6 +14,7 @@ read_when: 开始任何标准功能/高风险开发任务之前 · 用户意图
14
14
 
15
15
  - 标准功能或高风险任务(按 `dev-workflow.md` 分级)
16
16
  - 涉及 2 个以上资源(页面 + 导航、多页面联动、DB + 页面等)
17
+ - 新系统 / 新板块 / 新模块 / 完整业务能力,需要先产出轻量 PRD 与页面/功能清单
17
18
  - 用户描述包含模糊词(「做一个...」「帮我整一个...」「类似...的功能」)
18
19
  - 实现路径有分叉点(多种技术方案可选)
19
20
  - 用户意图与现有 Story 存在潜在冲突
@@ -31,6 +32,8 @@ read_when: 开始任何标准功能/高风险开发任务之前 · 用户意图
31
32
  | 功能目标(做什么) | 技术实现路径 | 数据来源(DB类型/字段) |
32
33
  | 目标页面/路由 | 权限配置 | 是否需要管理侧页面 |
33
34
  | 核心交互流程 | UI 风格偏好 | 与已有功能的关系 |
35
+ | 入口位置/导航归属 | 角色路径地图 | 是否必须保留系统内置入口 |
36
+ | 导航状态 | 登录态 / 管理员态 / 收起展开 | 是否需要区分未登录 / 已登录 / 管理员 |
34
37
 
35
38
  信息充分 → 直接输出声明
36
39
  关键信息缺失 → 先追问(最多 3 个问题),再输出声明
@@ -44,17 +47,27 @@ read_when: 开始任何标准功能/高风险开发任务之前 · 用户意图
44
47
  ```
45
48
  我准备这样理解这个任务,请确认或调整:
46
49
 
50
+ 0. **功能意图**(我的推测:先对齐这个功能要解决谁的什么问题)
51
+ A. 解决明确业务问题,给明确角色使用(推荐)
52
+ B. 内部/运营工具,不直接面向前台用户
53
+ C. 先做 MVP,方向后续再收敛
54
+
47
55
  1. **数据来源**(我的推测:用动态 DB 新建 `order` 类型)
48
56
  A. 用动态 DB 新建(推荐)
49
57
  B. 复用已有 DB 类型:___
50
58
  C. 用系统配置 KV 存储
51
59
 
52
- 2. **管理侧**(我的推测:需要一个后台管理页)
60
+ 2. **管理侧**(我的推测:通常需要一个后台管理页)
53
61
  A. 需要,用户提交 + 管理员审核
54
62
  B. 不需要,纯用户自助
55
63
  C. 后续再做
56
64
 
57
- 3. **入口位置**(我的推测:加到顶部导航)
65
+ 3. **导航状态**(我的推测:通常需要区分登录态和管理员态)
66
+ A. 需要,未登录 / 已登录 / 管理员都要考虑
67
+ B. 只做已登录态
68
+ C. 仅单一静态入口
69
+
70
+ 4. **入口位置**(我的推测:通常加到顶部导航)
58
71
  A. 顶部导航
59
72
  B. 首页模块入口
60
73
  C. 仅通过链接/按钮访问,不加导航
@@ -73,9 +86,14 @@ read_when: 开始任何标准功能/高风险开发任务之前 · 用户意图
73
86
  - [ ] [资源 1]:[具体内容]
74
87
  - [ ] [资源 2]:[具体内容]
75
88
  - [ ] [入口绑定]:[绑定位置]
89
+ - [ ] [PRD/Task]:在 `.draftgo/Task/` 记录页面清单、功能清单、数据、角色路径、导航状态和管理闭环
90
+
91
+ **意图**:[解决什么问题,给谁用]
76
92
 
77
93
  **数据方案**:[DB类型 / 字段设计 / 权限配置]
78
94
 
95
+ **角色路径 / 管理闭环**:[前台用户怎么进入,管理员/运营怎么维护,是否保留现有系统入口]
96
+
79
97
  **不做的事**:[明确排除的内容,避免范围蔓延]
80
98
 
81
99
  **风险点**:[如有,说明;无则省略]
@@ -83,12 +101,14 @@ read_when: 开始任何标准功能/高风险开发任务之前 · 用户意图
83
101
  确认后开始。
84
102
  ```
85
103
 
104
+ 新系统 / 新板块场景下,这份声明后续应沉淀到 `.draftgo/Task/YYYY-MM-DD-<topic>.md`,并扩展出轻量 PRD。PRD 不追求冗长,但必须清点页面、功能、数据、入口、管理端、导航状态和验收证据。
105
+
86
106
  ---
87
107
 
88
108
  ## 关键原则
89
109
 
90
110
  1. **声明是同步,不是审批**——输出后等用户一句确认(「可以」「没问题」「开始」均算确认),不必等用户逐条review。
91
111
  2. **推测要带自信**——「我推测」不是「我不确定」,是「我基于上下文的最优判断」;若用户不纠正则视为接受。
92
- 3. **一次声明,不反复确认**——声明输出后开始执行,中途不再停下来二次确认细节,除非遇到破坏性操作。
112
+ 3. **一次声明,不反复打断**——声明输出后开始执行,中途不再停下来重复确认细节,除非遇到破坏性操作。
93
113
  4. **小修不触发**——小修直接定位改,拖慢节奏的声明反而是反模式。
94
114
  5. **声明后发现冲突**——若执行中发现与 Story 或现有资源冲突,停止并显式提示,不静默执行。
@@ -25,7 +25,6 @@ allowed-tools: Bash(python:*), Read, Glob
25
25
  !python {{SKILL_SCRIPTS}}/draftgo_pull.py nav [nav_id ...]
26
26
  !python {{SKILL_SCRIPTS}}/draftgo_pull.py db_meta [db_meta_id ...]
27
27
  !python {{SKILL_SCRIPTS}}/draftgo_pull.py aihub [aihub_id ...]
28
- !python {{SKILL_SCRIPTS}}/draftgo_pull.py external_apis [api_id ...]
29
28
  !python {{SKILL_SCRIPTS}}/draftgo_pull.py system_config [config_key ...]
30
29
  !python {{SKILL_SCRIPTS}}/draftgo_pull.py docs [article_id ...]
31
30
  !python {{SKILL_SCRIPTS}}/draftgo_pull.py doc_categories [category_id ...]
@@ -42,6 +41,15 @@ allowed-tools: Bash(python:*), Read, Glob
42
41
  - 多人协作时需要同步其他人的修改
43
42
  - 本地文件损坏或过期,需要刷新
44
43
 
44
+ ## 拉取自定义服务后的身份契约检查
45
+
46
+ `draftgo pull custom_scripts` 会把云端服务的 `code`、`go_mod`、`go_sum` 写回 `.draftgo/custom_scripts/`。其中 `draftgo.Admin.*` 只是 Go 源码中的显式管理员 SDK 调用:
47
+
48
+ - 不会生成 `admin_access`、`system_capabilities` 或 SAT 配置;不要手动补这些字段。
49
+ - `draftgo.DB` 等普通 SDK 调用仍继承 Route 调用者权限;只有 `draftgo.Admin.*` 的那一项调用以平台管理员身份执行并进入执行审计。
50
+ - 拉取后如需修改含 `draftgo.Admin.*` 的服务,先阅读 `../specs/custom-services.md`,保留字段脱敏逻辑,再执行 `draftgo push custom_scripts <id>`。
51
+ - 推送后回读服务执行详情,确认存在 `Admin SDK call` 审计日志;不要把 SAT、管理员 cookie 或数据库连接复制进 `code_file` / `go_mod`。
52
+
45
53
  ## 与 init 的区别
46
54
 
47
55
  | 命令 | 功能 |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: draftgo-push
3
- description: Use this skill when the user says "推送页面", "推送导航", "推送数据库", "推送AI资产", "推送外部API", "推送系统配置", "推送角色", "推送用户", "推送文档", "推送文档分类", "推送自定义脚本", "同步页面", "同步导航", "同步数据库", "同步AI资产", "同步外部API", "同步系统配置", "同步角色", "同步用户", "同步文档", "同步文档分类", "同步自定义脚本", "push pages", "push nav", "push db_meta", "push aihub", "push external_apis", "push system_config", "push roles", "push users", "push docs", "push doc_categories", "push custom_scripts", "sync pages", "sync nav", "sync db_meta", "sync aihub", "sync external_apis", "sync system_config", "sync roles", "sync users", "sync docs", "sync doc_categories", "sync custom_scripts", "/draftgo push", "/draftgo sync", or wants to push local changes to the DraftGo server.
3
+ description: Use this skill when the user says "推送页面", "推送导航", "推送数据库", "推送AI资产", "推送系统配置", "推送角色", "推送用户", "推送文档", "推送文档分类", "推送自定义脚本", "同步页面", "同步导航", "同步数据库", "同步AI资产", "同步系统配置", "同步角色", "同步用户", "同步文档", "同步文档分类", "同步自定义脚本", "push pages", "push nav", "push db_meta", "push aihub", "push system_config", "push roles", "push users", "push docs", "push doc_categories", "push custom_scripts", "sync pages", "sync nav", "sync db_meta", "sync aihub", "sync system_config", "sync roles", "sync users", "sync docs", "sync doc_categories", "sync custom_scripts", "/draftgo push", "/draftgo sync", or wants to push local changes to the DraftGo server.
4
4
  version: 1.5.0
5
5
  allowed-tools: Bash(python:*), Read, Glob
6
6
  ---
@@ -8,7 +8,7 @@ allowed-tools: Bash(python:*), Read, Glob
8
8
  # DraftGo 推送(本地 → 云端)
9
9
 
10
10
  > **STOP — 禁止用 curl、禁止自己写 Python 上传逻辑。**
11
- > 唯一正确方式:运行下方 Python 脚本。脚本覆盖 init 拉取的全部类型(pages / nav / db_meta / aihub / external_apis / system_config / roles / users / docs / doc_categories / custom_scripts),已处理字段结构、token 读取、错误处理。
11
+ > 唯一正确方式:运行下方 Python 脚本。脚本覆盖 init 拉取的全部类型(pages / nav / db_meta / aihub / system_config / roles / users / docs / doc_categories / custom_scripts),已处理字段结构、token 读取、错误处理。
12
12
 
13
13
  脚本位于:`{{SKILL_SCRIPTS}}/draftgo_push.py`
14
14
 
@@ -18,7 +18,7 @@ allowed-tools: Bash(python:*), Read, Glob
18
18
  > - **有 id** → `PUT /api/{type}/{id}` 更新(PUT 404 时自动转为创建)
19
19
  > - **无 id** → `POST /api/{type}` 创建,成功后**自动回写新 id 到 index.json**,并把对应 .html/.md/代码文件**重命名为 pull 约定的 `{prefix}_{id}_{slug}.{ext}`**
20
20
 
21
- 支持创建的类型:**pages / nav / db_meta / aihub / external_apis / docs / doc_categories / custom_scripts**。
21
+ 支持创建的类型:**pages / nav / db_meta / aihub / docs / doc_categories / custom_scripts**。
22
22
 
23
23
  ### 新建页面的标准流程
24
24
 
@@ -50,10 +50,9 @@ allowed-tools: Bash(python:*), Read, Glob
50
50
  | nav | `name`, `code` | 创建必填 code,更新时不发 |
51
51
  | db_meta | `type`, `label`, `schema` | 无 id 时按 type 创建 |
52
52
  | aihub | `type`, `name`, `data` | 支持 model/prompt/agent/mcp/skill 等 AI 资产 |
53
- | external_apis | `code`, `name`, `base_url` | code 不可包含 `/` 或空格;创建时不发送 status |
54
53
  | docs | `title` | 其余字段有默认值 |
55
54
  | doc_categories | `name` | slug 可选;不填由后端生成/处理 |
56
- | custom_scripts | `name`, `slug`, `mode`, `triggers` | mode=route/event/scheduled;创建后默认覆盖代码,启停仍走 enable/disable |
55
+ | custom_scripts | `name`, `slug`, `mode` | 服务使用 `mode=mixed`;触发器写在 `Register` 中,启停仍走 enable/disable |
57
56
 
58
57
  > **创建后必须以脚本回写的 index 为准**,不要手动猜 id。回写后建议 `git diff` 或重新读 index 确认 `id` 已落地。
59
58
 
@@ -90,15 +89,6 @@ allowed-tools: Bash(python:*), Read, Glob
90
89
 
91
90
  读取 `.draftgo/aihub/index.json`,按 `AIHubUpdate` schema 推送;无 `id` 或 PUT 404 时会 `POST /api/aihub` 创建,成功后回写新 `id`。
92
91
 
93
- ## 推送外部 API("推送外部API" / "push external_apis")
94
-
95
- ```
96
- !python {{SKILL_SCRIPTS}}/draftgo_push.py external_apis
97
- !python {{SKILL_SCRIPTS}}/draftgo_push.py external_apis <api_id>
98
- ```
99
-
100
- 读取 `.draftgo/external_apis/index.json`(已包含 init 时合并的 detail 字段),按 `ExternalAPIUpdate` schema 推送;无 `id` 或 PUT 404 时会 `POST /api/external-apis` 创建,成功后回写新 `id`。创建最少需要 `code`、`name`、`base_url`。
101
-
102
92
  ## 推送系统配置("推送系统配置" / "push system_config")
103
93
 
104
94
  ```
@@ -108,33 +98,41 @@ allowed-tools: Bash(python:*), Read, Glob
108
98
 
109
99
  读取 `.draftgo/system_config/index.json`,按 `config_key` 调用 `PUT /api/system/{config_key}`。脚本优先使用 `parsed_value`。
110
100
 
111
- ## 推送角色("推送角色" / "push roles")⚠️ 需二次确认
101
+ 前端全局层(`category = frontend_global` 或 `frontend_global_*`)属于系统默认配置,推送时只发送 `config_value`,不要发送 `description/category/value_type/status` 等元信息。其它系统配置若遇到“系统默认字段不允许修改字段描述/分类/状态”等错误,脚本会自动降级为只推送 `config_value`。
112
102
 
113
- roles 涉及权限安全,**强制要求人工确认**:
103
+ Toast 全局配置常用键:
114
104
 
115
- 1. 读取 `.draftgo/roles/index.json`
116
- 2. **向用户展示即将推送的变更内容**
117
- 3. **等待用户明确确认**
118
- 4. 确认后运行:
119
- ```
120
- !python {{SKILL_SCRIPTS}}/draftgo_push.py roles
121
- !python {{SKILL_SCRIPTS}}/draftgo_push.py roles <role_id>
122
- ```
123
- 5. 用户拒绝则不推送
105
+ | config_key | 说明 |
106
+ |---|---|
107
+ | `frontend_global_toast_position` | 位置,支持 `center` |
108
+ | `frontend_global_toast_scale` | 大小比例,范围 `0.5-3` |
109
+ | `frontend_global_toast_opacity` | 背景透明度,范围 `0-100` |
110
+ | `frontend_global_toast_duration_success/error/warning/info` | 默认停留时间,存储单位为毫秒;页面管理以秒输入 |
111
+ | `frontend_global_toast_css` | Toast 自定义 CSS |
112
+ | `frontend_global_scrollbar_color_mode` | 滚动条颜色模式:`theme` / `custom` |
113
+ | `frontend_global_scrollbar_color` | 自定义滚动条颜色,`#RRGGBB` |
114
+ | `frontend_global_scrollbar_buttons` | 是否显示两端按钮 |
115
+ | `frontend_global_scrollbar_opacity` | 滑块透明度,范围 `0-100` |
116
+ | `frontend_global_scrollbar_radius` | 圆角 px |
117
+ | `frontend_global_scrollbar_width` | 宽度 px |
118
+
119
+ ## 推送角色("推送角色" / "push roles")
124
120
 
125
- ## 推送用户("推送用户" / "push users")⚠️ 需二次确认
121
+ ```
122
+ !python {{SKILL_SCRIPTS}}/draftgo_push.py roles
123
+ !python {{SKILL_SCRIPTS}}/draftgo_push.py roles <role_id>
124
+ ```
126
125
 
127
- users 涉及账号安全,**强制要求人工确认**:
126
+ 读取 `.draftgo/roles/index.json`,按 `RoleUpdateRequest` 字段推送。脚本不会修改未写入索引的权限绑定关系。
128
127
 
129
- 1. 读取 `.draftgo/users/index.json`
130
- 2. **向用户展示即将推送的变更内容**
131
- 3. **等待用户明确确认**
132
- 4. 确认后运行:
133
- ```
134
- !python {{SKILL_SCRIPTS}}/draftgo_push.py users
135
- !python {{SKILL_SCRIPTS}}/draftgo_push.py users <user_id>
136
- ```
137
- 5. 脚本不会下发 password / role_ids;如需修改请走专用接口
128
+ ## 推送用户("推送用户" / "push users")
129
+
130
+ ```
131
+ !python {{SKILL_SCRIPTS}}/draftgo_push.py users
132
+ !python {{SKILL_SCRIPTS}}/draftgo_push.py users <user_id>
133
+ ```
134
+
135
+ 读取 `.draftgo/users/index.json`,按 `UserUpdateRequest` 字段子集推送。脚本不会下发 `password` / `role_ids`;如需修改请走专用接口。
138
136
 
139
137
  ## 推送文档("推送文档" / "push docs")
140
138
 
@@ -143,7 +141,7 @@ users 涉及账号安全,**强制要求人工确认**:
143
141
  !python {{SKILL_SCRIPTS}}/draftgo_push.py docs <article_id>
144
142
  ```
145
143
 
146
- 读取 `.draftgo/docs/articles/index.json`;正文从 meta 中的 `content_file`(同目录 `.md` 文件)回填,按 `ArticleUpdate` schema 推送。修改文档时**直接改 `.md` 文件**即可,索引项保持稳定。
144
+ 读取 `.draftgo/docs/articles/index.json`;正文从 meta 中的 `content_file`(同目录 `.html` 文件)回填,按 `ArticleUpdate` schema 推送(自动附带 `content_type: "html"`)。修改文档时**直接改 `.html` 文件**即可,索引项保持稳定。
147
145
 
148
146
  ## 推送文档分类("推送文档分类" / "push doc_categories")
149
147
 
@@ -154,19 +152,16 @@ users 涉及账号安全,**强制要求人工确认**:
154
152
 
155
153
  读取 `.draftgo/doc_categories/index.json`,按 `CategoryUpdate` schema 推送;无 `id` 或 PUT 404 时会 `POST /api/docs/categories` 创建,成功后回写新 `id`。
156
154
 
157
- ## 推送自定义脚本("推送自定义脚本" / "push custom_scripts")⚠️ 需二次确认
155
+ ## 推送自定义脚本("推送自定义脚本" / "push custom_scripts"
158
156
 
159
- 脚本代码会以**生效语义**直接覆盖云端运行的脚本,**强制要求人工确认**:
157
+ > 编写或修改代码前必须先读 `{{SKILL_DIR}}/specs/custom-services.md`。新服务使用 Go `Register(app *sdk.App)`;该文档是 handler ctx、完整 SDK、权限和运行限制的权威契约。
160
158
 
161
- 1. 读取 `.draftgo/custom_scripts/index.json`,并读取每条 meta 中 `code_file` 指向的代码文件
162
- 2. **向用户展示即将更新的脚本与摘要差异**
163
- 3. **等待用户明确确认**
164
- 4. 确认后运行:
165
- ```
166
- !python {{SKILL_SCRIPTS}}/draftgo_push.py custom_scripts
167
- !python {{SKILL_SCRIPTS}}/draftgo_push.py custom_scripts <script_id>
168
- ```
169
- 5. 脚本不会修改 `mode`/`slug`/`status`(避免误启停);如需切换启停请走 `POST /api/scripts/{id}/enable|disable`
159
+ ```
160
+ !python {{SKILL_SCRIPTS}}/draftgo_push.py custom_scripts
161
+ !python {{SKILL_SCRIPTS}}/draftgo_push.py custom_scripts <script_id>
162
+ ```
163
+
164
+ 读取 `.draftgo/custom_scripts/index.json`,并读取每条 meta 中 `code_file` 指向的代码文件后推送。脚本不会修改 `mode`/`slug`/`status`(避免误启停);如需切换启停请走 `POST /api/scripts/{id}/enable|disable`。
170
165
 
171
166
  ### ⚠️ code_file 一致性(强制)
172
167
 
@@ -179,35 +174,77 @@ users 涉及账号安全,**强制要求人工确认**:
179
174
 
180
175
  违反后果:推送静默成功但上传的是旧代码,云端脚本不更新,排查极其隐蔽。
181
176
 
182
- ## 冲突检测(多窗口协作保护)
177
+ ### Go 服务注册规则(强制)
183
178
 
184
- > push 前会自动检测云端是否已被他人修改,防止静默覆盖。
179
+ 新服务必须使用 `package main` 与 `Register(app *sdk.App)`:
185
180
 
186
- **工作原理**:pull 时 `index.json` 会记录每条资源的 `updated_at`。push 时先 GET 云端当前 `updated_at`,与本地基线比对:
181
+ ```go
182
+ func Register(app *sdk.App) {
183
+ app.Route("GET", "/doctors", doctors)
184
+ app.On("doctor.updated", refresh)
185
+ }
187
186
 
188
- - **一致** 正常推送
189
- - **不一致** 跳过该条,打印警告,继续推下一条
190
- - **`--force`** → 跳过检测,直接覆盖
187
+ func doctors(draftgo *sdk.Context) (any, error) {
188
+ return draftgo.Respond(map[string]any{"ok": true}, 200, nil), nil
189
+ }
190
+ ```
191
191
 
192
- **典型场景**:
192
+ 路径换算:`slug=prescription` + `app.Route("GET", "/doctors", doctors)` = `GET /api/x/prescription/doctors`。一个服务可混合多个 route、event、scheduled handler;新服务使用 `mode=mixed`。旧 `triggers` 字段不是 Go 注册来源。
193
193
 
194
- | 场景 | 行为 |
195
- |---|---|
196
- | 单窗口正常 push | 无变化,正常推 |
197
- | 窗口 A push 后,窗口 B push 同一资源 | B 检测到冲突 → 跳过 |
198
- | B `draftgo pull` push | pull 刷新基线 正常推 |
199
- | 确定要覆盖 → `draftgo push --force` | 跳过检测,强制覆盖 |
194
+ route 脚本推送后的完成证据不能只看 `OK script_id=...`;至少还要真实请求目标端点,确认返回不是 404。需要鉴权时带管理员或允许角色 token 验证。
195
+
196
+ ### route handler SDK 运行时(强制)
197
+
198
+ handler 签名为 `func handler(draftgo *sdk.Context) (any, error)`。`draftgo` 是普通局部变量名,可自定义;本 skill 统一用它强调平台能力。Route 输入位于 `draftgo.Input`:`body`、`query_params`、`headers`、`method`、`path_params`;`path_params` 只含 `slug/path`,不解析 `{id}` 模板。身份用 `draftgo.Auth.CurrentUser()`,状态码和响应头用 `draftgo.Respond(...)`。
199
+
200
+ ### 显式管理员 SDK 调用(随代码同步)
201
+
202
+ `draftgo.Admin.*` 是 Go 服务源码的一部分;它不对应 `admin_access`、`system_capabilities` 或其他 index 配置字段。pull/push 只同步 `code_file`、`go_mod`、`go_sum`,**绝不**在本地元数据、服务源码、页面或请求中写入 SAT。
203
+
204
+ ```go
205
+ // 普通调用继承 Route 调用者权限。
206
+ mine, err := draftgo.DB.Query("order", sdk.QueryOptions{})
207
+
208
+ // 只有这一项调用以平台管理员身份执行,运行时自动记录审计。
209
+ catalog, err := draftgo.Admin.DB.Query("internal_catalog", sdk.QueryOptions{})
210
+ ```
211
+
212
+ `draftgo.Admin` 对齐普通 SDK 的 `DB`、`Users`、`Auth`、`Notify`、`HTTP`、`Cache`、`Config`、`AIHub`。管理员服务可使用完整平台权限;调用方返回前仍应显式组装允许暴露的字段。包含 `draftgo.Admin.` 的服务推送后,除 route 真实请求外,还必须回读 `/api/scripts/{id}/executions/{execution_id}`,确认 `logs` 有 `Admin SDK call` 审计项。
213
+
214
+ ### ctx.DB.Query 分页语义(强制)
215
+
216
+ 自定义服务里的 `ctx.DB.Query(type, sdk.QueryOptions{...})` 返回 `sdk.QueryResult`:
217
+
218
+ ```go
219
+ result, err := ctx.DB.Query("order", sdk.QueryOptions{Page: 1, PageSize: 20})
220
+ ```
221
+
222
+ - `sdk.QueryResult` 提供 `Items`、`Total`、`Page`、`PageSize`。
223
+ - 使用 `Page` 与 `PageSize` 明确分页;需要完整数据时按 `Total` 逐页读取。
224
+ - `filters` 默认是 `eq` 精确匹配;字段必须在 db_meta schema 中标记 `searchable`,操作符规则见 `specs/data.md`。
225
+
226
+ ### 权限与安全配置(强制区分)
227
+
228
+ - `scripts:read/create/update/delete/execute` 是服务管理面的角色 RBAC;创建和编辑权限只授予可信代码编辑者。
229
+ - `permission` 决定谁能调用 route 服务:`public` / `login` / `admin` / 指定 roles。
230
+ - `config.route_security` 决定运行时护栏:`auth_required`、`rate_limit_per_minute`、`burst_limit`、`max_body_size_kb`、`timeout_ms`、`ip_allowlist`、`ip_blocklist`。
231
+ - `permission` 为空时默认公开;如服务不应公开,必须显式设置 `permission.default` 或 `route_security.auth_required=true`。
232
+ - 管理权限不自动获得 route 调用权限;推送时不要因调用者是管理员或编辑者而省略 `permission`。
233
+ - 管理员 SDK 不是 Route 自动提权:只有代码显式调用 `draftgo.Admin.*` 的单次 SDK 操作提升为管理员身份;其余 `draftgo.DB` 等调用仍按 Route 调用者权限执行。
234
+ - 高并发服务配置 `max_concurrency` / `queue_timeout_ms`,并让调用方处理 HTTP 429;不要依赖不存在的自动重试配置。
235
+
236
+ ## 推送语义
237
+
238
+ `pull` 只负责从云端拉取到本地,`push` 只负责把本地文件推送到云端。push 不做云端 `updated_at` 对比,也不会因为云端时间更新而跳过资源;请在推送前自行确认本地文件就是要生效的版本。
200
239
 
201
240
  **CLI 用法**:
202
241
  ```bash
203
- draftgo push pages # 带冲突检测
204
- draftgo push pages --force # 跳过检测,强制覆盖
242
+ draftgo push pages
205
243
  ```
206
244
 
207
245
  **脚本直接调用**:
208
246
  ```
209
247
  !python {{SKILL_SCRIPTS}}/draftgo_push.py pages
210
- !python {{SKILL_SCRIPTS}}/draftgo_push.py pages --force
211
248
  ```
212
249
 
213
250
  ## 推送方式
@@ -241,9 +278,7 @@ payload 必须包含完整元数据(从 `pages/index.json` 读取)+ HTML:
241
278
 
242
279
  **AI 资产推送**:`PUT /api/aihub/{id}`,payload 子集:`type`, `name`, `data`, `priority`, `version`, `tags`, `describe`, `permission`, `status`。
243
280
 
244
- **外部 API 推送**:`PUT /api/external-apis/{id}`,payload 子集:`name`, `base_url`, `method`, `path`, `headers`, `auth_type`, `auth_config`, `timeout_ms`, `permission`, `param_schema`, `tags`, `description`, `status`。
245
-
246
- **系统配置推送**:`PUT /api/system/{config_key}`,payload:`config_value`(parsed), `value_type`, `category`, `description`, `is_sensitive`, `status`。
281
+ **系统配置推送**:`PUT /api/system/{config_key}`。前端全局层和受保护系统默认配置只推 `config_value`(parsed);自定义配置可推 `value_type`, `category`, `description`, `is_sensitive`, `status`,不存在时再 `POST /api/system/` 创建。
247
282
 
248
283
  **角色推送**:`PUT /api/roles/{id}`,payload 含 `name`, `description`, `status`, `sort_order`, `user_visible`。
249
284
 
@@ -253,7 +288,7 @@ payload 必须包含完整元数据(从 `pages/index.json` 读取)+ HTML:
253
288
 
254
289
  **文档分类推送**:`PUT /api/docs/categories/{id}`,payload:`name`, `slug`, `description`, `icon`, `parent_id`, `sort_order`, `status`。
255
290
 
256
- **自定义脚本推送**:`PUT /api/scripts/{id}`,payload 子集:`name`, `description`, `code`(从语言对应的代码文件读取), `triggers`, `config`, `permission`。注意 schema 不接受 `mode`/`status`,启停请走 `POST /api/scripts/{id}/enable|disable`。
291
+ **自定义脚本推送**:`PUT /api/scripts/{id}`,payload 子集:`name`, `description`, `code`(从语言对应的代码文件读取), `config`, `permission`。触发器只来自代码装饰器,不发送旧 `triggers` 字段。注意 schema 不接受 `mode`/`status`,启停请走 `POST /api/scripts/{id}/enable|disable`。
257
292
 
258
293
  ## 失败处理
259
294
 
@@ -4,8 +4,10 @@ read_when: 需要查具体 API 端点时 · 构造请求时
4
4
 
5
5
  # 后端 API 速查
6
6
 
7
- > 完整 OpenAPI 规范见 [api.json](./api.json)
7
+ > 优先运行 `draftgo api <keyword>` 做结构化查询;需要完整 OpenAPI 时见 [api.json]({{SKILL_SHARED}}/quickref/api.json)
8
8
  > 统一响应信封:`{ code: 200, data: <载荷>, message: "success" }`
9
+ > GET 列表端点通常在不传 `page` / `page_size` 时全量返回;自定义服务执行记录是固定分页特例(默认 20,最大 100)。
10
+ > Go 自定义服务使用 `ctx.DB.Query(type, sdk.QueryOptions{...})`;返回 `sdk.QueryResult`,筛选和分页见 `specs/custom-services.md`。
9
11
 
10
12
  ## 认证
11
13
 
@@ -19,95 +21,116 @@ POST /api/auth/wechat/mp/qr/create GET /wechat/mp/qr/poll
19
21
  ## 用户 & 角色
20
22
 
21
23
  ```
22
- GET/PUT /api/users/me PUT /users/me/password
23
- GET/POST /api/users GET/PUT/DELETE /users/{id}
24
- POST /users/{id}/ban, /unban
24
+ GET/PUT /api/users/me PUT /api/users/me/password
25
+ GET/POST /api/users GET/PUT/DELETE /api/users/{id}
26
+ POST /api/users/{id}/ban, /unban
25
27
 
26
- GET/POST /api/roles GET/PUT/DELETE /roles/{id}
27
- POST /roles/{id}/assign/{uid} DELETE /roles/{id}/revoke/{uid}
28
+ GET/POST /api/roles GET/PUT/DELETE /api/roles/{id}
29
+ POST /api/roles/{id}/assign/{uid} DELETE /api/roles/{id}/revoke/{uid}
28
30
  ```
29
31
 
30
32
  ## 页面
31
33
 
32
34
  ```
33
35
  GET/POST /api/pages/
34
- GET/PUT/DELETE /pages/{id}
35
- POST /pages/{id}/reset-system
36
- GET /pages/by-route?route=/xxx
37
- GET /pages/{id}/versions
38
- POST /versions/{vid}/restore, /star
36
+ GET/PUT/DELETE /api/pages/{id}
37
+ POST /api/pages/{id}/reset-system
38
+ GET /api/pages/by-route?route=/xxx
39
+ GET /api/pages/{id}/versions
40
+ POST /api/pages/{page_id}/versions/{version_id}/restore, /star
39
41
  ```
40
42
 
41
43
  ## 导航栏
42
44
 
43
45
  ```
44
46
  GET/POST /api/navigations
45
- GET /navigations/{code}
46
- PUT/DELETE /navigations/{id}
47
+ GET /api/navigations/{code}
48
+ PUT/DELETE /api/navigations/{id}
47
49
  ```
48
50
 
49
51
  ## 动态 DB
50
52
 
51
53
  ```
52
- GET /api/db/{type} 支持 filters/order_by/order
53
- POST /db/{type} body: { data: {...} } 或数组
54
- PATCH /db/{type}/batch
55
- GET/PUT/DELETE /db/{type}/{id}
54
+ GET /api/db/{type}
55
+ 支持 filters/order_by/order/page/page_size/populate/scope=mine
56
+ scope=mine 仅 admin 用户的列表 GET 生效:非后台业务页用,后台管理页不用
57
+ 📌 filters 语法 → specs/data.md#filters-操作符
58
+ 📌 searchable 模式 → specs/data.md#searchable-字段标记
59
+ 📌 ref/populate/onDelete → specs/data.md#关联关系ref
60
+ POST /api/db/{type} body: { data: {...} } 或数组
61
+ PATCH /api/db/{type}/batch
62
+ GET/PUT/DELETE /api/db/{type}/{id}
63
+ DELETE 会按真实引用字段的 ref.onDelete 处理级联 / 置空 / 阻止 / 解除关联
56
64
  ```
57
65
 
58
66
  ## DB Meta ⚠️
59
67
 
60
68
  ```
61
69
  GET/POST /api/db-meta
62
- GET /db-meta/{type} ← 必须用 type,不是 id!
63
- PUT/DELETE /db-meta/{id}
64
- POST /db-meta/{type}/reconcile-fields
70
+ GET /api/db-meta/{type} ← 必须用 type,不是 id!
71
+ PUT/DELETE /api/db-meta/{id}
72
+ POST /api/db-meta/{type}/reconcile-fields
65
73
  ```
66
74
 
67
75
  ## 自定义服务
68
76
 
69
77
  ```
70
78
  GET/POST /api/scripts
71
- GET/PUT/DELETE /scripts/{id}
72
- POST /scripts/{id}/enable, /disable, /execute
79
+ GET /api/scripts/options/roles
80
+ GET/PUT/DELETE /api/scripts/{id}
81
+ GET /api/scripts/{id}/routes
82
+ POST /api/scripts/{id}/enable, /disable, /execute
83
+ GET /api/scripts/{id}/versions
84
+ POST /api/scripts/{id}/versions/{version_id}/restore
85
+ GET /api/scripts/{id}/executions
86
+ GET /api/scripts/{id}/executions/{execution_id}
73
87
  ANY /api/x/{slug}/{path} ← 脚本运行时端点
74
88
  ```
75
89
 
76
- ## 外部 API
77
-
78
- ```
79
- GET /api/external-apis/available ← 页面可调用列表(优先用 App.callApi)
80
- GET/POST /api/external-apis ← 管理端
81
- PATCH /external-apis/{id}/status
82
- POST /external-apis/{id}/test
83
- ```
90
+ 自定义服务要点:
91
+
92
+ - 本地文件:`.draftgo/custom_scripts/index.json` + 每条记录的 `code_file`。
93
+ - 新服务使用 Go `Register(app *sdk.App)`;用 `app.Route` / `app.On` / `app.Schedule` 自动注册。
94
+ - 新服务使用 `mode=mixed`,可同时暴露 HTTP、响应事件和执行 cron。
95
+ - route 注册来自 `app.Route("METHOD", "/path", handler)`;一个服务可声明多个 route,共用同一个 slug 命名空间。
96
+ - event 和 scheduled 分别来自 `app.On(...)` 与 `app.Schedule(...)`;均支持在一个服务内声明多个 handler。
97
+ - 旧 `triggers` 字段不参与注册,CLI 不再创建或推送该字段。
98
+ - route handler 签名:`func handler(ctx *sdk.Context) (any, error)`;实际字段位于 `ctx.Input`,用户身份用 `ctx.Auth.CurrentUser()`。
99
+ - Route 的普通 SDK 调用继承当前调用者资源权限,管理员创建服务不自动提升;需要管理员权限时逐次显式调用 `draftgo.Admin.DB`、`draftgo.Admin.Users` 等。`Admin` 调用以管理员身份执行并自动写入执行审计,但不会向代码暴露 SAT。带 `user_id` / `actor_user_id` 的事件继承该用户,定时任务及无可解析用户的事件才是系统身份。
100
+ - 路径换算:`slug=order` + `app.Route("POST", "/pay", handler)` → `POST /api/x/order/pay`。
101
+ - route 是精确路径匹配,不支持 `/items/{id}` 参数模板;ID 使用 query/body。
102
+ - 动态数据访问使用 `ctx.DB.Query("order", sdk.QueryOptions{...})`,结果为 `sdk.QueryResult`;筛选与分页见 `specs/custom-services.md`。
103
+ - `permission` 控制调用权限;`config.route_security` 控制限流、IP、body 大小和超时。
104
+ - `scripts:*` 控制服务管理权限,和 Route 的调用权限彼此独立;执行列表固定分页,详情日志按单条加载。
105
+ - `config.max_concurrency` / `queue_timeout_ms` 控制服务级退避;Route 饱和返回 429。
106
+ - 完整 SDK、ctx、AIHub、事件、配置与运行限制见 `specs/custom-services.md`。
84
107
 
85
108
  ## AIHub & AI推理
86
109
 
87
110
  ```
88
111
  GET/POST /api/aihub
89
- POST /aihub/{id}/sync
112
+ POST /api/aihub/{id}/sync
90
113
  GET /api/v1/models
91
- POST /v1/chat/completions ← OpenAI 兼容格式
92
- POST /api/agents/{id}/chat, /images
114
+ POST /api/v1/chat/completions ← OpenAI 兼容格式
115
+ POST /api/agents/{id}/chat, /api/agents/{id}/images
93
116
  ```
94
117
 
95
118
  ## 文档中心
96
119
 
97
120
  ```
98
121
  GET/POST /api/docs/categories
99
- GET /docs/articles, /docs/articles/{key}, /docs/search
100
- POST /docs/articles PUT/DELETE /docs/articles/{id}
122
+ GET /api/docs/articles, /api/docs/articles/{key}, /api/docs/search
123
+ POST /api/docs/articles PUT/DELETE /api/docs/articles/{id}
101
124
  ```
102
125
 
103
126
  ## 系统 & 备份
104
127
 
105
128
  ```
106
129
  GET /api/system/config
107
- GET/PUT/DELETE /system/{key}
130
+ GET/PUT/DELETE /api/system/{key}
108
131
  GET/POST /api/system/backup
109
- POST /system/restore, /reset
110
- POST /system/restore/selective?mode=replace|merge|append
132
+ POST /api/system/restore, /api/system/reset
133
+ POST /api/system/restore/selective?mode=replace|merge|append
111
134
  POST /api/upload
112
135
  GET /api/logs
113
136
  ```
@@ -124,7 +147,6 @@ POST /api/auth/reauth { password, scope } → 返回 confirm_token
124
147
 
125
148
  | 端点 | 格式 |
126
149
  |---|---|
127
- | `POST /v1/chat/completions` | OpenAI SSE / JSON |
128
- | `GET /v1/models` | `{ object:"list", data:[...] }` |
129
- | `POST /external-apis/call/{code}` | 上游原始响应 |
150
+ | `POST /api/v1/chat/completions` | OpenAI SSE / JSON |
151
+ | `GET /api/v1/models` | `{ object:"list", data:[...] }` |
130
152
  | `ANY /api/x/{slug}/{path}` | 脚本自定义 |