# 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 MySQL(schema 隔离) - prod schema:`mindfulness` - dev schema:`mindfulness_dev` - 字符集:`utf8mb4` - 连接方式:后端通过 `DATABASE_URL`(SQLAlchemy Async)连接到对应 schema ### 2.2 Redis(ACL + 前缀隔离 + 内存限制) - 单 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://:@redis:6379/0` - `CELERY_BROKER_URL=redis://:@redis:6379/0` - `CELERY_RESULT_BACKEND`:默认不配置(或仅在 dev 开启) ### 5.2 密钥管理 - `.env.dev/.env.prod` 不进仓库 - 提供 `.env.example` 仅展示字段结构 ## 6. 实施步骤(建议顺序) ### 阶段 A:验证现有 MySQL/Redis 与隔离策略 - Redis:ACL 生效验证(dev 用户无法访问 `pro:*`,prod 用户无法访问 `dev:*`) - Redis:prod 配置验证(`maxmemory=256mb` 生效) - MySQL:确认 `mindfulness_dev` 与 `mindfulness` 两个 schema 已创建(若未创建则创建) ### 阶段 B:后端最小可运行骨架 - `requirements.txt` 固化依赖 - FastAPI 最小健康检查接口(如 `/healthz`) - SQLAlchemy 连接与基础会话 - Alembic 初始化与一次空迁移验证 ### 阶段 C:Celery 最小闭环 - 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` 生效 - 不启用(或短 TTL)result backend,避免长期堆积 - **可运行性** - FastAPI 能启动并提供基础接口 - Celery worker 能消费任务,beat(如启用)能触发定时任务 ## 8. 风险与应对 - Redis 256MB 触顶风险: - 控制队列积压(worker 数量/并发) - 禁用或缩短结果存储 TTL - 任务 payload 只传 id - 多环境同机误用风险: - 强制不同 ACL 用户 + 前缀 - Celery 队列名带前缀,避免互相消费