记录本项目每次改动。新条目追加到顶部。格式:
日期 — 改动概述,正文按新增 / 变更 / 修复 / 移除分类。链接 PR / commit / 相关文档(如有)。
.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_7d → day,首屏即看昨日的拼团漏斗(数据 T+1,昨日为最大可查日);测试同步更新。HS-Data → HS 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 tab → button。Vitest 37 passed、build clean。docs/04 §5 同步。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」。FunnelChart 改 React.lazy + Suspense,拆出独立 chunk —— 主包 1.56MB → 510KB(echarts 1.05MB 按需加载,非漏斗页不加载)。ThemeToggle):顶栏 Sun/Moon 切换,偏好存 localStorage,main.tsx 首屏前应用避免闪烁。Target 换为自绘漏斗 glyph(与 favicon 统一)。findByTestId 适配懒加载)。docs/01/docs/02/docs/04 + apps/web):
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。docs/01/docs/02/docs/04 + apps/web):
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。apps/web,落地 docs/01 §2):左侧导航由 5 个扁平能力域改为多级 L1 能力域 + 三级导航树(L1 能力域 → L2 分析模块 → L3 报表)。
routes/domains.ts 的 NAV 树 + layout/NavTree.tsx(递归渲染、仅展开当前分支、按深度缩进);App.tsx 由树自动生成路由(父节点重定向到首个叶子,可用叶子 → 页面,余 → 占位)。/behavior/funnel/group(= 行为分析 > 漏斗分析 > 拼团漏斗);/ 重定向至此。其余 L1/L2 出"待开发"占位。AppLayout 抽出导航为 NavTree,保留既定主题/三段式布局/抗抖滚动模型;docs/04 §3 导航说明同步更新。vite build clean(本机实跑)。docs/01 v2.0):由 5 个扁平能力域升级为主流数据平台通用的三级 IA(L1 能力域 → L2 分析模块 → L3 报表/实例),参考神策 + 网易有数/阿里 OneData/Aloudata 指标平台/CDP。
行为分析 > 漏斗分析 > 拼团漏斗(固定) 端到端,余 L1/L2 进导航出"待开发"占位。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 迁移基础上):
#04CB94、文本 #1F2D3D、底 #F9FAFC(非纯白)、弱化 #99A9BF、淡 mint #DEFFF6、错误 #EF4444;默认亮色(.dark 备而不用)。#064E3B→#04CB94,块宽按真实 UV 比例。DateField 自带「单日」标签 + 高亮 active 态)替代「单日」Tab;Tabs 仅留近 7/30 天。AppLayout):根容器 min-h-screen → h-screen overflow-hidden,令 <main> 为唯一滚动区 + scrollbar-gutter:stable,横向不再因滚动条出现/消失而抖;骨架高度对齐内容,竖向不跳。apps/web):
yesterday|last_7d|last_30d → day|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 取不同数)、missing 时 snapshot_dt: null、保留 ?missing=1、VITE_USE_MOCK 默认开。react-day-picker@10 + date-fns@4,新增 components/ui/{calendar,popover}.tsx。保留既定 mint 主题、AppLayout、漏斗渐变、抗抖骨架不动。vite build clean(本机实跑)。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_dt 走 WHERE dt=:dt,否则最新 dt,列 uv_start/show/detail/order/paid);last_7d/last_30d → rolling 唯一行,取 uv_*_7d / uv_*_30d。day 的 snapshot_dt 上限昨日(T+1),今天/未来 → 422;非存在 dt → missing。第 3 步展示名由「详情」改为「拼团详情」。data_status 仍 ready|missing,不补零。FakeFunnelRepository(USE_FAKE_DATA 默认开)兜底:造约 10 天递减历史 daily 行(截至昨日,支持日期选择器回溯、不同 snapshot_dt 取不同数据)+ 1 行 as-of 昨日 rolling;无 DB 即可起。seed 脚本同步改插 10 daily + 1 rolling。models.py(两 ORM 模型)、repository.py/funnel.py/schemas.py/api/funnels.py;更新 README.md、.env.example。openapi.json(Period=day/last_7d/last_30d、请求含 snapshot_dt)。docs/02 §1 已改:React + Vite + TS + Tailwind v4 + shadcn/ui(radix-nova/neutral)+ ECharts + TanStack Query,Ant Design 退出技术栈。@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.json 和 src/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 行为不变。vite build clean(本机实跑)。dev server 起在 :5173。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 漏斗转向条目原文保留:)
ads_trd_group_funnel 到位,替代原 bitmap 泛用漏斗方案):
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。app/services/bitmap.py、daily/period_event_bitmap 两表与迁移、pyroaring 依赖、相关测试/seed(挪到后续"泛用漏斗"阶段)。StepConfig、自定义 TimeRangePicker、15天/今天校验工具及其测试。apps/api/.venv 装齐依赖,后端测试本机可跑。否决"降级到 Python 2.7.5"(FastAPI/Pydantic v2 不支持)。Docker 仍未用(非管理员装不了),本地以 USE_FAKE_DATA 假数据替代。docs/01/02/03 与计划阶段 0–4):
git init(main)、根 package.json + pnpm-workspace.yaml、.gitignore/.nvmrc/.editorconfig;根脚本 dev:web/build:web/test:web/gen:api-types。infra/docker-compose.yml 起 PostgreSQL 16。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 层转化率 null、data_status 四态不补零;bitmap 计算走线程池不阻塞 event loop;seed 脚本(含缺失/损坏样本)、export_openapi.py、pytest 测试集(覆盖 docs/02 §8)。apps/web(React 19 + Vite + TS + AntD 5 + ECharts + TanStack Query):平台壳 + 五域导航;漏斗页四区 + 校验(≤15 天、今天不可选/不可提交);其余四域共用 Placeholder;按 data_status 显式渲染、null 转化率显示 “—” 不补零;mock 模式(VITE_USE_MOCK);Vitest 37 项测试通过。packages/api-types:接好 openapi-typescript 生成链(pnpm gen:api-types 读 apps/api/openapi.json),含占位 schema.ts。CLAUDE.md:项目协作守则(思考优先、简单优先、外科手术式改动、目标驱动、变更入 changelog)。CHANGELOG.md:本文件。apps/api 代码与测试按 3.11 编写但未执行。gen:api-types 待后端用 python -m scripts.export_openapi 导出 apps/api/openapi.json 后运行;在此之前前端用 apps/web/src/api/types.ts(契约一致)。