Files

1 line
17 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "chasingwind-z/yidanshi", "files": {"docs/multi-tenant-design.md": {"745529995cee9070251df9bf620520bcd7743b81": {"t": 1785747376.7065654, "n": 4279, "h": "61e9104483784281", "c": "# 多租户改造设计(备用蓝图 · 只设计未动工)\n\n> 2026-07-22 立此存照。触发条件:小红书宣发后「多人版内测」呼声达标(点赞过 X 钩子)。\n> 在那之前**不动工**——别为还不存在的用户先付四笔账(改造/成本/合规/定位)。\n> 总原则(zzf 拍板):**zzf 出基建(容器/MySQL/COS/抠图配额),用户自带 AI(BYOK:\n> 自己配 LLM/生图 key)**。使用说明与设置界面按此重点设计(§5/§6)。\n\n## 0. 模式定位\n\n- **小程序云端 = 多租户**:任何人打开即自动拥有自己的厨房(openid 即身份,零注册)。\n- **Web/本地 = 自托管单用户**:文件模式一字不动,保留开源故事(\"数据在自己手里\")。\n- 两模式一套代码,env 开关 `YIDANSHI_MULTI_TENANT=1`(只在云端开)。\n\n## 1. 责任分界(BYOK 核心)\n\n| 项 | 谁出 | 说明 |\n|---|---|---|\n| 容器/MySQL/COS 存储 | zzf | 配额内免费给用户 |\n| 抠图(阿里云 SegmentFood) | zzf | **每厨房每日限额**(如 5 张),超额自动降级圆框直裁(现成兜底) |\n| AI 文字(整理菜谱/AI 每日荐/食材百科生成) | **用户 key** | 无 key 全部优雅降级(§4 表),app 照常可用 |\n| AI 生图(插画教程卡生成) | **用户 key** | 贵(Seedream ~0.3 元/张),必须 BYOK |\n| 点菜提醒(Server酱) | **用户 key** | 每厨房自己的 SENDKEY,与 BYOK 同一哲学 |\n\n**无 key 降级表(设计底线:不配任何 key 也是完整可用的记录 App)**\n\n| 功能 | 有 key | 无 key |\n|---|---|---|\n| 记菜/记餐/点菜/长图/教程卡导出 | ✓ | ✓(完全一样) |\n| 每日荐 | AI 朱批理由 | 规则版理由(现成,零成本) |\n| 贴链接 AI 整理成菜谱 | ✓ | 手动录入(表单现成) |\n| 食材小百科 | AI 生成并缓存 | 内置 187 条营养库照查 |\n| 插画生成 | ✓ | 无插画,教程卡照出(版式自适应) |\n\n## 2. 数据模型\n\n- 新表 `kitchens`:`openid PK / created / name(默认\"某某的小厨房\"可改)/ guest_token /\n ai_config(JSON 加密,见 §4)/ serverchan_key(加密)/ quota 计数列(今日抠图数、照片总数)`。\n- `recipes / meals / kvdocs` 各加 `owner_openid` 列 + 联合索引 `(owner_openid, id)`;\n kvdocs 主键改 `(owner_openid, name)`。\n- 文件模式(自托管)不加列不迁移——单用户语义天然成立,storage 双实现继续 parity。\n- 迁移:现库数据全部归 zzf openid(一条 UPDATE);zzf 的厨房就是第一个租户。\n\n## 3. 鉴权改造\n\n- `owner_gate` 退役,换 `identity` 中间件:从 `X-WX-OPENID` 得出「当前厨房」,\n 所有读写自动圈定 `owner_openid=me`——**锁从\"门\"变成\"分户\"**,不再需要\n `YIDANSHI_OWNER_OPENID`(退役为迁移标记)。\n- 客人链路不变但 per-kitchen:`/api/guest/*?t=` 与图片通道 `?t=` 先查 t 属于哪个厨房,\n 数据圈到该厨房。客人可同时存多家口令(miniapp storage 存 `{token, 厨房名}` 列表,\n 「去点菜」入口变成多家选择——解你说的\"只能看一个人的菜单\")。\n- h5/无 openid 请求:多租户模式下只放 guest 链路,管理接口 403(云端 web 管理不开放)。\n\n## 4. BYOK AI 设计\n\n- per-kitchen `ai_config`:`{llm: {preset, base_url, model, api_key}, imagegen: {...}}`。\n- **key 加密落库**:Fernet 对称加密,主密钥 `YIDANSHI_MASTER_KEY` 只在云端 env(zzf 掌管);\n API 永不回显完整 key,只回 `sk-…尾4位`;日志全链路禁 print key。\n- llm.py/imagegen.py 从「进程级配置」改「每请求带厨房配置」——调用签名加 `cfg` 参数,\n 自托管模式仍读全局配置(兼容不破)。\n- **预设通道菜单**(降低配置门槛,选预设只填一个 key):\n DeepSeek(推荐首选,注册送额度,自用每月几毛钱)/ Kimi / 智谱 GLM / 通义 /\n 自定义 OpenAI 兼容(base_url+model 全手填)。\n- **「测一测」**:`POST /api/ai/test` 用当前配置真实调一次(限频 1 次/10 秒),\n 回耗时 + 模型回声 + 失败原文(脱敏 key),让用户配完 10 秒内知道通没通。\n- AI 每日荐缓存改 per-kitchen;无 key 厨房直接走规则版不进冷却逻辑。\n\n## 5. 设置界面设计(重点,纸上视觉不变)\n\n设置页重排为六个纸卡区块,自上而下:\n\n1. **我的厨房**:厨房名(默认\"微信昵称的小厨房\",可改,用于长图题签/点菜页抬头)。\n2. **AI 通道**(核心区块):\n - 预设选择:五张小卡横滑(DeepSeek 卡标「推荐 · 注册送额度」章);\n - key 输入框(密文回显尾 4 位)+ 每个预设配一行**去哪拿 key**:\n 「深度求索开放平台注册 → API Keys → 复制」+ 一句费用预期:\n 「自用大约每月几毛钱,充 10 元管一年」;\n - **[测一测]**按钮 + 状态行(「✓ 通了,1.2 秒」/ 失败原文);\n - 降级说明一行小字:「不配也完全能用:AI 理由换成规则版、菜谱手动录入」。\n3. **插画生图**(可选,折叠收起):同构;顶部一句「生成整套插画约 1.8 元/道菜,\n 丰俭由人」——诚实报价是信任的一部分。\n4. **家人点菜与提醒**:点菜卡片(现有)+ Server酱 SENDKEY 输入(配了才有微信提醒,\n 附「sct.ftqq.com 扫码即得」一行)。\n5. **额度**:「今日抠图 2/5 · 照片 37/500」进度条式一行——透明比隐藏好。\n6. **说明书与数据**:「使用说明 ›」入口 +「导出我的数据」+「注销并删除所有数据」\n (合规必备,二次确认)。\n\n文案纪律:说明性文字平实直述(说明书不用朱批腔);不夸大(\"几毛钱\"要真是几毛钱);\n每个需要用户掏钱/注册的地方,先讲为什么(\"AI 的账单跟着你的 key 走,你的用量你做主\")。\n\n## 6. 使用说明页(新页面「说明书」,从设置进)\n\n大纲(手账排版,每节一张纸卡):\n\n1. **三分钟上手**:记一道菜 → 拍照抠图 → 记一餐 → 翻牌子/今日荐。\n2. **为什么 AI 要自己配 key**:诚实三句——这是个人开发者维护的免费 App;\n 服务器/存储/抠图我请客;AI 按用量计费、跟着你的 key 走,你的用量你做主。\n3. **免费与自费对照表**(§1 降级表的用户版)。\n4. **家人点菜怎么玩**:发卡片 → 家人点菜留讲究 → 你收微信提醒(配 Server酱)。\n5. **隐私承诺**:你的食单只有你和你发过卡片的人可见;key 加密存储、只用于你自己的\n 请求、随时可删;注销即全删。\n6. **常见问题**:图片不显示(网络)/ AI 没反应(key 没配或欠费)/ 找不到点菜入口。\n\n## 7. UGC 合规与滥用防护\n\n- **内容安全(微信硬要求,有 UGC 必接)**:照片上传过 `imgSecCheck`、菜名/备注/点单\n 留言过 `msgSecCheck`——需要小程序 **AppSecret** 换 access_token(zzf 亲自填云端 env,\n 沿用\"不经 Claude 手\"纪律)。违规内容拒绝入库并提示。\n- **备案**:正式发布前完成 ICP 备案(个人可办);内测期走体验版免备案。\n- **滥用防护**:内测期厨房总数上限 + 邀请码开通;单厨房配额(菜谱 ≤100 道、\n 照片 ≤500 张、抠图 5 张/日);接口按 openid 限频;「测一测」限频。\n\n## 8. 成本粗估(zzf 侧,100 活跃厨房)\n\nCOS 存储 100×200MB≈20GB ≈ 2 元/月 + 流量看晒图量(约 0.5 元/GB);\nMySQL 现有实例够用;容器按量随请求涨(估 <30 元/月);抠图限额内 100×5×30=1.5 万张/月\n上限(实际远低),阿里云单价 ~0.003 元/张 ≈ 封顶 45 元/月。**量级:百元内/月**,\n超预算就收紧配额——所有阀门都在 zzf 手里。\n\n## 9. 分期\n\n- **M0**:本设计定稿(本文档)+ 呼声钩子发帖验证需求。\n- **M1**(约 1-2 个会话):数据模型迁移 + identity 中间件 + parity/回归。\n- **M2**(约 1 个会话):BYOK(加密/预设/测一测)+ 设置页/说明书两页。\n- **M3**:内容安全接入 + 邀请码内测(体验版渠道)+ 备案启动。\n- **M4**:提审正式发布。\n\n## 10. 未决问题\n\n- 厨房发现机制:完全私密(现设计)vs 允许\"逛别人家\"(社交化,倾向不做——红海+审核重)。\n- Web 管理端要不要多租户版(现设计:不做,Web 专属自托管)。\n- 客人多家口令列表的 UI(多家点菜切换器)细节,实现时定。\n"}, "f6285fe6f8b31ba01592e93ac077c090987aa4da": {"t": 1785772926.382092, "n": 4279, "h": "61e9104483784281", "c": "# 多租户改造设计(备用蓝图 · 只设计未动工)\n\n> 2026-07-22 立此存照。触发条件:小红书宣发后「多人版内测」呼声达标(点赞过 X 钩子)。\n> 在那之前**不动工**——别为还不存在的用户先付四笔账(改造/成本/合规/定位)。\n> 总原则(zzf 拍板):**zzf 出基建(容器/MySQL/COS/抠图配额),用户自带 AI(BYOK:\n> 自己配 LLM/生图 key)**。使用说明与设置界面按此重点设计(§5/§6)。\n\n## 0. 模式定位\n\n- **小程序云端 = 多租户**:任何人打开即自动拥有自己的厨房(openid 即身份,零注册)。\n- **Web/本地 = 自托管单用户**:文件模式一字不动,保留开源故事(\"数据在自己手里\")。\n- 两模式一套代码,env 开关 `YIDANSHI_MULTI_TENANT=1`(只在云端开)。\n\n## 1. 责任分界(BYOK 核心)\n\n| 项 | 谁出 | 说明 |\n|---|---|---|\n| 容器/MySQL/COS 存储 | zzf | 配额内免费给用户 |\n| 抠图(阿里云 SegmentFood) | zzf | **每厨房每日限额**(如 5 张),超额自动降级圆框直裁(现成兜底) |\n| AI 文字(整理菜谱/AI 每日荐/食材百科生成) | **用户 key** | 无 key 全部优雅降级(§4 表),app 照常可用 |\n| AI 生图(插画教程卡生成) | **用户 key** | 贵(Seedream ~0.3 元/张),必须 BYOK |\n| 点菜提醒(Server酱) | **用户 key** | 每厨房自己的 SENDKEY,与 BYOK 同一哲学 |\n\n**无 key 降级表(设计底线:不配任何 key 也是完整可用的记录 App)**\n\n| 功能 | 有 key | 无 key |\n|---|---|---|\n| 记菜/记餐/点菜/长图/教程卡导出 | ✓ | ✓(完全一样) |\n| 每日荐 | AI 朱批理由 | 规则版理由(现成,零成本) |\n| 贴链接 AI 整理成菜谱 | ✓ | 手动录入(表单现成) |\n| 食材小百科 | AI 生成并缓存 | 内置 187 条营养库照查 |\n| 插画生成 | ✓ | 无插画,教程卡照出(版式自适应) |\n\n## 2. 数据模型\n\n- 新表 `kitchens`:`openid PK / created / name(默认\"某某的小厨房\"可改)/ guest_token /\n ai_config(JSON 加密,见 §4)/ serverchan_key(加密)/ quota 计数列(今日抠图数、照片总数)`。\n- `recipes / meals / kvdocs` 各加 `owner_openid` 列 + 联合索引 `(owner_openid, id)`;\n kvdocs 主键改 `(owner_openid, name)`。\n- 文件模式(自托管)不加列不迁移——单用户语义天然成立,storage 双实现继续 parity。\n- 迁移:现库数据全部归 zzf openid(一条 UPDATE);zzf 的厨房就是第一个租户。\n\n## 3. 鉴权改造\n\n- `owner_gate` 退役,换 `identity` 中间件:从 `X-WX-OPENID` 得出「当前厨房」,\n 所有读写自动圈定 `owner_openid=me`——**锁从\"门\"变成\"分户\"**,不再需要\n `YIDANSHI_OWNER_OPENID`(退役为迁移标记)。\n- 客人链路不变但 per-kitchen:`/api/guest/*?t=` 与图片通道 `?t=` 先查 t 属于哪个厨房,\n 数据圈到该厨房。客人可同时存多家口令(miniapp storage 存 `{token, 厨房名}` 列表,\n 「去点菜」入口变成多家选择——解你说的\"只能看一个人的菜单\")。\n- h5/无 openid 请求:多租户模式下只放 guest 链路,管理接口 403(云端 web 管理不开放)。\n\n## 4. BYOK AI 设计\n\n- per-kitchen `ai_config`:`{llm: {preset, base_url, model, api_key}, imagegen: {...}}`。\n- **key 加密落库**:Fernet 对称加密,主密钥 `YIDANSHI_MASTER_KEY` 只在云端 env(zzf 掌管);\n API 永不回显完整 key,只回 `sk-…尾4位`;日志全链路禁 print key。\n- llm.py/imagegen.py 从「进程级配置」改「每请求带厨房配置」——调用签名加 `cfg` 参数,\n 自托管模式仍读全局配置(兼容不破)。\n- **预设通道菜单**(降低配置门槛,选预设只填一个 key):\n DeepSeek(推荐首选,注册送额度,自用每月几毛钱)/ Kimi / 智谱 GLM / 通义 /\n 自定义 OpenAI 兼容(base_url+model 全手填)。\n- **「测一测」**:`POST /api/ai/test` 用当前配置真实调一次(限频 1 次/10 秒),\n 回耗时 + 模型回声 + 失败原文(脱敏 key),让用户配完 10 秒内知道通没通。\n- AI 每日荐缓存改 per-kitchen;无 key 厨房直接走规则版不进冷却逻辑。\n\n## 5. 设置界面设计(重点,纸上视觉不变)\n\n设置页重排为六个纸卡区块,自上而下:\n\n1. **我的厨房**:厨房名(默认\"微信昵称的小厨房\",可改,用于长图题签/点菜页抬头)。\n2. **AI 通道**(核心区块):\n - 预设选择:五张小卡横滑(DeepSeek 卡标「推荐 · 注册送额度」章);\n - key 输入框(密文回显尾 4 位)+ 每个预设配一行**去哪拿 key**:\n 「深度求索开放平台注册 → API Keys → 复制」+ 一句费用预期:\n 「自用大约每月几毛钱,充 10 元管一年」;\n - **[测一测]**按钮 + 状态行(「✓ 通了,1.2 秒」/ 失败原文);\n - 降级说明一行小字:「不配也完全能用:AI 理由换成规则版、菜谱手动录入」。\n3. **插画生图**(可选,折叠收起):同构;顶部一句「生成整套插画约 1.8 元/道菜,\n 丰俭由人」——诚实报价是信任的一部分。\n4. **家人点菜与提醒**:点菜卡片(现有)+ Server酱 SENDKEY 输入(配了才有微信提醒,\n 附「sct.ftqq.com 扫码即得」一行)。\n5. **额度**:「今日抠图 2/5 · 照片 37/500」进度条式一行——透明比隐藏好。\n6. **说明书与数据**:「使用说明 ›」入口 +「导出我的数据」+「注销并删除所有数据」\n (合规必备,二次确认)。\n\n文案纪律:说明性文字平实直述(说明书不用朱批腔);不夸大(\"几毛钱\"要真是几毛钱);\n每个需要用户掏钱/注册的地方,先讲为什么(\"AI 的账单跟着你的 key 走,你的用量你做主\")。\n\n## 6. 使用说明页(新页面「说明书」,从设置进)\n\n大纲(手账排版,每节一张纸卡):\n\n1. **三分钟上手**:记一道菜 → 拍照抠图 → 记一餐 → 翻牌子/今日荐。\n2. **为什么 AI 要自己配 key**:诚实三句——这是个人开发者维护的免费 App;\n 服务器/存储/抠图我请客;AI 按用量计费、跟着你的 key 走,你的用量你做主。\n3. **免费与自费对照表**(§1 降级表的用户版)。\n4. **家人点菜怎么玩**:发卡片 → 家人点菜留讲究 → 你收微信提醒(配 Server酱)。\n5. **隐私承诺**:你的食单只有你和你发过卡片的人可见;key 加密存储、只用于你自己的\n 请求、随时可删;注销即全删。\n6. **常见问题**:图片不显示(网络)/ AI 没反应(key 没配或欠费)/ 找不到点菜入口。\n\n## 7. UGC 合规与滥用防护\n\n- **内容安全(微信硬要求,有 UGC 必接)**:照片上传过 `imgSecCheck`、菜名/备注/点单\n 留言过 `msgSecCheck`——需要小程序 **AppSecret** 换 access_token(zzf 亲自填云端 env,\n 沿用\"不经 Claude 手\"纪律)。违规内容拒绝入库并提示。\n- **备案**:正式发布前完成 ICP 备案(个人可办);内测期走体验版免备案。\n- **滥用防护**:内测期厨房总数上限 + 邀请码开通;单厨房配额(菜谱 ≤100 道、\n 照片 ≤500 张、抠图 5 张/日);接口按 openid 限频;「测一测」限频。\n\n## 8. 成本粗估(zzf 侧,100 活跃厨房)\n\nCOS 存储 100×200MB≈20GB ≈ 2 元/月 + 流量看晒图量(约 0.5 元/GB);\nMySQL 现有实例够用;容器按量随请求涨(估 <30 元/月);抠图限额内 100×5×30=1.5 万张/月\n上限(实际远低),阿里云单价 ~0.003 元/张 ≈ 封顶 45 元/月。**量级:百元内/月**,\n超预算就收紧配额——所有阀门都在 zzf 手里。\n\n## 9. 分期\n\n- **M0**:本设计定稿(本文档)+ 呼声钩子发帖验证需求。\n- **M1**(约 1-2 个会话):数据模型迁移 + identity 中间件 + parity/回归。\n- **M2**(约 1 个会话):BYOK(加密/预设/测一测)+ 设置页/说明书两页。\n- **M3**:内容安全接入 + 邀请码内测(体验版渠道)+ 备案启动。\n- **M4**:提审正式发布。\n\n## 10. 未决问题\n\n- 厨房发现机制:完全私密(现设计)vs 允许\"逛别人家\"(社交化,倾向不做——红海+审核重)。\n- Web 管理端要不要多租户版(现设计:不做,Web 专属自托管)。\n- 客人多家口令列表的 UI(多家点菜切换器)细节,实现时定。\n"}}}}