This commit is contained in:
吕新雨
2026-01-28 20:50:17 +08:00
commit 049995692d
27 changed files with 1661 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
# Project Bootstrap技术计划
## 1. 目标与约束(来自 spec
- 目标完成项目初始化可落地的工程与基础设施约定client/server + dev/prod 隔离 + MySQL/Redis 命名与访问边界)。
- 关键选择:
- 后端依赖:`requirements.txt` + `pip`
- 定时/异步Celery + Redis
- 环境:仅 dev / prod
- Redis 隔离ACL + key 前缀(`dev:*` / `pro:*`
- 部署:**不在本需求中提供 Docker 起 MySQL/Redis**MySQL/Redis 已部署),后端通过环境变量连接
- 数据库迁移Alembic
- Redis 生产环境:**maxmemory=256MB 硬限制**
## 2. 总体方案
### 2.1 MySQLschema 隔离)
- prod schema`mindfulness`
- dev schema`mindfulness_dev`
- 字符集:`utf8mb4`
- 连接方式:后端通过 `DATABASE_URL`SQLAlchemy Async连接到对应 schema
### 2.2 RedisACL + 前缀隔离 + 内存限制)
- 单 Redis 实例(同机同容器可行)。
- 通过 **ACL 用户**限制不同环境只能访问各自前缀:
- dev 用户:只能访问 `dev:*`
- prod 用户:只能访问 `pro:*`
- 应用侧硬约束:所有 Redis key 必须带环境前缀(`dev:` / `pro:`)。
- 生产 maxmemory`256mb`,并采用“少用 Redis、短 TTL、避免任务积压”的策略。
> 重要Celery broker 以“可靠投递”为优先,计划中默认 **不启用** Celery result backend或启用时必须设置 TTL
### 2.3 运行方式(不限定部署形态)
本需求只要求:
- MySQL 与 Redis **已可访问**
- 后端通过 `.env.dev/.env.prod`(或等价环境变量注入方式)获取连接信息
- API/Celery/Beat 以任意进程管理方式运行Docker/systemd/进程托管均可),但需满足验收项
## 3. 目录与文件落地清单
> 本计划只定义“应该创建/调整什么”,具体文件内容在 tasks 阶段逐项实现。
### 3.1 后端依赖与启动入口server
- `server/requirements.txt`
- `server/app/main.py`FastAPI 入口)
- `server/app/core/config.py`pydantic-settings`APP_ENV` 加载 `.env.dev/.env.prod`
- `server/app/worker.py`Celery app 入口)
- `server/alembic.ini` + `server/alembic/`(迁移脚手架)
- `server/.env.example`(字段结构,不含真实值)
### 3.2 基础设施infra
本需求不强制创建 `infra/`(因为 MySQL/Redis 已部署)。
可选新增(仅用于“文档化配置/备份参考”,不要求参与部署):
- `infra/redis/users.acl`ACL 用户定义备份)
- `infra/redis/redis.prod.conf`prod 配置备份,包含 maxmemory=256mb
- `infra/mysql/init/00-create-schemas.sql`(创建 `mindfulness_dev/mindfulness` 的 SQL 备份)
## 4. Redis ACL 与 maxmemory 的落地方案
### 4.1 ACL 文件(`infra/redis/users.acl`
> 若 Redis 已在服务器配置完成,本节用于“约定与验收”。
- 定义 `dev_user``pro_user` 两个账号
- 分别限制 key pattern
- dev`~dev:*`
- prod`~pro:*`
- 建议禁用默认用户,避免未授权访问(推荐):`user default off`
### 4.2 Redis 配置(`infra/redis/redis.prod.conf`
> 若 Redis 已在服务器配置完成,本节用于“约定与验收”。
- `maxmemory 256mb`
- `maxmemory-policy noeviction`(队列场景优先“不丢任务”,宁可让写入失败报警)
- 开启 ACL例如 `aclfile .../users.acl`
### 4.3 应用侧约束(在代码实现时落地)
为确保 ACL 真的起作用,需要做到:
- **所有业务 key 带前缀**:例如 `dev:cache:...` / `pro:cache:...`
- **Celery 队列名带前缀**:例如 `dev:push` / `pro:push`
- **禁用或限制 result backend**:默认不启用;如启用必须设置短 TTL例如 1 小时/1 天)
- **任务参数保持小**:只传 id不传长文本/大 payload避免队列膨胀导致 Redis 触顶
## 5. 环境变量与配置约定
### 5.1 后端 `.env.dev/.env.prod`(字段示例)
- `APP_ENV=dev|prod`
- `DATABASE_URL=.../mindfulness_dev`dev`.../mindfulness`prod
- `REDIS_URL=redis://<user>:<pass>@redis:6379/0`
- `CELERY_BROKER_URL=redis://<user>:<pass>@redis:6379/0`
- `CELERY_RESULT_BACKEND`:默认不配置(或仅在 dev 开启)
### 5.2 密钥管理
- `.env.dev/.env.prod` 不进仓库
- 提供 `.env.example` 仅展示字段结构
## 6. 实施步骤(建议顺序)
### 阶段 A验证现有 MySQL/Redis 与隔离策略
- RedisACL 生效验证dev 用户无法访问 `pro:*`prod 用户无法访问 `dev:*`
- Redisprod 配置验证(`maxmemory=256mb` 生效)
- MySQL确认 `mindfulness_dev``mindfulness` 两个 schema 已创建(若未创建则创建)
### 阶段 B后端最小可运行骨架
- `requirements.txt` 固化依赖
- FastAPI 最小健康检查接口(如 `/healthz`
- SQLAlchemy 连接与基础会话
- Alembic 初始化与一次空迁移验证
### 阶段 CCelery 最小闭环
- Celery app 初始化broker 指向 Redis按环境选择 dev_user/pro_user
- 1 个示例任务(例如打印/写库)验证 worker 可消费
- 如需要定时beat 定时触发任务验证
## 7. 验收与自检清单plan 阶段定义)
- **环境隔离**
- dev 连接 `mindfulness_dev`prod 连接 `mindfulness`
- dev 的 Redis 凭证无法读写 `pro:*`,反之亦然
- **资源约束**
- prod Redis `maxmemory=256mb` 生效
- 不启用(或短 TTLresult backend避免长期堆积
- **可运行性**
- FastAPI 能启动并提供基础接口
- Celery worker 能消费任务beat如启用能触发定时任务
## 8. 风险与应对
- Redis 256MB 触顶风险:
- 控制队列积压worker 数量/并发)
- 禁用或缩短结果存储 TTL
- 任务 payload 只传 id
- 多环境同机误用风险:
- 强制不同 ACL 用户 + 前缀
- Celery 队列名带前缀,避免互相消费

View File

@@ -0,0 +1,155 @@
# Project Bootstrap高层规范
## 1. 背景与目标
本需求用于完成「正念 APP」项目的**仓库初始化与工程约定落地**覆盖客户端React Native + Expo与后端FastAPI的基础目录结构、文档、环境区分与基础设施依赖MySQL / Redis隔离策略为一期功能推送、小组件、情绪卡片后续迭代提供稳定底座。
### 目标
- **仓库结构清晰**`client/``server/``infra/``scripts/``.gitea/` 等职责明确
- **环境可区分dev / prod**:客户端与后端均支持 dev/prod 两套配置,不混用资源
- **数据库命名可持续**MySQL schema 命名统一、可扩展、可一键区分环境
- **Redis 隔离可控**:通过 Redis ACL + key 前缀隔离 dev/pro 数据访问,满足同机部署需求
- **文档可执行**:新人按 README 可完成本地启动、配置、联调(允许依赖尚未完全落地时使用占位说明)
### 非目标(本阶段不做)
- 不在本阶段实现完整业务接口与表结构(仅定义约定与边界)
- 不在本阶段实现推送业务全链路(仅确定任务调度与资源隔离策略)
- 不在本阶段完成生产级监控/告警/灰度(后续需求承接)
## 2. 范围与交付物
### 范围
- 仓库根目录结构与职责约定
- 客户端/后端 README 规范化(可运行步骤、配置说明、常见问题)
- dev/prod 环境区分策略(配置文件命名、变量命名、密钥管理)
- MySQL schema 命名约定
- Redis ACL 与 key 前缀隔离约定
### 交付物
- **根 README**:项目概览、目录结构、一期功能说明、技术栈与环境区分说明
- **`client/README.md`**:客户端启动/调试/环境切换/打包规范
- **`server/README.md`**:后端启动/配置/迁移/任务调度Celery说明
- **基础设施约定**(文档层面):
- MySQLschema 命名与字符集约定
- RedisACL 用户与 key 前缀隔离方案dev/pro
## 3. 用户与核心使用场景
- **开发者(单人或小团队)**
- 能快速在本地启动 client/server 并联调
- 能明确 dev/prod 使用的数据库与 Redis 资源不互相污染
- **运维/部署执行者**
- 能根据文档完成最小化部署(即使暂不容器化,也应明确运行依赖)
## 4. 功能需求(高层)
### 4.1 仓库结构与职责边界
- `client/`React Native + Expo 客户端工程
- `server/`FastAPI 后端工程
- `infra/`Docker / k8s / nginx 等基础设施(可后置,但需预留)
- `scripts/`:构建/部署脚本(可后置,但需预留)
- `.gitea/`CI/CD 工作流(可后置,但需预留)
### 4.2 环境区分dev / prod
- **客户端**:使用 `.env.dev` / `.env.prod`,不提交真实 `.env`,提供 `.env.example`
- **后端**:使用 `.env.dev` / `.env.prod`,不提交真实 `.env`,提供 `.env.example`
- **资源隔离原则**
- dev/pro 必须使用**不同的 MySQL schema**
- dev/pro 必须使用**不同的 Redis 访问权限ACL与 key 前缀**
### 4.3 MySQL 命名约定schema / 表 / 字段)
- **schema数据库名**
- prod`mindfulness`
- dev`mindfulness_dev`
- **字符集**:统一 `utf8mb4`
- **命名风格**:统一小写 + 下划线snake_case
- **约束命名**(建议,便于迁移与排障):
- 唯一索引:`uq_<table>_<column>`
- 普通索引:`ix_<table>_<column>`
- 外键:`fk_<fromtable>_<column>__<totable>`
### 4.4 Redis 使用范围与隔离约定
#### 4.4.1 使用范围
- Redis 主要用于:
- Celery broker任务队列
- (可选)短 TTL 缓存
- 约束:
- **不允许**把大对象(长文本/图片/base64直接写入 Redis
- 若启用 Celery 结果存储result backend必须设置 TTL避免无限增长
- 若生产环境有资源限制(例如 `maxmemory=256MB`),需在文档中明确并按“少用、短 TTL、避免积压”的策略执行
#### 4.4.2 dev/pro ACL + key 前缀隔离
Redis 单实例同机部署时,采用 ACL 限制不同环境只能访问自己的 key 前缀:
- dev只能访问 `dev:*`
- prod只能访问 `pro:*`
ACL 规则示例(以 Redis 6+ 为前提):
```text
# Dev 用户,只能访问 dev:* 前缀
user dev_user on >devpassword ~dev:* +@all
# Pro 用户,只能访问 pro:* 前缀
user pro_user on >propassword ~pro:* +@all
```
应用侧约定:
- 所有 Redis key 必须以环境前缀开头dev 用 `dev:`prod 用 `pro:`
- Celery 队列名/键名建议也带环境前缀,避免同机多环境互相影响
## 5. 技术与工程规范(高层)
### 5.1 文档规范
- README 必须包含:
- 环境准备(版本要求)
- 安装依赖与启动命令
- dev/prod 配置与 `.env.example` 说明
- 数据库/缓存/队列依赖说明
- 常见问题与排障建议
### 5.2 密钥与敏感信息管理
- 禁止将真实 IP/账号/密码/Token 写入仓库文档与代码
- 所有敏感信息通过 `.env.dev/.env.prod` 注入
- 仓库仅提供 `.env.example` 展示字段结构
### 5.3 后端 Python 版本与依赖安装方式
- **Python 版本基线**:建议 **Python 3.11+**(与 FastAPI / SQLAlchemy 2.x 异步生态兼容性更好)
- **依赖管理方式(二选一,团队需统一)**
- **方案 A`requirements.txt` + `pip`**
- 安装:`pip install -r requirements.txt`
- 适用:简单直接,适合快速启动与小团队
> 约定:后端 README 需要明确项目采用的方案 A 或方案 B并给出可复制执行的安装与启动命令。
## 6. 验收标准
- 仓库层面:
- 目录结构与根 README 清晰,能让新成员理解项目模块划分
- 环境隔离层面:
- 明确 dev/pro MySQL schema 分别为 `mindfulness_dev``mindfulness`
- 明确 Redis 使用 ACL 限制 dev/pro 前缀访问,并写清 key 前缀约定
- 文档可执行层面:
- `client/README.md``server/README.md` 至少能指导完成“本地启动 + 配置注入”的完整流程(若代码未落地,需明确占位与替换点)
## 7. 风险与注意事项
- Redis 若设置较小 `maxmemory`,在任务积压或无 TTL 的缓存策略下可能触发内存压力,需要通过限流、缩短 TTL、提高消费能力解决
- dev/pro 同机部署时,除 ACL 外还需避免队列名、key 名混用;建议在配置中显式标注环境前缀
- 推送依赖外部网络Expo需在任务侧加入超时与重试策略避免偶发失败导致体验不稳定

View File

@@ -0,0 +1,125 @@
# Project Bootstrap任务清单
> 说明:本清单用于把 `plan.md` 拆成“可逐条执行”的任务。执行完成后请把对应项从 `[ ]` 勾选为 `[x]`。
## 0. 约定与前置
- [ ] **确认后端依赖管理方式**:使用 `requirements.txt + pip`
- [ ] **确认环境**:仅 dev / prod
- [ ] **确认 Redis 方案**:单实例 + ACL`dev:*`/`pro:*`+ prod `maxmemory=256mb`(硬限制)
- [ ] **确认迁移工具**Alembic
- [ ] **确认部署方式**MySQL/Redis 已部署,后端通过环境变量连接(不做 Docker 起 MySQL/Redis
## A. 现有 MySQL/Redis 验证与环境隔离确认
### A1. MySQLschema确认
- [ ] 确认 dev schema`mindfulness_dev` 已存在(字符集 `utf8mb4`
- [ ] 确认 prod schema`mindfulness` 已存在(字符集 `utf8mb4`
### A2. RedisACL + maxmemory=256MB确认
- [ ] 确认 Redis 已启用 ACL并存在账号
- [ ] `dev_user` 仅允许访问 `~dev:*`
- [ ] `pro_user` 仅允许访问 `~pro:*`
- [ ] 确认生产环境 Redis 内存限制:
- [ ] `maxmemory=256mb` 生效
- [ ] `maxmemory-policy=noeviction` 生效(队列优先,不丢任务)
### A3. Redis ACL 验收(必须可复现)
- [ ] 使用 `dev_user` 写入 `dev:test=1` 成功
- [ ] 使用 `dev_user` 写入 `pro:test=1` 失败(权限不足)
- [ ] 使用 `pro_user` 写入 `pro:test=1` 成功
- [ ] 使用 `pro_user` 写入 `dev:test=1` 失败(权限不足)
### A4. 可选:把现有配置“备份到仓库”(不参与部署)
- [ ] (可选)新建 `infra/redis/users.acl`(把线上 ACL 规则复制备份,注意去掉真实密码)
- [ ] (可选)新建 `infra/redis/redis.prod.conf`把线上关键参数备份maxmemory/noeviction/aclfile 等)
- [ ] (可选)新建 `infra/mysql/init/00-create-schemas.sql`(备份 schema 创建脚本)
## B. 后端工程骨架server/)落地
> 当前 `server/` 目录可能尚未创建代码文件,本阶段目标是“能启动、能连库、能跑迁移、能跑 Celery”。
### B1. 依赖与环境变量模板
- [ ] 新增 `server/requirements.txt`
- [ ] FastAPI、uvicorn
- [ ] SQLAlchemy 2.x异步+ MySQL driver`aiomysql`
- [ ] pydantic-settingspydantic v2
- [ ] alembic
- [ ] celery、redisPython 客户端)
- [ ] pytest
- [ ] 新增 `server/.env.example`(仅字段结构,不含真实值)
- [ ] `APP_ENV=dev|prod`
- [ ] `DATABASE_URL=.../mindfulness_dev`dev`.../mindfulness`prod
- [ ] `REDIS_URL=redis://<user>:<pass>@<REDIS_HOST>:6379/0`
- [ ] `CELERY_BROKER_URL=redis://<user>:<pass>@<REDIS_HOST>:6379/0`
- [ ] (默认不写)`CELERY_RESULT_BACKEND`
### B2. FastAPI 最小入口
- [ ] 新增 `server/app/main.py`
- [ ] 创建 FastAPI 实例 `app`
- [ ] 增加健康检查接口 `/healthz`
- [ ] 新增 `server/app/core/config.py`
- [ ] 使用 `pydantic-settings`
- [ ] 根据 `APP_ENV` 加载 `.env.dev` / `.env.prod`
### B3. SQLAlchemy 与数据库连接
- [ ] 新增 `server/app/db/`(目录)
- [ ] 新增 `server/app/db/session.py`
- [ ]`DATABASE_URL` 创建 async engine
- [ ] 提供 session 工厂
### B4. Alembic 初始化
- [ ] 初始化 Alembic
- [ ] 生成 `server/alembic.ini`
- [ ] 生成 `server/alembic/`env.py / versions/
- [ ] 配置从环境变量读取数据库连接
- [ ] 验收:
- [ ] 能执行 `alembic revision -m "init"`(即使空迁移也可)
- [ ] 能执行 `alembic upgrade head`
## C. Celery 最小闭环Redis broker + 队列前缀)
### C1. Celery 入口与任务示例
- [ ] 新增 `server/app/worker.py`
- [ ] Celery 初始化使用 `CELERY_BROKER_URL`
- [ ] 默认 **不启用** result backend或仅 dev 可选)
- [ ] 配置默认队列名带环境前缀(例如 `dev:push` / `pro:push`
- [ ] 新增 1 个示例任务(例如 `server/app/tasks/ping.py`
- [ ] 任务只传小参数(如字符串/ID
### C2. Worker/Beat 启动与验收
- [ ] Worker 验收:
- [ ] `celery -A app.worker:celery_app worker -l info` 可启动
- [ ] 发送任务后能被消费
- [ ] Beat如需要定时
- [ ] `celery -A app.worker:celery_app beat -l info` 可启动
- [ ] 能按周期触发示例任务
## D. 文档与验收补全
### D1. 更新 README 与约定一致
- [ ] 更新 `server/README.md`
- [ ] 明确:`requirements.txt + pip` 作为依赖安装方式
- [ ] 明确dev/pro MySQL schema`mindfulness_dev`/`mindfulness`
- [ ] 明确Redis ACL + key 前缀、prod `maxmemory=256mb` 硬限制
- [ ] 明确Celery 默认不启用 result backend或启用需 TTL
- [ ] (可选)更新根 `README.md`
- [ ] 追加:基础设施依赖与 dev/pro 隔离约定摘要
### D2. 最终验收清单(完成后统一勾选)
- [ ] **环境隔离**dev/pro MySQL schema 与 Redis ACL 均生效
- [ ] **资源约束**prod Redis `maxmemory=256mb` 生效
- [ ] **可运行性**FastAPI/Celery 可启动并完成最小任务闭环(依赖通过环境变量连接现有 MySQL/Redis