12 KiB
12 KiB
Spec Kit Overview
本文件用于简短记录当前项目每个 spec 的核心内容摘要,便于快速总览与追踪变更。
Client Bootstrap
- 目标:初始化正念 APP 客户端工程规范,确保可运行、可切环境、可多语言扩展、目录标准化、可 EAS 打包
- 核心范围:客户端工程骨架与文档(
client/README.md)、环境变量约定、i18n(CN/EN/ES/PT/TC)、推送/小组件/卡片滑动的一期能力约束 - 主要约定:
- 环境:
.env.dev/.env.prod,推荐EXPO_PUBLIC_前缀 - 语言码:
zh-CN/en/es/pt/zh-TW - 目录:
app/(可选 expo-router)+src/(features/services/store/utils 等)+assets/ - 打包:EAS Build,dev/prod bundle id 约定
- 环境:
- 阶段产物:
spec_kit/Client Bootstrap/spec.mdspec_kit/Client Bootstrap/plan.mdspec_kit/Client Bootstrap/tasks.md
- 已完成编码(阶段性):
- Expo 工程已在
client/初始化,并完成pnpm install - i18n 基座已接入:5 份语言资源 + 设备语言优先/设置可切换/持久化 + 入口初始化
- 推荐 Feed 请求链路增加调试日志(仅开发环境):打印 Feed API 请求头与请求体,便于联调排查
- 环境变量注入增加调试日志(仅开发环境):打印参与
API_BASE_URL计算的EXPO_PUBLIC_*与最终解析结果,便于定位“打到哪个后端”
- Expo 工程已在
Client User Identity
- 目标:在无账号体系或账号可选的前提下,为客户端建立稳定的
client_user_id,用于与 APNs/FCM 的 Push Token 做绑定,支撑精准推送与 Token 变更更新 - 关键结论:
client_user_id使用**随机 UUID(默认 UUID v4)**合适;将其视为不透明字符串,不使用可追踪设备硬件标识 - 阶段产物:
spec_kit/Client User Identity/spec.md
App Push
- 目标:实现“每日提醒”推送闭环:首次进入 Onboarding 可选择每日推送次数(0~5,可跳过),个人主页每日提醒弹窗可改次数/关闭;客户端使用首次生成 UUID(
client_user_id)与后端关联;后端按用户配置定时推送 - 关键选型:客户端继续使用
expo-notifications;后端使用 Expo Push Service + 定时任务(Celery/等价方案)按用户偏好发送 - 阶段产物:
spec_kit/App Push/spec.mdspec_kit/App Push/plan.mdspec_kit/App Push/tasks.md
- 已完成编码(阶段性):
- 客户端:新增
client_user_id(UUID v4)生成与持久化;每日提醒次数范围修正为 0~5(0 表示关闭) - 客户端:Onboarding 结束页(每日提醒)在用户选择次数 > 0 时直接触发系统权限申请;授权后获取 Expo Push Token 并调用后端
register/preferences(移除单独的 push 引导页) - 客户端:个人主页“每日提醒”弹窗移除测试模式强制无权限逻辑,改为真实读取系统权限;并在开关/点击 OK 时同步后端偏好
- 客户端:新增推送接口封装
client/src/services/pushApi.ts(token 获取、register/preferences/get、自动上报时区与 locale,并携带用户画像供后端 Push 模板使用) - 后端:新增 Push 数据模型 + Alembic 迁移(
push_tokens/push_preferences/push_send_log) - 后端:新增 Push API(
/v1/push/register、/v1/push/preferences、/v1/push/test(dev)),并新增基础限流 - 后端:实现 Celery 定时任务
- 每日生成计划(按用户时区在 9:00~24:00 均匀分段随机抖动生成 0~5 个时间点)
- ETA 发送任务(幂等:同一用户同一天同一 slot 只发一次;用户中途关闭/降次数会跳过)
- 发送文案复用推荐模块
scene="push"(降风险)
- 后端:
pytest全量通过(27 passed)
- 客户端:新增
Project Bootstrap
- 目标:完成项目仓库初始化与工程约定落地,明确 client/server 结构、dev/pro 环境隔离、MySQL/Redis 资源命名与访问边界
- 核心范围:根目录结构与文档、dev/pro 配置策略、MySQL schema 命名(
mindfulness_dev/mindfulness)、Redis ACL + key 前缀隔离(dev:*/pro:*) - 主要约定:
- MySQL:prod=
mindfulness,dev=mindfulness_dev,统一utf8mb4与 snake_case - Redis:单实例,通过 ACL 限制不同用户只能访问对应前缀;应用侧强制 key 使用
dev:/pro:前缀 - 安全:真实 IP/账号/密码/Token 不写入仓库,仅提供
.env.example结构
- MySQL:prod=
- 阶段产物:
spec_kit/Project Bootstrap/spec.md
- 近期变更:
- 新增后端镜像构建基础:
server/Dockerfile、server/.dockerignore - 新增后端镜像打包与推送工作流:
.gitea/workflows/server-build.yml(自动递增 semver tag 并推送到 Docker Hub) - 新增后端蓝绿部署工作流:
.gitea/workflows/server-deploy.yml(SSH 上机 + Docker 蓝绿启动 + Nginx upstream 切流 + 健康检查与失败回滚) - 后端配置缺失时报错增强:
app/core/config.py将缺失的必填环境变量用中文提示并给出注入方式;补充server/env.example与 Docker 运行说明
- 新增后端镜像构建基础:
Onboarding App Shell
- 目标:落地首次进入体验(Onboarding 3–5 页可跳过 + 每日提醒可跳过/可关闭)与主应用壳(点赞/讨厌、收藏夹入口、通用设置入口)
- 核心范围:Onboarding 多页流程、主界面反应操作(Like/Dislike)、收藏夹、设置页(版本、iOS 小组件入口/说明)
- 阶段产物:
spec_kit/Onboarding App Shell/spec.mdspec_kit/Onboarding App Shell/plan.mdspec_kit/Onboarding App Shell/tasks.md
iOS Widget
- 目标:实现真正的 iOS 桌面小组件(WidgetKit Extension),展示美观文案并与 App 共享数据
- 核心范围:WidgetKit 扩展、App Group 数据共享、尺寸适配(Small/Medium/Large)、点击跳转回 App
- 阶段产物:
spec_kit/iOS Widget/spec.mdspec_kit/iOS Widget/plan.mdspec_kit/iOS Widget/tasks.md
- 近期变更:
- iOS 主 App Bundle ID 已统一为
com.damer.mindfulness,Widget Extension 为com.damer.mindfulness.emotionwidget - 修复 iOS 签名 Team 配置不一致:为主 App(Debug)与 Widget Extension(Debug/Release)显式补齐
DEVELOPMENT_TEAM=WS92GPX9H2,避免打包/上传过程中回退到默认 Team 导致显示 “Other Team” - iOS 构建号已提升到
2,并将client/ios/client/Info.plist改为自动跟随MARKETING_VERSION/CURRENT_PROJECT_VERSION - 推送 entitlements 的
aps-environment已切到production(用于 TestFlight/线上包) - 清理未接入编译的 WidgetKit 骨架残留:移除磁盘上的
client/ios/MindfulnessWidget/文件,并从client/ios/client.xcodeproj/project.pbxproj删除对应工程引用(避免 Xcode 显示幽灵文件)
- iOS 主 App Bundle ID 已统一为
Splash Consent
- 目标:实现开屏页(使用
client/assets/images/index/图片资源),首次加载展示渐变同意按钮并提供隐私/协议入口 - 核心范围:开屏 UI、首次同意状态持久化(
consent.accepted)、点击同意后进入后续 Onboarding/App 流程 - 阶段产物:
spec_kit/Splash Consent/spec.mdspec_kit/Splash Consent/plan.mdspec_kit/Splash Consent/tasks.md
Policy Links
- 目标:在客户端首次进入同意页底部补充「隐私协议/用户使用协议」入口,并将协议链接改为由后端托管与按设备语言下发(默认回退 EN)
- 核心范围:后端提供协议链接下发接口(可配置、可多语言);客户端按设备语言请求并展示链接,失败不阻塞“同意并继续”
- 阶段产物:
spec_kit/Policy Links/spec.mdspec_kit/Policy Links/plan.mdspec_kit/Policy Links/tasks.md
- 已完成编码(任务清单已执行完毕):
- 后端新增
GET /v1/legal/links(按Accept-Language分发,默认回退 EN,返回resolvedLang) - 后端配置:
LEGAL_*环境变量(server/env.example已补齐示例;不配置时走内置协议页兜底) - 后端新增内置协议内容页:
GET /v1/legal/privacyGET /v1/legal/terms
- 客户端新增协议接口封装
client/src/services/legalApi.ts - 客户端工程化:新增统一 HTTP 封装
client/src/utils/http.ts(baseURL/超时/JSON/统一错误),并将legalApi.ts/recoApi.ts接入 - 客户端接入两处入口:
app/(splash)/splash.tsx、components/home/ProfileModal.tsx - 变更文件清单:
server/app/api/v1/legal.pyserver/app/core/config.pyserver/app/legal_docs.pyserver/app/main.pyserver/env.exampleserver/tests/test_legal_links_unittest.pyclient/src/services/legalApi.tsclient/src/services/__tests__/legalApi.test.tsclient/app/(splash)/splash.tsxclient/components/home/ProfileModal.tsxspec_kit/Policy Links/spec.mdspec_kit/Policy Links/plan.mdspec_kit/Policy Links/tasks.md
- 后端新增
Card UI
- 目标:优化卡片页 UI 与交互,支持右上角主题切换与个人主页弹窗,并将喜欢/讨厌改为 icon + 动效
- 核心范围:
- 系统导航栏右上角两个圆形 icon:主题(
theme.svg)/ 我的(my.svg) - 底部上拉弹窗(Sheet):统一内容区背景
#FAF3EC,点 X 关闭 - 主题两种模式:
scenery/color(本期最少影响 Home 页面背景),并持久化ui.theme.mode - 喜欢/讨厌按钮:使用
like.svg/hate.svg,喜欢提供“心形填满”强反馈动效(like_filled.svg) - 每日提醒弹窗:次数 +/-、Push 提醒开关、渐变 Ok 按钮,并持久化设置
- 系统导航栏右上角两个圆形 icon:主题(
- 阶段产物:
spec_kit/Card UI/spec.mdspec_kit/Card UI/plan.mdspec_kit/Card UI/tasks.md
- 已完成编码(阶段性):
- 已接入
react-native-svg-transformer+client/metro.config.js - 新增
SheetModal、ThemeModal、ProfileModal并在 Home 中接入 - 新增
DailyReminderModal并从个人主页弹窗打开 - Home:右上角 icon 按钮、主题切换背景、喜欢/讨厌 icon + 动效
- 修复:收藏(“我的喜欢”)不展示后端推荐文案的问题——收藏时持久化写入
text快照,并在ProfileModal的 Favorites 页面同时兼容 Mock 与推荐缓存内容回填
- 已接入
User Profile Scoring
- 目标:将 Onboarding 问卷答案映射为标准化“用户画像 U”,并输出硬规则与置信度元信息,供推荐/Push 等模块统一复用
- 核心范围:mom_stage(离散)、emotion_score(0–1 连续)、context(离散)、need(离散)四维度;以及
profile_version/source/generated_at/confidence(V1.1) - 主要约定:
- 输出结构稳定可版本化,便于规则演进
- 支持题目可跳过:新增
profile_answered标记各题是否作答;字段缺失时由推荐算法走“通用值 + 不确定性惩罚” - mom_stage 跳过按安全策略视为
unknown(用于避免冒犯),emotion/context/need 跳过不强行填默认值 - 置信度
conf_U= 时间衰减 × 作答完整度(答得越少越不确定),用于推送场景降个性化/降风险 - 硬规则优先于任何分数计算:
unknown仅在“育儿压力且强个性化(personalization_power=1)”时禁推;block_health_medical全场景硬过滤
- 测试覆盖:提供“输入题目答案 → 输出用户画像”的回归用例,覆盖字段映射、置信度衰减与硬规则触发(可选但建议)
- 阶段产物:
spec_kit/User Profile Scoring/spec.md
- 已完成编码(阶段性):
- 客户端 Onboarding 完成时已收集问卷答案并生成用户画像,写入本地存储供推荐/Push/Widget 复用