# Tushare PostgreSQL 同步实施计划 ## 实施原则 - 按以下顺序增量交付,每一步先写对应行为测试,再补最小实现。 - 不修改旧项目;不导入其带有最新市值回填的历史 CSV。 - 不在本任务中实现选股策略、HTTP 管理接口或宿主机 crontab 写入。 - schema、CSV 契约和批次状态一旦被后续步骤使用,变更时必须同步更新迁移、测试和设计文档。 ## 1. 依赖、配置与迁移骨架 - 在 `zhixing-server/pyproject.toml` 增加 Tushare、Psycopg 3、SQLAlchemy 和 Alembic 依赖并更新 `uv.lock`。 - 扩展 `bootstrap.config.Settings`:数据库 URL、Tushare token、CSV 根目录、覆盖率阈值、并发/限流/重试参数;保持 `ZHIXING_` 前缀且不暴露秘密。 - 初始化 Alembic 配置和 metadata,创建股票、日线、每日指标、同步 batch/item 表及唯一约束、索引。 - 增加 migration 集成测试,验证空库 upgrade 到 head、唯一约束和必要索引。 验证: ```bash cd zhixing-server uv sync uv run alembic upgrade head uv run pytest tests/integration/test_market_data_migrations.py ``` 回滚点:本阶段只建立 schema;若迁移失败,修正 migration 后重建测试库,不对生产卷执行手工 DDL。 ## 2. 领域模型、规范化与端口 - 创建 `modules/market_data` 四层目录和 bounded-context README。 - 定义 `ts_code`、目标交易日、六年窗口、bar、daily basic、batch/item 状态和值对象。 - 定义 Tushare 来源、快照存储、市场数据仓储、批次仓储和同步锁端口。 - 实现固定列、日期、小数、空值规范化,完整重叠区间 SHA-256 计算和变化分类。 - 先用纯领域测试覆盖:初次同步、仅新增日期、历史值变化、重叠区间缺行、输入顺序变化、空值/小数稳定性和窗口边界。 验证: ```bash cd zhixing-server uv run pytest tests/unit/market_data/test_fingerprint.py tests/unit/market_data/test_window.py ``` ## 3. Tushare 与 CSV 适配器 - 封装 `stock_basic`、`trade_cal`、`pro_bar(adj="qfq")` 和 `daily_basic(trade_date=...)`,把 DataFrame 转为领域记录。 - 实现当前沪深非 ST 股票池过滤、请求退避/抖动和可配置并发限制。 - 实现 bar 按股票、daily basic 按日期、stock basic 当前版的临时 CSV 写入、校验、指纹读取、原子晋升和过期文件清理。 - 通过 fake Tushare 客户端与临时目录测试,不让普通单元测试访问真实网络。 验证: ```bash cd zhixing-server uv run pytest tests/unit/market_data/test_tushare_adapter.py tests/unit/market_data/test_csv_snapshot_store.py ``` 回滚点:正式 CSV 只在数据库提交后晋升;适配器测试必须证明异常路径保留旧文件。 ## 4. PostgreSQL 批量仓储 - 使用 Psycopg 连接/事务实现股票主数据、bar、daily basic、batch/item 和 advisory lock 适配器。 - 对 bar 和 daily basic 使用临时 staging + `COPY` + 集合式 upsert;通过 `IS DISTINCT FROM` 避免无意义 update。 - 实现 insert-only、新窗口完整修复、窗口内缺失删除和六年前数据清理。 - 集成测试覆盖幂等、更新计数、单股票回滚、日期事务回滚、并发锁以及数据库最终与快照一致。 验证: ```bash cd zhixing-server uv run pytest tests/integration/test_market_data_repository.py ``` ## 5. 同步用例与失败重试 - 实现 `SyncMarketData.execute()`:解析目标交易日、刷新股票池、创建批次、回补/更新 daily basic、逐股票同步 bar、收敛状态和覆盖率。 - 初始化模式只回补缺失开市日;日常模式只获取目标日 daily basic,但每股始终拉六年 qfq。 - 实现父 batch 的失败股票和失败指标日期重试;成功项不回滚、不重复抓取。 - 用 fake 端口编排测试覆盖 `success`、`partial_success`、`failed`、99% 阈值、旧数据不得计入有效集合、CSV 发布失败和重试恢复。 验证: ```bash cd zhixing-server uv run pytest tests/unit/market_data/test_sync_market_data.py ``` ## 6. CLI、Compose 与运维文档 - 增加 console script/CLI,支持普通同步、显式目标日期、初始化和按 batch 重试;输出批次摘要并返回稳定退出码。 - 在 dev/prod Compose 中增加 PostgreSQL、CSV 持久卷、`migrate` 和 `market-sync` profile Job,复用后端镜像和统一环境配置。 - 更新 `.env.example` 与部署文档,提供 migration、手工运行、失败重试和宿主机 cron 示例;不自动写入 crontab。 - 验证正常 `up` 不启动 Job,显式 `run --rm` 能连接数据库与 CSV 卷。 验证: ```bash docker compose -f docker-compose.prod.yml config docker compose -f docker-compose.dev.yml config docker compose -f docker-compose.prod.yml --profile jobs config ``` ## 7. 全链路验收与质量门禁 - 使用受控 fixture 或测试 Tushare 适配器完成空库初始化、无变化重跑、仅新增日期、历史 qfq 修订、单股票失败和定向重试场景。 - 核对 batch/item 计数、覆盖率、数据库内容、正式 CSV、六年清理和秘密脱敏。 - 若运行真实 Tushare smoke test,必须由显式环境开关启用,限制少量股票且不把 token 写入测试输出。 - 运行后端和根目录质量门禁;修复所有 Ruff、Pyright、pytest 与 Compose config 问题。 验证: ```bash cd zhixing-server uv run ruff format --check . uv run ruff check . uv run pyright uv run pytest cd .. ./dev.sh check ./dev.sh test git diff --check ``` ## 开始实施前检查 - [ ] 用户已在最终规划摘要之后明确批准实施。 - [ ] `prd.md`、`design.md`、`implement.md` 内容一致且无阻塞问题。 - [ ] `implement.jsonl` 与 `check.jsonl` 各自至少包含一条真实规格/研究上下文。 - [ ] `task.py validate tushare-postgres-sync` 通过。 - [ ] 当前工作区已有改动已识别,实施不覆盖用户或其他任务的文件。