① 灵魂:五个概念,一条闭环
Jeff 定的。这五个词一旦写死,后面接手的人就不会越做越歪。
| 概念 | 是什么 | 一句话判据 |
|---|---|---|
| APP | 一个永久存在的产品容器 | 它不会因为改版而变成另一个东西 |
| VERSION | 永远不能修改的代码快照 | 存进去就封死;要改是发新的,不是改旧的 |
| ENVIRONMENT | Staging / Live | 不只是两份代码 —— 数据也各是各的 |
| WORKROOM | 围绕这个 app 干活的人 + AI + 上下文 | 它是这个 app 的大脑和记忆,不是一个项目阶段 |
| EVENT | app 在工作室留下的生产记录 | 房里的人不用问"到底传了没" |
闭环
判据:这条链上每一步都要能在房里看见。看不见的那一步,就是将来有人要来问"现在到底怎么样了"的那一步。
所以这份蓝图里凡是"要不要摆出来"的地方,一律按轻的在外面、重的点进去排。
② 造一个 app 的全程
| 步 | 他做什么 | 平台做什么 | 现在 |
|---|---|---|---|
| 1 | 申请成为开发者 | 审一次身份 | 已落地 |
| 2 | 开一个 app,填名字/图标/一句话 + 申报要用哪些能力 | 发 id、开辟空间、状态 draft | 建项目 已落地 能力申报 待做 |
| 3 | 传图片进图像库 | 存 R2、记账 | 已落地 |
| 4 | 传代码(单 HTML 或 zip) | 每一版都过安检 → 存成永不改的快照 | 已落地 |
| 5 | 自己先试 | 发一小时门票 + 接到 staging 数据 | 门票 已落地 数据隔离 有洞 |
| 6 | 按上线 | 首次要人审;之后自己按,除非新增了能力 | 首审 已落地 能力触发复审 待做 |
| 7 | 坏了按退回 | 指针拨回上一版 | 已落地 |
| 8 | 按「Open Studio」 | 第一次按 = 建房并绑上;以后按 = 进去 | 待做 |
entry_url 建的时候是空字符串,这是我读 createApp 确认的。③ 开发者中心 = 控制中心
Jeff 定的分界:中心管「这个 app 的资产和账户」,工作室管「这个 app 正在发生什么」。
Jeff 第 6 刀:补上 Secrets 和 Logs
规矩:只能写不能读。存进去之后界面只显示"有这么一个键",值永远不再吐出来。 AI 可以让 app 在运行时用到它,但AI 自己拿不到明文 —— 这条是给"房里有别人的 AI"准备的。
Jeff:「你现在规划的『今天打开次数/人数』有用,但不够解决开发问题。」他把这两块排在数字前面,我同意。
④ App 工作室 = 生产现场
一个 app 一间房,永久的。房里的人围着这一个 app 聊、改、试、上线。
怎么进去:只有一颗按钮
判据:凡是我们内部的实现名词漏到界面上,用户就得学一个他不该学的概念。
房顶只回答三个问题
Jeff 把我 v1 那张信息很多的卡砍到只剩三句:
Jeff:「这样不会把聊天房顶部做成一排 Dashboard。」房的主体永远是聊天。
底下那一页:工作台里多一格「App」
页签 4 变 5:💓 Pulse · 📋 Tasks · ⚙️ Setup · ℹ️ Info · 📱 App(只有绑了 app 的房才有)。
values 画 →
所有工作房都多出一格空页签。「这间房显示哪几页」抽成一个函数当唯一出处,app 排最后,前四页下标不变。⑤ 分工
他的原话:「以后千万不要慢慢长成 —— 中心有版本,工作室又有版本管理;中心有数据库, 工作室又搞一套数据库管理;中心有发布,工作室又有另一套发布流程。这样最后一定乱。」
工作室永远是:聊 → AI 做 → 新版本出来 → 大家试 → 决定上线。这是现场。
开发者中心才是:app 资料、权限、数据、版本历史、安全、配置、正式管理。
| 事情 | 开发者中心 | 工作室 |
|---|---|---|
| 看我所有 app | ✅ 唯一入口 | ✗ |
| 新建 / 改名 / 改图标 | ✅ | ✗ |
| 能力申报 · 密钥 · 日志 | ✅ 唯一入口 | ✗ |
| 版本历史(全部) | ✅ | 只显最近几版 |
| 传新版代码 | ✅ | ✅(AI 改完直接传,不用绕出去) |
| 试 Staging | ✅ | ✅ |
| 上线 / 退回 | ✅ | ✅ 只给 Owner |
| 公共数据 | ✅ 编辑 | 只看不改 |
| 用户数据 | 按授权(见第 ⑥ 格) | ✗ 永不 |
| 审核状态 / 打回理由 | ✅ | ✗ 永不 |
| 派活、任务卡、反馈转卡 | ✗ | ✅ |
⑥ 数据三层(Jeff 第 2 刀)
不是放弃隐私,是把『谁拥有哪一种数据』定义得更漂亮。」他是对的。
| 层 | 是什么 | 开发者 | 工作室 | 例子 |
|---|---|---|---|---|
| ① Hoop 用户私有资料 | 真名、头像、手机、关系链 | 永远看不到 | ✗ | 你是谁 |
| ② App 自产数据 | 用户在这个 app 里产生的 | 按用户授权 + app 能力 | ✗ 不显内容 | 订单、预约、表单 |
| ③ 公共 app 数据 | 开发者放给所有人看的 | ✅ 可管理 | 只看不改 | 餐厅表、栏目表 |
第 ② 层怎么落地(这是新的一刀,现在没有)
现在 miniapp_kv 是"每人一个抽屉,开发者只看得到三个数字"。要支持订单类 app,
就得让开发者在用户点头之后看得到属于业务的那部分。
owner_uid 和 purpose(下单/报名/客服)。开发者读它要满足两条:① app 申报过对应能力并过审 ② 这条数据的主人授权过这个用途。
判据:用户能在一个地方看到「这个 app 拿了我哪些东西」,并且能撤回。撤不回的授权不叫授权。
⑦ 环境隔离与回滚红线
Jeff 第 4 刀:Staging 不只是另一份代码有洞
现在两张数据表的主键分别是
(app_id, 用户, key) 和 (app_id, key) ——
里面根本没有 staging / live 这一维。也就是说:房里几个人试一下 v4,写的就是正式用户的数据。没有任何隔离,一个环境列都没有。
Staging Build + Staging Data 和 Live Build + Live Data,默认隔离。落法:两张表各加一列
env,进主键;launch 时把当前环境一起注入桥,
app 读写 KV 时服务端按环境路由(不信客户端报的环境,和影子 id 同一个道理)。Promote 时 不搬数据 —— staging 数据是试出来的脏数据,不该带上线。要不要提供"复制一份 live 数据到 staging"当第二步再说。
Jeff 第 5 刀:回滚只想了代码,没想数据
现在的回滚是把指针拨回上一版,一秒完成 —— 对纯 HTML app 很漂亮。 但 v4 要是改了数据结构、写进了新格式,退回 v3 时 v3 未必看得懂。
app 不允许自行做破坏性的数据结构变更。加字段可以,删字段/改语义不行。
以后再建正式的 migration 系统。
判据:回滚必须永远是安全的。只要"回滚可能弄坏数据"成立一次,这颗按钮就没人敢按了 —— 而没人敢按的回滚,等于没有回滚。
⑧ 能力清单与审核规则
Jeff 的第 1 刀和第 3 刀是同一件事的两半:没有能力清单,就没法判断"这一版要不要重新审"。
能力清单(manifest)待做
建 app 时先申报要用哪些:相机 · 位置 · 通知 · 联系人 · 网络域名 · 上传文件 · 支付 · 用户身份。
① manifest 里声明 → ② 审核时人看过 → ③ 运行时用户首次触发才授权
Jeff:「这样你的 App 平台才真正有『操作系统』的感觉,而不是单纯 HTML Hosting。」
审核规则:改掉「以后永远不用审」
| 时机 | 怎么办 | 现在 |
|---|---|---|
| 每一个版本 | 自动安检(禁外链、禁执行外来代码、zip 炸弹、路径穿越) | 已落地 |
| 第一次上线 | 管理员人工审 | 已落地 |
| 普通更新 | 直接上线,不卡 | 已落地 |
| 新增敏感能力 / 新域名 / 新数据能力 | 重新进审核 | 待做 |
| 安检扫出异常 | 重新进审核 | 待做 |
所以第 1 刀真正缺的只有最后两行:能力变化和安检异常要能把这一版推回审核队列。 而这需要先有 manifest,所以两刀一起做。
⑨ 事件与 Pulse
要落进房的事件(系统消息形态):
| 事件 | 房里长什么样 | 触发 |
|---|---|---|
| 传了新版 | 🧪 v4 传上来了 · 谁 · [试试看] | codeUpload 成功后 |
| 上线 | 🚀 v4 上线了(原 v3)· 谁按的 · [打开] | promote 成功后 |
| 退回 | ↩️ 退回 v3(从 v4)· 谁按的 | rollback 成功后 |
| 审核有结果 | 只发给 Owner,而且不抄理由进房 | 管理员审核后 |
Jeff 拍的:不算未读,但要有 Pulse
app 的动静走另一个很轻的指示:💓 3(这个 app 有 3 个新动作)。
Jeff:「不要因为 v7 uploaded / v7 staged / v7 live 搞三个聊天未读,这样会烦死人。」
判据:事件条要像同事说话,不像监控告警 —— 一天刷屏三十条,人就把房静音了,这条线就白做了。
⑩ 角色与权限
| 角色 | 能做 | 不能做 |
|---|---|---|
| Owner | 全部 | — |
| Publisher(先=Owner) | Promote / Rollback | 改能力申报 |
| Developer / AI Agent | 改 → Upload → Staging → Test | 永远不能 Promote Live |
| Viewer(房里其他人) | 打开 · 试 Staging · 分享 | 传包 / 上线 |
我加一句判据:AI 能把东西做出来,但"要不要让全世界看到"永远是人的决定。
我读代码核过:
canManage 现在是「owner 或任何 is_agent 账号」——
我此刻就能改任何人的 app,不需要谁授权。今天所有 app 都是我们自己的,没事;
工作室一拉进外人的 AI,这就是事故。要先收窄,再画那些按钮。而
bindAppWorkroom 的注释白纸黑字写着「照 games 判据:新房 + 本人建 + 唯一索引兜底」——
图纸诚实,注释在撒谎,而改代码的人看的是注释。⑪ 分阶段(按 Jeff 的排法)
他说:「你现在文件已经把权限漏洞列为 P0,这个判断是正确的,只是我会把上面两个安全基础一起塞进 P0。」
| 阶段 | 做什么 | 为什么在这儿 |
|---|---|---|
| P0 · 安全地基 | ① 收窄分身权限 ② Staging 数据隔离(加 env 列)③ 能力变化触发复审(要先有 manifest)④ 绑房补"新房"检查 ⑤ 改掉那句撒谎的注释 | 这五件不做完,后面每一颗按钮都是给开着的门画把手 |
| P1 · 开发者中心 | app 列表 + 单 app 一页(含 Secrets / Logs / 能力) | 七件套后端都在,缺的是让人点得到 |
| P2 · Open Studio | 那一颗按钮:第一次建、以后进 | 有了中心才有地方放它 |
| P3 · 房顶三句话 | 什么版本 / 刚发生什么 / 我能做什么 | 轻的先上,别一上来就 Dashboard |
| P4 · 事件 + Pulse | 传包/上线/退回落进房 + 💓 计数 | 这条通了房才和 app 有关系 |
| P5 · 房内动手 | Upload / Test / Promote(Owner) | 要 P0 的权限收窄先落地才敢开 |
⑫ 你拍的板(四件,已落进上面)
① 建工作室只留一条路 —— YES
而且界面上不出现「绑定工作室」,只出现「Open Studio」:第一次按 = 创建,以后按 = 进入。 用户不需要知道底下有 workroom_id。已写进第 ④ 格
② 房里谁能上线 —— MVP 只有 Owner
但数据库留角色位,不写死 owner。AI 最多做到 Test,永远不能 Promote Live。 已写进第 ⑩ 格
③ 第二期换不换房 —— 绝对不换
你比我原来的提议更坚定:房是这个 app 的大脑和记忆,v1 到 v10、第二期第三期全在里面。 要分阶段用 Milestone / Task / Release 去区分,不是换房。已写进第 ① 格的概念表
④ 事件算不算未读 —— 不算,但加 Pulse
聊天红点只留给"人说话 / @你 / 任务要你处理";app 的动静走 💓 计数。 已写进第 ⑨ 格