# 实现计划:Weibo-HotSign 多用户签到系统 ## 概述 按照自底向上的顺序实现:先构建共享基础层,再逐步实现各微服务。每个阶段包含核心实现和对应的测试任务。 ## Tasks - [x] 1. 创建共享模块 (shared/) - [x] 1.1 创建 `backend/shared/` 包结构和共享配置 - 创建 `shared/__init__.py`、`shared/config.py` - 配置项包括 DATABASE_URL、REDIS_URL、JWT_SECRET_KEY、COOKIE_ENCRYPTION_KEY - 使用 pydantic-settings 从环境变量加载 - _Requirements: 10.1, 10.2_ - [x] 1.2 创建共享 ORM 模型和数据库连接管理 - 创建 `shared/models/base.py`:AsyncEngine、AsyncSessionLocal、Base、get_db() - 创建 `shared/models/user.py`:User 模型(含 accounts relationship) - 创建 `shared/models/account.py`:Account 模型(含 tasks、signin_logs relationship) - 创建 `shared/models/task.py`:Task 模型 - 创建 `shared/models/signin_log.py`:SigninLog 模型 - 所有模型与 `init-db.sql` 中的表结构对齐 - _Requirements: 10.1, 10.2, 10.3_ - [x] 1.3 实现 Cookie 加密/解密工具 (`shared/crypto.py`) - 使用 pycryptodome 实现 AES-256-GCM 加密/解密 - `encrypt_cookie(plaintext, key) -> (ciphertext_b64, iv_b64)` - `decrypt_cookie(ciphertext_b64, iv_b64, key) -> plaintext` - 密钥从环境变量 COOKIE_ENCRYPTION_KEY 派生(使用 SHA-256 哈希为32字节) - _Requirements: 3.1, 3.2, 10.4_ - [ ]* 1.4 编写 Cookie 加密 Round-trip 属性测试 - **Property 1: Cookie 加密 Round-trip** - 使用 hypothesis 生成随机字符串,验证 encrypt 后 decrypt 还原 - **Validates: Requirements 3.1, 3.2, 3.3** - [x] 1.5 实现统一响应格式工具 (`shared/response.py`) - `success_response(data, message)` 返回标准成功格式 - `error_response(message, code, details, status_code)` 返回标准错误格式 - _Requirements: 9.1, 9.2_ - [x] 2. 重构 Auth_Service(Token 刷新机制) - [x] 2.1 重构 Auth_Service 使用 shared 模块 - 修改 `auth_service/app/main.py` 导入 shared models 和 get_db - 删除 `auth_service/app/models/database.py` 中的重复 User 模型定义 - 更新 `auth_service/app/services/auth_service.py` 使用 shared User 模型 - _Requirements: 10.3_ - [x] 2.2 实现 Refresh Token 机制 - 在 `auth_service/app/utils/security.py` 中添加 `create_refresh_token()` 和 `verify_refresh_token()` - Refresh Token 使用 Redis 存储(key: `refresh_token:{hash}`, value: `user_id`, TTL: 7天) - 登录接口返回 access_token + refresh_token - 实现 `/auth/refresh` 端点:验证旧 token → 删除旧 token → 生成新 token 对(Token Rotation) - 更新 `auth_service/app/schemas/user.py` 添加 RefreshToken 相关 schema - _Requirements: 1.3, 1.5, 1.6_ - [x] 2.3 为 Auth_Service 所有响应应用统一格式 - 注册、登录、刷新、获取用户信息接口使用 `shared/response.py` 格式化响应 - 注册全局异常处理器(HTTPException、RequestValidationError) - _Requirements: 9.1, 9.2, 9.3, 9.4_ - [ ]* 2.4 编写认证流程属性测试 - **Property 2: 用户注册后可登录获取信息** - **Property 3: 用户名/邮箱唯一性约束** - **Property 4: 无效凭证登录拒绝** - **Property 5: Refresh Token 轮换** - **Property 6: 弱密码拒绝** - **Validates: Requirements 1.1-1.8** - [x] 3. Checkpoint - 确保共享模块和认证服务测试通过 - 运行所有测试,确认 shared 模块和 auth_service 工作正常 - 如有问题请向用户确认 - [x] 4. 实现 API_Service(账号管理) - [x] 4.1 创建 API_Service 基础结构 - 创建 `api_service/app/__init__.py`、`main.py`、`config.py`、`dependencies.py` - `main.py`:FastAPI 应用,注册 CORS、全局异常处理器、路由 - `dependencies.py`:JWT 认证依赖(`get_current_user`),复用 shared 的 JWT 验证逻辑 - _Requirements: 2.8, 9.1, 9.2, 9.3, 9.4_ - [x] 4.2 实现微博账号 CRUD 路由 - 创建 `api_service/app/schemas/account.py`:AccountCreate、AccountUpdate、AccountResponse - 创建 `api_service/app/routers/accounts.py`: - `POST /api/v1/accounts`:加密 Cookie 后存储,状态初始化为 "pending" - `GET /api/v1/accounts`:返回当前用户的账号列表(不含 Cookie 明文) - `GET /api/v1/accounts/{id}`:返回账号详情 - `PUT /api/v1/accounts/{id}`:更新备注或 Cookie(更新 Cookie 时重新加密) - `DELETE /api/v1/accounts/{id}`:删除账号(级联删除 tasks 和 logs) - 所有接口验证资源归属(user_id 匹配) - _Requirements: 2.1-2.8_ - [ ]* 4.3 编写账号管理属性测试 - **Property 7: 账号创建与列表一致性** - **Property 8: 账号详情 Round-trip** - **Property 9: 账号更新反映** - **Property 10: 账号删除级联** - **Property 11: 跨用户资源隔离** - **Property 12: 受保护接口认证要求** - **Validates: Requirements 2.1-2.8, 4.6, 8.5, 8.4, 9.4** - [-] 5. 实现 API_Service(任务配置) - [x] 5.1 实现签到任务 CRUD 路由 - 创建 `api_service/app/schemas/task.py`:TaskCreate、TaskUpdate、TaskResponse - 创建 `api_service/app/routers/tasks.py`: - `POST /api/v1/accounts/{id}/tasks`:验证 Cron 表达式有效性,创建任务 - `GET /api/v1/accounts/{id}/tasks`:获取账号的任务列表 - `PUT /api/v1/tasks/{id}`:更新任务(启用/禁用) - `DELETE /api/v1/tasks/{id}`:删除任务 - 使用 `croniter` 库验证 Cron 表达式 - 任务创建/更新/删除时通过 Redis pub/sub 通知 Task_Scheduler - _Requirements: 4.1-4.6_ - [ ]* 5.2 编写任务配置属性测试 - **Property 13: 有效 Cron 表达式创建任务** - **Property 14: 无效 Cron 表达式拒绝** - **Property 15: 任务启用/禁用切换** - **Property 16: 任务删除** - **Validates: Requirements 4.1-4.6** - [x] 6. 实现 API_Service(签到日志查询) - [x] 6.1 实现签到日志查询路由 - 创建 `api_service/app/schemas/signin_log.py`:SigninLogResponse、PaginatedResponse - 创建 `api_service/app/routers/signin_logs.py`: - `GET /api/v1/accounts/{id}/signin-logs`:支持分页(page, size)和状态过滤(status) - 返回按 `signed_at` 降序排列的日志 - 返回总记录数用于前端分页 - 验证账号归属权限 - _Requirements: 8.1-8.5_ - [ ]* 6.2 编写签到日志查询属性测试 - **Property 23: 签到日志时间倒序** - **Property 24: 签到日志分页** - **Property 25: 签到日志状态过滤** - **Validates: Requirements 8.1-8.3** - [ ] 7. Checkpoint - 确保 API_Service 所有测试通过 - 运行所有测试,确认账号管理、任务配置、日志查询功能正常 - 如有问题请向用户确认 - [ ] 8. 重构 Task_Scheduler(真实数据库交互) - [ ] 8.1 重构 Task_Scheduler 使用 shared 模块 - 修改 `task_scheduler/app/celery_app.py` 导入 shared models - 实现 `load_scheduled_tasks()`:从 DB 查询 `is_enabled=True` 的 Task,动态注册到 Celery Beat - 实现 Redis pub/sub 监听:接收任务变更通知,动态更新调度 - 替换 `signin_tasks.py` 中的 mock 账号列表为真实 DB 查询 - _Requirements: 5.1, 5.2, 5.3_ - [ ] 8.2 实现分布式锁和重试机制 - 使用 Redis SETNX 实现分布式锁,防止同一任务重复调度 - 配置 Celery 任务重试:`max_retries=3`、`default_retry_delay=60` - _Requirements: 5.4, 5.5_ - [ ]* 8.3 编写调度器属性测试 - **Property 17: 调度器加载已启用任务** - **Property 18: 分布式锁防重复调度** - **Validates: Requirements 5.1, 5.5** - [ ] 9. 重构 Signin_Executor(真实数据库交互) - [ ] 9.1 重构 Signin_Executor 使用 shared 模块 - 修改 `signin_service.py` 中的 `_get_account_info()` 从 DB 查询真实 Account 数据 - 修改 `weibo_client.py` 中的 `_decrypt_cookies()` 使用 `shared/crypto.py` - 实现签到结果写入 `signin_logs` 表(替代 mock) - 实现 Cookie 失效时更新 `account.status = "invalid_cookie"` - _Requirements: 6.1, 6.2, 6.4, 6.5_ - [ ] 9.2 实现反爬虫防护模块 - 实现随机延迟函数:返回 `[min, max]` 范围内的随机值 - 实现 User-Agent 轮换:从预定义列表中随机选择 - 实现代理池集成:调用 proxy pool 服务获取代理,不可用时降级为直连 - _Requirements: 7.1, 7.2, 7.3, 7.4_ - [ ]* 9.3 编写签到执行属性测试 - **Property 19: 签到结果持久化** - **Property 20: Cookie 失效时更新账号状态** - **Property 21: 随机延迟范围** - **Property 22: User-Agent 来源** - **Validates: Requirements 6.1, 6.4, 6.5, 7.1, 7.2** - [ ] 10. 更新 Dockerfile 和集成配置 - [ ] 10.1 更新 `backend/Dockerfile` - 在每个构建阶段添加 `COPY shared/ ./shared/` - 确保 shared 模块在所有服务容器中可用 - _Requirements: 10.1, 10.3_ - [ ] 10.2 更新 `backend/requirements.txt` - 添加 `croniter`(Cron 表达式解析) - 添加 `hypothesis`(属性测试) - 添加 `pytest`、`pytest-asyncio`(测试框架) - 确认 `pycryptodome`、`redis`、`celery` 等已存在 - [ ] 11. 最终 Checkpoint - 全量测试 - 运行所有单元测试和属性测试 - 验证各服务可独立启动 - 如有问题请向用户确认 ## 备注 - 标记 `*` 的任务为可选测试任务,可跳过以加快 MVP 进度 - 每个任务引用了具体的需求编号以确保可追溯性 - 属性测试使用 `hypothesis` 库,每个测试至少运行 100 次迭代 - Checkpoint 任务用于阶段性验证,确保增量开发的正确性