CHANGELOG.md 27 KB

Changelog

记录本项目每次改动。新条目追加到顶部。格式:日期 — 改动概述,正文按 新增 / 变更 / 修复 / 移除 分类。链接 PR / commit / 相关文档(如有)。

2026-07-03

文档

  • PRD(docs/01)对齐现状 + 补完整性:
    • 对齐:阶段改「已内网上线」、补 06-26/06-29 修订记录;§3 范围与 §8 验收补入趋势视图;§7 去掉与趋势矛盾的"不做自定义日期范围"(趋势已支持自定义起止);空态文案「数据缺失」→「暂无数据」。
    • 补充:§1.2 业务目标与成功指标、§1.3 目标用户与典型场景、§1.4 访问与权限(现状内网无鉴权、对外前须补)。
  • PRD 两层结构落地 + PRD 先行入铁律:
    • 抽出模块级 PRD docs/prd/拼团漏斗.md(漏斗定义/时间能力/漏斗视图/趋势视图/模块验收);docs/01 §4 收敛为模块索引表、§8 验收拆为"平台级"(导航/IA/不补零),模块功能级验收移入模块 PRD。
    • CLAUDE.md规则 7「新模块 PRD 先行」:开新模块前先登记 + 写模块 PRD 对齐再写码;docs/08 §3 同步"已落地"。
  • docs/08-迭代与发布 新增:沉淀迭代方式(端到端垂直切片 + 闭环流程 + PRD 先行)、PRD 两层结构与拆分时机、版本方案(里程碑版 v1.0 起、每模块 minor+1,API 对外供数时另走 SemVer)、三层记录区分、发布收尾 7 步清单。PRD 顶部加"版本"栏 + 修订记录加"版本"列(MVP 期留空);README/docs07 索引补 docs/08。
  • /docs-check 全套复扫(只读、未派子代理):修掉 3 处残留漂移——docs/06 鉴权交叉引用 §7→§1.4、docs/02 空态措辞对齐「暂无数据」、docs/02 §5 标注 /query 不含自定义范围(趋势见 §5.1);其余(接口/口径/表结构/IA/结构/部署)均一致。

2026-06-29

新增

  • 防文档漂移机制:CLAUDE.md 加规则 6「改动同步文档」(含"改动类型→该改哪份文档"映射,与 changelog 同属收尾动作)作预防;新增 /docs-check 命令(.claude/commands/docs-check.md)按同一映射审计文档与代码现状的漂移、报告并修复,作发版前/定期兜底。
  • docs/07-项目结构与模块:新接手者的"地图"——顶层目录树、apps/web · apps/api · packages · infra 各模块与关键文件职责、线上/本地运行数据流、构建与 /look 部署流程、本地怎么跑。

文档

  • docs/06 snapshot_dt 表述纠偏(/docs-check 首次审计抓到):原写"missingsnapshot_dtnull",与代码不符——null 仅当未命中任何行;命中行但列为 NULL 的 missing 仍回该行 dt。已在 §2.2/§2.3 改准。
  • apps/api/README 翻成中文并更新:补趋势端点、DB_SCHEMA=ads/search_path、假数据 ~95 天、STATIC_DIR 单进程同源托管、真实数据由上游 ETL 写入(不经 seed/alembic)。
  • 对齐滞后文档到现状:
    • README:部署段从"hypothetical nginx/conda+node20"改为实际(/look + uvicorn:8080 单进程同源 + 隔离 Miniconda),infra 目录说明更正,加 docs/07 指路 + 趋势两视图。
    • docs/04:时间控件去"单日"字样、空态文案「数据缺失」→「暂无数据」、范围文案去"不含今日"、补趋势视图与图例/断线规范、补 漏斗/趋势 Tab。
    • docs/01 §4:补 §4.4 趋势视图;§4.3 同步(默认昨日只显日期、范围文案、空态「暂无数据」)。

变更

  • 单日默认改回「昨日」(apps/web):去掉 06-26 引入的"最新可用日"默认(原为省略 snapshot_dt → 后端取 MAX(dt))。改回默认查昨日并发 snapshot_dt;昨日无数据就如实显示空状态——空就空,是上游问题,不在应用侧兜底
    • 起因:上游 daily 跑批从 6/27 起写入全 0 行,MAX(dt) 落到空行 → 默认显示 0000。
    • TimePeriodSelect 去掉「单日」字样与「最新/最新可用日」,按钮直接显示所选日期(默认昨日);日历仍可选历史。
  • 空状态文案精简(apps/web):漏斗 / 趋势空状态由「数据缺失:所选周期暂无产出数据,未做补零处理。」→ 「暂无数据」(去掉与状态重复的解释 + "补零"内部口径)。
  • look.sh 部署不再误重启后端(infra):仅当 apps/api 真有变更才重启 uvicorn(纯前端改动 uvicorn 实时读盘);重启改为 pkill -9 + 等端口释放 + setsid nohup 直接拉起(不走 serve 脚本的 pgrep 守卫,消除将死进程竞态导致的部署掉站)。

2026-06-26

新增

  • 漏斗页「趋势」Tab:按日折线(apps/api + apps/web):事件 UV 与相邻转换率的每日变化。
    • 数据源就是 ads_trd_group_funnel_daily(天然时序),无需新表/ETL
    • 后端 POST /api/funnels/trend:范围可选(默认最新可用日往前 30 天),每点复用 FunnelStepResult(uv+conversion 服务端算,口径与漏斗页一致);裁前导全 0 天(上线前爬坡);缺口日缺点不补零;end_dt>昨日/start>end → 422。repositoryfetch_daily_range
    • 前端:漏斗页加 漏斗 / 趋势 视图 Tab(React 状态驱动,不用 radix data-active 以免选中态不可见);趋势视图两张分离折线(事件 UV / 相邻转换率,4 段),范围控件 近30天(默认) / 自定义起止(自定义上限锁最新可用日);连续日期轴补 null 断线(connectNulls:false,不补零);ECharts 懒加载。
    • look.sh:后端按需重启(仅 ~/hs-api HEAD 变化才重启 uvicorn,纯前端改动不抖)。
    • 测试:后端 +7(范围/裁 0/口径/missing/校验)、前端 +9(mock 序列 + 视图/Tab 状态)。

修复

  • 日期范围文案挤动页面(apps/web FunnelPage):右上角日期范围(如 2026-06-15 ~ 2026-06-21)原是条件挂载/卸载,显示↔隐藏(单日↔近7/30天切换、pending→加载完)时控件列高度变化,撑动外层行,把下方图表整体顶动。改为始终占位(h-4 固定行高,空内容不塌缩),仅滚动周期且查询完成时填文案——高度恒定,不再抖动。

新增

  • 后端上线:服务器单进程同源托管(真实数据)(infra/ + 服务器):线上 http://100.64.0.62:8080/ 从 mock 切到真实 PG 数据
    • 服务器装隔离 Miniconda Python 3.11(~/miniconda3,py311_24.7.1,兼容 CentOS7 glibc 2.17;新版 Miniconda 要 glibc≥2.28 故选旧版),pip 仅装运行时依赖(--only-binary 走 manylinux2014 轮子,无需编译器);不动系统 3.6/3.7 环境
    • 后端源码独立 clone 到 ~/hs-api(feature 分支);apps/api/.env 直连 PG(服务器内网可达 100.64.0.10:25432)。
    • app/main.pySTATIC_DIR 条件静态托管:uvicorn 单进程同源托管 SPA(~/hs-data,实时读盘)+ /api,端口 8080,取代原 serve.py——同源免 CORS、前端相对 /api 不变、只剩一个常驻进程。本地/测试未设 STATIC_DIR 故不挂载,零影响。
    • ~/serve-hs-api.sh 启动器(nohup setsid,脱离 SSH 会话存活,幂等);infra/look.sh 构建改 VITE_USE_MOCK=false、拉产物后确保后端在跑。
    • 端到端实测(公网 8080):SPA + 深链回退 200,/api 三周期均 ready(day=最新可用日 20260621,11859→5366)。

变更

  • 后端接通真实 PG(apps/api):由假数据切到真实拼团漏斗预聚合两表(ads.ads_trd_group_funnel_daily / _rolling)。
    • config.pydb_schema(默认 ads);session.py 给真实连接挂 search_path=ads(asyncpg server_settings)——ORM 表名保持无 schema,SQLite 测试不受影响,模型零改动。
    • 真实连接串 + USE_FAKE_DATA=false 放进 gitignoredapps/api/.env(密码不入库)。
    • 端到端实测通过:{"period":"day"} 取最新可用日(dt=20260621)ready;last_7d/last_30d 取 rolling 行。
    • 已验证部署服务器(100.64.0.62)能连通 PG(100.64.0.10:25432);后端落点(隔离 conda/Py3.11)为后续。
  • 默认单日改为「最新可用日」(apps/web):数据 T+1 且可能滞后(当前最新仅到 6-21),默认不再硬编码昨日。
    • FunnelPage 默认 snapshotDt=null → 查询省略 snapshot_dt,后端取 MAX(dt),打开即见最新一天,不再「数据缺失」。
    • TimePeriodSelect:单日按钮无选中时显示「最新」;日历 popover 顶部加「最新可用日」快捷项可一键回到默认;日历仍可选历史具体日。

2026-06-25

新增

  • docs/06-接口文档:面向调用方的 API 参考——端点、请求/响应字段与约束、data_status(ready/missing)、422 错误场景、各周期 curl 示例。

变更

  • PRD 改日期制变更记录:docs/01 去掉 v1/v2 语义版本号(MVP 快迭期不适用),改为「阶段:MVP 开发中(未发布)+ 按日期记变更」,补全 06-24/06-25 的迭代(三级 IA → 拼团两表 → IA 精简 5 域 → 平台更名)。
  • 文档对齐现状(清 v1 残留):几次 pivot(bitmap→拼团两表、AntD→shadcn、四态→两态)后,周边文档段没回头清。本次对齐:
    • docs/02 §3/§4(前端/后端职责)、§7(性能)、§8(测试):由 bitmap / 15 天自定义范围 / Ant Design / 步骤参数 → 拼团两表 + shadcn + ready/missing + period 取列
    • docs/05 §5/§6(前后端 agent)、§7(数据状态):同步到两表 + shadcn + 两态。
    • docs/03 §7:标注当前两表源只用 ready/missing,partial/invalid 属后续 bitmap 方案(暂不落地)。
    • 保留有意内容:历史修订注、"不读 bitmap"、后续泛用漏斗段、"数据服务"(PG 存储术语)。
  • 平台更名「数据服务平台」→「数据平台」:把"数据服务"一词留给将来的对外供数 / API 层(业界 OneService = 统一数据服务,该词语义本属 API 层,不该占在看数平台上)。改顶栏品牌、index.html / document.titlepackage.jsondocs/01-05 的平台名引用;保留"数据服务层"(PG 存储层术语,不动)。docs/01 §1 加命名约定。
  • 时间边界条收尾:去掉"· 不含今日";单日不显示任何时间文案(日期已在按钮上),仅近 7/30 天显示日期范围。

新增

  • 一键部署 /look + 服务器静态托管(infra/ + .claude/):
    • 部署链路(纯 git、不用 scp):本地 build → 推 feature(源码)+ deploy(构建产物,独立分支)→ 服务器 git pull → 上线。封装为 infra/look.sh
    • 因目标服务器是 CentOS 7(glibc 2.17)建不了现代前端,改为本地构建、产物经 deploy 分支送达;服务器用 infra/serve.py(SPA 回退、Python 3.6 兼容)在 8080 静态托管。访问 http://100.64.0.62:8080/
    • .claude/commands/look.md:斜杠命令 /look(仅显式触发,不做自然语言自动触发)。
  • 服务器部署辅助:infra/serve.py(静态服)、infra/serve-start.sh(守护启动器,未启用 cron)。

变更

  • 时间边界条二次精简(apps/web):从标题下方的"带边框 + 图标"大条 → 移到时间控件正下方的小字灰行,去图标、去"数据日期/近N天/T+1"等与按钮重复或术语化的前缀,仅保留 日期(范围)· 不含今日funnelRangeText 同步精简。

修复

  • 时间边界文案不可见(apps/web):原"数据快照日/数据截至"小灰字埋在结果卡片最底部,用户感知不到漏斗覆盖的时间范围。改为在标题区下方放醒目的"数据范围"条(带边框 + 日历图标):单日「数据日期 YYYY-MM-DD」、近 7/30 天「近 N 天 起 ~ 止」,并显式标注「数据 T+1,不含今日」。period.tsfunnelRangeText;FunnelResult 去掉底部 caption(period prop 移除)。

变更

  • README 更新到最新进度:拼团漏斗 MVP、shadcn 主题、五个 L1 IA、两表数据源、真实可运行命令、分支模型、CentOS7 服务器部署说明(conda 或静态托管)。

新增

  • 远程开发准备:新增 .gitattributes(文本统一 LF,避免 Windows CRLF 污染 Linux 服务器)与 infra/setup.sh(Debian/Ubuntu 一键装 Node20/pnpm/Python3.11 + 依赖 + 启动说明)。首个 git commit 落地(此前仅 git init,0 提交)。

变更

  • 默认周期改为「单日(昨日)」(apps/web period.ts):DEFAULT_PERIOD last_7dday,首屏即看昨日的拼团漏斗(数据 T+1,昨日为最大可查日);测试同步更新。
  • 品牌字 HS-DataHS Data(空格替代连字符):顶栏品牌、index.html 标题、document.title 一并更新。

修复

  • 时间选择选中态彻底重做(apps/web):此前 近7/近30 用 shadcn Tabs、单日用 Button variant,选中高亮依赖 data-active/默认白底,在浅色页几乎不可见——用户感知不到"当前在哪个周期"。
    • 合并 DateField + PeriodSelect → 单一 TimePeriodSelect segmented 控件(单日/近7天/近30天三选一);选中 = mint 实色 + 白字,由 React 状态直接驱动(不依赖任何 shadcn 变体),100% 可见、三段反馈统一。
    • 删除 DateField.tsx / PeriodSelect.tsx 及孤儿导出(PERIOD_OPTIONS/ROLLING_PERIOD_OPTIONS/periodLabel);测试 role tabbutton。Vitest 37 passed、build clean。docs/04 §5 同步。

2026-06-24

新增

  • 品牌与 favicon(apps/web):新增 public/favicon.svg(mint 圆角方块 + 漏斗三阶 glyph),index.html 接入 favicon + theme-color + 标题改 HS-Data · 数据服务平台。顶栏品牌重做:mint 方块 mark(漏斗 glyph,与 favicon 一致)+ HS-Data(-Data mint)+ 竖线 + 灰色副标题「数据服务平台」,替换原全小写平排文字。
  • 顶栏/页面体验五件套(apps/web):
    • 面包屑(Breadcrumb + nav-utils.findTrail):内容区顶部显示「行为分析 / 漏斗分析 / 拼团漏斗」,末项高亮——深层导航定位。
    • 动态页面标题:document.title 随路由变为「<当前页> · HS-Data」。
    • ECharts 懒加载:FunnelChartReact.lazy + Suspense,拆出独立 chunk —— 主包 1.56MB → 510KB(echarts 1.05MB 按需加载,非漏斗页不加载)。
    • 暗色模式开关(ThemeToggle):顶栏 Sun/Moon 切换,偏好存 localStorage,main.tsx 首屏前应用避免闪烁。
    • 品牌图标由 lucide Target 换为自绘漏斗 glyph(与 favicon 统一)。
    • Vitest 37 passed、build clean(FunnelResult 图表断言改 findByTestId 适配懒加载)。

变更

  • 加回「指标体系」L1 + 导航展开/折叠改为主流交互(docs/01/docs/02/docs/04 + apps/web):
    • L1 由 4 → 5,加回 指标体系(指标目录/指标大盘/指标监控):主流数据产品核心(统一指标口径),只取消费面、不做治理后台。
    • 导航展开/折叠对齐主流后台(VS Code/AntD Pro/神策):点 L1/L2 分组手动展开/折叠(不跳转)、多个可同时展开(非手风琴)、进入某页自动展开其所在分支且不折叠其它分支、当前分支可手动折叠。NavTree.tsx 改为受控 open 集合;父节点为 toggle 按钮,叶子才跳转。
    • 同步 docs/01 §2(5 L1 + §2.3 导航交互)/§3/§7/§8、docs/02 §9、docs/04 §3。Vitest 37 passed(+折叠/多开两条)、build clean。
  • IA 精简为内部工具版(四字对齐,多实体画像)(docs/01/docs/02/docs/04 + apps/web):
    • L1 由 7 砍到 4:行为分析 / 画像体系 / 数据看板 / 营销触达(模块名统一四字)。依据:内部工具非 SaaS——不设独立"实时"域(实时大盘并入数据看板)、画像改多实体体系(用户/商家/产品画像,标签作底层不单列)、砍掉数据管理/工作台/指标平台门面。
    • 导航视觉强化层级:L1 加粗 + 图标 + 展开箭头 ▸/▾;L2/L3 左侧竖引导线 + 缩进 + mint pill 激活。
    • 同步 docs/01 §2(4 L1 表 + L2/L3 + 取舍说明)、§3/§5/§7/§8;docs/02 §9;docs/04 §3;NAV 树 + NavTree.tsx。Vitest 35 passed、build clean。
  • 前端导航对齐三级 IA(apps/web,落地 docs/01 §2):左侧导航由 5 个扁平能力域改为多级 L1 能力域 + 三级导航树(L1 能力域 → L2 分析模块 → L3 报表)。
    • 新增 routes/domains.tsNAV 树 + layout/NavTree.tsx(递归渲染、仅展开当前分支、按深度缩进);App.tsx 由树自动生成路由(父节点重定向到首个叶子,可用叶子 → 页面,余 → 占位)。
    • 拼团漏斗落点 /behavior/funnel/group(= 行为分析 > 漏斗分析 > 拼团漏斗);/ 重定向至此。其余 L1/L2 出"待开发"占位。
    • AppLayout 抽出导航为 NavTree,保留既定主题/三段式布局/抗抖滚动模型;docs/04 §3 导航说明同步更新。
    • Vitest 35 passedvite build clean(本机实跑)。
  • PRD 信息架构重构(docs/01 v2.0):由 5 个扁平能力域升级为主流数据平台通用的三级 IA(L1 能力域 → L2 分析模块 → L3 报表/实例),参考神策 + 网易有数/阿里 OneData/Aloudata 指标平台/CDP。
    • 平台定位改为多形态一站式数据平台门户;明确数据现实约束(T+1 预聚合宽表 → 只做固定报表,自助分析需事件级数据列远期)。
    • 7 个 L1 能力域:看板 / 行为分析 / 用户画像与标签 / 指标平台 / 实时 / 营销触达 / 数据管理(+工作台首页);标签体系、指标体系各立为独立 L1 预留。
    • MVP 落点明确:行为分析 > 漏斗分析 > 拼团漏斗(固定) 端到端,余 L1/L2 进导航出"待开发"占位。
    • 漏斗详规对齐已上线实况(拼团固定 5 步、单日/近7天/近30天、单日历史回溯、T+1、不补零),替换旧"任意步骤/自定义15天/bitmap"描述;演进路线、明确不做、验收标准同步更新。
    • 同步:docs/02 §9 路由对齐 7 个 L1 + 漏斗下 L2/L3;docs/05 补"导航 IA 以 docs/01 为准、视觉以 docs/04 为准"。
    • 导航代码改造(apps/web 左侧导航 5→7 域 + L2 子菜单)列为后续任务,本次仅文档。

新增

  • docs/04-设计规范:前端视觉/交互定稿并锁定(神策风 mint 主题色板、三段式布局、漏斗图 mint 渐变、单日日历常驻 + 滚动 Tabs 控件、快照/截至文案、抗抖滚动模型)。docs/02 §1 加指针。设计决策以本文为唯一权威来源。

变更

  • 前端视觉定稿(神策风)(apps/web,在 shadcn 迁移基础上):
    • 主题色板取自 sensorsdata.cn 实际 CSS:主色 mint #04CB94、文本 #1F2D3D、底 #F9FAFC(非纯白)、弱化 #99A9BF、淡 mint #DEFFF6、错误 #EF4444;默认亮色(.dark 备而不用)。
    • 布局三段式:白顶栏(底线 + mint logo + mint dot/MVP)+ 浅 slate-100 侧栏(active 项淡 mint 底 + mint-700 字)+ 微蓝白主区 + 白卡轻投影。否决过的方案:全白(太平)、深 navy 侧栏(对比太狠 / 顶左同色)。
    • 漏斗图改 mint 单色渐变 #064E3B→#04CB94,块宽按真实 UV 比例。
    • 控件改版:单日日历常驻(DateField 自带「单日」标签 + 高亮 active 态)替代「单日」Tab;Tabs 仅留近 7/30 天。
  • 修复加载抖动(AppLayout):根容器 min-h-screenh-screen overflow-hidden,令 <main> 为唯一滚动区 + scrollbar-gutter:stable,横向不再因滚动条出现/消失而抖;骨架高度对齐内容,竖向不跳。
  • 前端漏斗对齐拼团契约 v3 + 单日历史日期选择器(apps/web):
    • 周期模型:yesterday|last_7d|last_30dday|last_7d|last_30d,Tab 文案 单日 / 近 7 天 / 近 30 天,默认仍 last_7d。固定漏斗第 3 步「详情」→「拼团详情」;副标题改「拼团漏斗:启动 → 曝光 → 拼团详情 → 下单 → 成功」。
    • 类型(api/types.ts):请求加可选 snapshot_dt?(仅 day 发送),响应 snapshot_dt 可为 null
    • 新增 DateField(shadcn calendar + popover,基于 react-day-picker v10):仅 period==='day' 渲染;默认昨日;disabled={{ after: 昨日 }} 禁今天/未来(T+1),历史不设下限;选日即以该 snapshot_dt 重查。切到 7/30 天时隐藏。
    • 快照说明两态:day → 「数据快照日:YYYY-MM-DD」;last_7d/30d → 「数据截至 YYYY-MM-DD(近 7 天/近 30 天)」,点明滚动窗口 as-of 日不含今天。
    • 请求形态:day{period, snapshot_dt};7/30 天发 {period}(api fn 与页面双重保证省略)。mock 支持 day 历史(按日期做确定性 ±8% 抖动,不同 snapshot_dt 取不同数)、missingsnapshot_dt: null、保留 ?missing=1VITE_USE_MOCK 默认开。
    • 新增依赖 react-day-picker@10 + date-fns@4,新增 components/ui/{calendar,popover}.tsx。保留既定 mint 主题、AppLayout、漏斗渐变、抗抖骨架不动。
    • Vitest 33 passedvite build clean(本机实跑)。
  • 后端 MVP 漏斗升级为「拼团漏斗 + 两张真实表」(契约 v3)(apps/api):
    • 数据源由单表 ads_trd_group_funnel 拆为两表(docs/03 §11):ads_trd_group_funnel_daily(单日、留全历史)+ ads_trd_group_funnel_rolling(近 7/30 天、覆盖式 1 行)。
    • 请求契约:period 枚举由 yesterday|last_7d|last_30d 改为 day|last_7d|last_30d;新增可选 snapshot_dt(ISO YYYY-MM-DD,仅 day 有效,7/30 天忽略)。响应 snapshot_dt 回显实际取数行的 dt(yyyyMMdd)。
    • 路由:day → daily 表(给 snapshot_dtWHERE dt=:dt,否则最新 dt,列 uv_start/show/detail/order/paid);last_7d/last_30d → rolling 唯一行,取 uv_*_7d / uv_*_30d
    • 校验:daysnapshot_dt 上限昨日(T+1),今天/未来 → 422;非存在 dtmissing。第 3 步展示名由「详情」改为「拼团详情」。data_statusready|missing,不补零。
    • FakeFunnelRepository(USE_FAKE_DATA 默认开)兜底:造约 10 天递减历史 daily 行(截至昨日,支持日期选择器回溯、不同 snapshot_dt 取不同数据)+ 1 行 as-of 昨日 rolling;无 DB 即可起。seed 脚本同步改插 10 daily + 1 rolling。
    • 重写 Alembic 迁移(建两表,删旧单表迁移);改 models.py(两 ORM 模型)、repository.py/funnel.py/schemas.py/api/funnels.py;更新 README.md.env.example
    • pytest 47 passed(本机实跑);重出 openapi.json(Period=day/last_7d/last_30d、请求含 snapshot_dt)。
  • 前端 UI 栈从 Ant Design 5 全量迁移到 shadcn/ui + Tailwind CSS v4(B 方案):
    • docs/02 §1 已改:React + Vite + TS + Tailwind v4 + shadcn/ui(radix-nova/neutral)+ ECharts + TanStack Query,Ant Design 退出技术栈。
    • 装 Tailwind v4(@tailwindcss/vite 插件)、路径别名 @/* → ./src/*(tsconfig + vite.config)、src/index.css 用 v4 + neutral OKLCH 主题(light + dark)、html/body 默认 class="dark"
    • shadcn@latest init(CLI v4.11.0,style radix-nova,base color neutral,iconLibrary lucide)生成 components.jsonsrc/components/ui/;add 了 button/card/tabs/table/badge/alert/skeleton/separator/scroll-area/sheet/sonner。
    • 移除 antd / @ant-design/icons / dayjs(grep 0 命中)。重写 AppLayout(Tailwind 壳 + lucide-icon 侧栏)、PeriodSelect(shadcn Tabs)、FunnelResult(Card + Alert + Skeleton + lucide Inbox)、ResultTable(shadcn Table)、Placeholder(Card + Construction 图标)。保留 ECharts 漏斗图、新契约、5 域导航、mock 行为不变。
    • Vitest 26/26 passedvite build clean(本机实跑)。dev server 起在 :5173

已知未完成

  • shadcn 官方 Skill 未装到 apps/web/.claude/skills/shadcn/。两层阻断:① 网络上 git clone https://github.com/shadcn/ui.git(pnpm dlx skills add shadcn/ui 调用的)被防火墙 RST(raw.githubusercontent.com 也超时,api.github.com / codeload 通);② harness 拒绝代理脚本写入 .claude/skills/(self-modification 防护)。需要在本地终端跑 pnpm dlx skills add shadcn/ui,或改走 shadcn MCP(.mcp.json 配置)。

(前一条 v2 漏斗转向条目原文保留:)

  • MVP 漏斗转向"固定漏斗 + 真实预聚合宽表"(真实表 ads_trd_group_funnel 到位,替代原 bitmap 泛用漏斗方案):
    • 契约 v2(docs/02 §5/§6、docs/03 §11):请求 {period: yesterday|last_7d|last_30d};响应 {period, snapshot_dt, results×5(event_key), data_status: ready|missing};固定 5 步 启动→曝光→详情→下单→成功。
    • 后端 apps/api:改查 ads_trd_group_funnel 最新 dt 行选 *_1d/7d/30d 列;USE_FAKE_DATA(默认开)假数据兜底,无 DB 也能起;移除 pyroaring/bitmap 两表/OR 逻辑;Alembic 改建宽表;seed 改插快照行;pytest 25 passed(本机实跑);重出 openapi.json
    • 前端 apps/web:去掉任意步骤配置 + 自定义范围 + 15天/今天校验;改 3 周期按钮(默认近7天)+ 固定 5 步;接新契约;mock 默认开;Vitest 26 passed、构建通过(本机实跑)。
    • packages/api-types:pnpm gen:api-types 跑通,由 openapi.json 生成 schema.ts(Period/DataStatus/event_key/snapshot_dt)。
  • 端到端联通(本机实跑):后端 uvicorn(假数据)POST /api/funnels/query {period:last_7d} 返回契约正确;前端 dev server 起于 :5173

移除

  • bitmap 相关:app/services/bitmap.pydaily/period_event_bitmap 两表与迁移、pyroaring 依赖、相关测试/seed(挪到后续"泛用漏斗"阶段)。
  • 前端:StepConfig、自定义 TimeRangePicker、15天/今天校验工具及其测试。

环境

  • 安装 Python 3.11.9(用户作用域),apps/api/.venv 装齐依赖,后端测试本机可跑。否决"降级到 Python 2.7.5"(FastAPI/Pydantic v2 不支持)。Docker 仍未用(非管理员装不了),本地以 USE_FAKE_DATA 假数据替代。

2026-06-23

新增

  • MVP 全栈脚手架落地(按 docs/01/02/03 与计划阶段 0–4):
    • 阶段 0 — Monorepo 脚手架:git init(main)、根 package.json + pnpm-workspace.yaml.gitignore/.nvmrc/.editorconfig;根脚本 dev:web/build:web/test:web/gen:api-types
    • infra — infra/docker-compose.yml 起 PostgreSQL 16。
    • 阶段 1+2 — 后端 apps/api(FastAPI + Pydantic v2 + SQLAlchemy async + pyroaring):POST /api/funnels/query 严格按 docs/02 §5;Alembic 建 daily_event_bitmap / period_event_bitmap 两表;周期优先 / 自定义 daily OR 取数;第 1 层转化率 nulldata_status 四态不补零;bitmap 计算走线程池不阻塞 event loop;seed 脚本(含缺失/损坏样本)、export_openapi.py、pytest 测试集(覆盖 docs/02 §8)。
    • 阶段 3 — 前端 apps/web(React 19 + Vite + TS + AntD 5 + ECharts + TanStack Query):平台壳 + 五域导航;漏斗页四区 + 校验(≤15 天、今天不可选/不可提交);其余四域共用 Placeholder;按 data_status 显式渲染、null 转化率显示 “—” 不补零;mock 模式(VITE_USE_MOCK);Vitest 37 项测试通过。
    • 阶段 4 — packages/api-types:接好 openapi-typescript 生成链(pnpm gen:api-typesapps/api/openapi.json),含占位 schema.ts
  • CLAUDE.md:项目协作守则(思考优先、简单优先、外科手术式改动、目标驱动、变更入 changelog)。
  • CHANGELOG.md:本文件。

待办(环境受限,未在本机执行)

  • 后端运行/测试与端到端联调需 Python 3.11+Docker(本机仅 Python 3.8、无 Docker):apps/api 代码与测试按 3.11 编写但未执行。
  • gen:api-types 待后端用 python -m scripts.export_openapi 导出 apps/api/openapi.json 后运行;在此之前前端用 apps/web/src/api/types.ts(契约一致)。