Commit Graph

171 Commits

Author SHA1 Message Date
kurihada f892c92608 Jenkins 改为容器化执行 Node 质量门禁与 E2E 2026-03-03 15:13:50 +08:00
kurihada 17cf80bed3 Jenkins 增加 Node 运行时自检与回退 2026-03-03 15:04:59 +08:00
kurihada cf7a7bd2e0 Jenkins 失败时归档 E2E 测试产物 2026-03-03 14:54:59 +08:00
kurihada b28c61ea3a 跑通 E2E 并修正执行链路与文档记录 2026-03-03 14:37:55 +08:00
kurihada c4c1cb400b 接入 E2E 门禁并固定 Playwright 执行版本 2026-03-03 14:06:40 +08:00
kurihada fe3016d710 新增 E2E 测试配置与用例并更新测试补充文档 2026-03-03 13:56:07 +08:00
kurihada 482307f2f4 清理 lint 剩余告警并更新审计文档状态 2026-03-03 13:53:19 +08:00
kurihada d91ea8c1e8 补充核心回归测试并完成补测清单 T1-T4 2026-03-03 13:33:42 +08:00
kurihada 3cd4c26d3c 新增测试补充执行文档并定义补测清单 2026-03-03 13:26:08 +08:00
kurihada 22610f0b59 统一盲盒前端 API 调用层并收敛错误处理 2026-03-03 13:17:42 +08:00
kurihada 532d8ff7ad 统一盲盒请求契约并移除冗余 userId 参数 2026-03-03 13:11:33 +08:00
kurihada 4a5ed3b25a 优化房间点赞同步为增量更新策略 2026-03-03 13:07:22 +08:00
kurihada 325b7b5742 优化计划查询避免 N+1 数据库访问 2026-03-03 13:05:29 +08:00
kurihada 41ac21ea12 完善 CI 质量门禁并启用覆盖率阈值 2026-03-03 13:02:31 +08:00
kurihada 4cd593bc30 修复定时器与动画回调清理不完整问题 2026-03-03 12:27:34 +08:00
kurihada 45dbac1935 修复 lint 阻塞错误并恢复门禁 2026-03-03 12:25:03 +08:00
kurihada 52b87abee3 修复 TypeScript 基线并补齐测试类型 2026-03-03 12:21:02 +08:00
kurihada 673dc1177e 修复计划接受流程的前后端状态不一致 2026-03-03 12:16:04 +08:00
kurihada 67fdf7427a 修复 SSE 成员校验未生效的问题 2026-03-03 12:14:38 +08:00
kurihada 724be69c76 修复 Jenkinsfile 中敏感信息硬编码问题 2026-03-03 12:12:17 +08:00
kurihada 5a6d457a87 修复 API 500 响应泄露内部错误细节 2026-03-03 12:11:02 +08:00
kurihada 486193c823 修复 suggest-item 接口缺失鉴权并补充测试 2026-03-03 12:08:35 +08:00
kurihada 8b4ab415fd fix: validate swipe restaurant ids against room candidates 2026-03-03 12:06:03 +08:00
kurihada f3d8a58603 fix: unify panic room code format and validate room join id 2026-03-03 12:04:00 +08:00
kurihada 4f4220652e refactor(P2/P3): 完成全部7批重构 — 模块化、SSE退避、无障碍、Zod校验、Server组件、Room关系化
批次A:重命名 + 路由拆分
- store.ts → roomRepository.ts,更新全部 import
- blindbox/plan/route.ts 精简为薄路由,业务逻辑抽取到 planActions.ts / planQueries.ts

批次B:blindboxPlanGen.ts 拆分(710行 → src/lib/plan/)
- agentPlan.ts:Agent 工具调用与系统提示
- legacyPlan.ts:非 Agent 备用生成逻辑
- ideaSelection.ts:Idea 筛选与 Slot 映射
- transitEnrichment.ts:交通信息查询与填充
- index.ts:runPlanGeneration 主入口

批次C:SSE 连接稳定性
- useRoomPolling.ts 加入指数退避重连(上限60s,含Jitter)
- plan/stream/route.ts 添加30s心跳 + abort信号清理

批次D:无障碍修复
- Modal:role=dialog、aria-modal、aria-labelledby
- AuthModal:aria-label关闭按钮、tablist/tab/aria-selected
- PlanItemEditModal、QrInviteModal:补全aria-label
- BlindboxPlan:图标按钮aria-label

批次E:Zod 引入
- src/lib/schemas/ai.ts:AI返回值 Schema(IdeaTagsSchema等5个)
- src/lib/schemas/requests.ts:请求体 Schema
- ai.ts 手工验证替换为 Zod safeParse

批次F:Server Components
- achievements/page.tsx → Server Component + AchievementsClient.tsx
- profile/page.tsx → Server Component + ProfileClient.tsx

批次G:Room 关系化模型
- prisma/schema.prisma:新增 RoomMember、RoomRestaurant、RoomLike、RoomSwipe 4张表
- migration:20260302010000_room_relational_model
- roomRepository.ts 完整重写(关系查询+应用锁)
- buildRoomStatus.ts 适配关系查询

测试:全部329个用例通过,修复68个因auth mock缺失导致的测试失败
2026-03-02 20:27:06 +08:00
kurihada 6bb0e65d4c refactor(P1): 5 项代码质量改进 — 消除重复、拆分巨型组件、统一基础设施
Task 4: 统一 amap.ts 为完整 API 客户端
- 扩展 amap.ts 为统一客户端(amapFetch 8s 超时 + 错误处理)
- 导出 searchPlaceText/searchPlaceAround/getInputTips/reverseGeocode/getTransitDirection
- 精简 4 个 location route 为单行调用,blindboxPlanGen 删除 ~80 行内联 API 代码

Task 2: 抽取 ShareCardShell 消除三兄弟重复
- 新建 ShareCardShell.tsx 共享外框/背景/品牌头/QR 底部
- RestaurantShareCard 406→268 行,BlindboxShareCard 341→173 行,BlindboxPlanShareCard 277→159 行

Task 3: 拆分 BlindboxPlan.tsx (742→371 行)
- 提取 planUtils.ts (guessCategory + formatDuration)
- 提取 PoiSearchField / SortablePlanItem / PlanItemEditModal 三个独立组件

Task 1: 拆分 blindbox/[code]/page.tsx 上帝组件 (1300→509 行)
- 提取 useBlindboxRoom / useBlindboxIdeas / useBlindboxPlan / useBlindboxDraw 四个 hooks
- 提取 BlindboxPoolPhase / BlindboxRevealPhase 两个子组件
- 主页面仅保留 phase 协调 + hook 组装 + 子组件渲染

Task 5: 统一 SWR 数据获取层
- 新建 fetcher.ts (FetchError 携带 status,401 不重试)
- 新建 useBlindboxRooms / useAchievements / useFavorites SWR hooks
- useRoomPolling 改用共享 fetcher
- blindbox 大厅/成就/个人中心页面删除手写 fetch 样板代码
- JWT 过期时自动弹出登录框而非反复重试
2026-03-02 18:05:06 +08:00
kurihada ce76980fe5 refactor(P0): JWT 认证、并发安全、错误日志三项安全加固
- 新增 JWT httpOnly cookie 认证链路 (jose),登录/注册签发 token,
  所有用户和盲盒 API 改为从 cookie 提取 userId,不再信任客户端传值
- 新增 /api/auth/logout 端点清除认证 cookie
- GET /api/user 区分 owner/非 owner,非 owner 不暴露 email
- atomicUpdateRoom 新增 per-room 应用层互斥锁,防止 SQLite 下并发 lost update
- 修复 getRoomData 中 fire-and-forget delete 改为 await
- 37 个静默 catch 块跨 17 个文件添加 console.error 日志
- 新增 REFACTOR_PLAN.md 全景分析文档
2026-03-02 17:24:26 +08:00
kurihada 99120a7042 feat: 交通信息与 AI 解耦,完善出发/回程路线显示
- 从 finalize_plan schema 和 agent 提示词中移除 transit 字段,AI 只负责活动/POI/坐标
- 新增 enrichTransitInfo:计划生成后查询高德 V3 公交 API,计算出发地→首活动、活动间、末活动→出发地三段交通
- parseTransitSegments 增加起终点站显示(去除线路名中的全程终点括号)
- WeekendPlanData 新增 transitFromStart/transitToEnd 字段
- BlindboxPlan 新增出发地和返回出发地交通连接器,传入 startLocationLabel 显示具体地址
- BlindBoxRoom schema 新增 address 字段存完整逆地理地址,city 保留供 API 使用
- 新增 /api/debug/transit 调试端点(仅开发环境)
- agent userPrompt 要求将出发/回程时间计入全天时间预算
2026-03-02 16:35:38 +08:00
kurihada e5a255a49e feat: 行程卡片间显示交通路线描述和时间
- get_travel_time 解析 Amap segments 提取线路名和站数
- PlanItem 新增 transitToNext / transitDescription 字段
- finalize_plan schema 加入 transit_to_next_description
- 修复 Turbopack 中文引号解析报错
- UI 连接器改为两行布局,路线描述与时长分行显示
2026-03-02 14:20:53 +08:00
kurihada 7b6ce22f63 fix: 修复行程卡片间距被 last:mb-0 清零的问题
每个 SortablePlanItem 被 motion.div 包裹,last:mb-0 会对
所有 item 生效导致 mb-5 失效,移除 last:mb-0 即可。
同步优化卡片内部间距、padding、reason 加分隔线。
2026-03-02 13:03:53 +08:00
kurihada 04a45c4894 feat: AI 辅助修改行程(自然语言调整 + 单活动替代推荐)
- 新增 refinePlan / suggestAlternativeItems 到 ai.ts
- 新增 POST /api/blindbox/plan/refine(整体行程调整)
- 新增 POST /api/blindbox/plan/suggest-item(单活动 AI 替代 + POI 搜索)
- BlindboxPlan 底部新增自然语言输入框(方案 A)
- 编辑 modal 内新增 AI 推荐替代方案卡片(方案 B)
- export searchPois 供 suggest-item 路由复用
2026-03-02 12:29:21 +08:00
kurihada 4e6a3e007c feat: 行程活动拖拽排序 + 编辑表单(含高德 POI 搜索)
- 安装 @dnd-kit/core/sortable/utilities/modifiers
- BlindboxPlan: 同天内拖拽排序(PointerSensor + TouchSensor,限垂直轴)
- BlindboxPlan: 点击编辑弹出 sheet modal,支持改时间(type=time)、时长、活动名
- BlindboxPlan: POI 字段改为高德 inputtips 搜索下拉,选中自动填入名称/地址/坐标
- BlindboxPlan: 搜索传入房间坐标 location 参数,结果按距离排序
- BlindboxPlan: 跨天移动通过 select 立即生效
- plan route: 新增 update_plan action,支持 PATCH 保存修改后的 days
- page.tsx: 新增 handlePlanDaysChange,乐观更新本地 state + 失败时回滚
2026-03-02 12:06:50 +08:00
kurihada df2e373beb feat: 改进计划生成体验与 AI 提示词
- 生成中状态改为滚动日志列表,底部新增消息自动滚动
- 返回想法池不再清空计划,pool 页面保留"待确认计划"横幅
- 换方案时才清空旧计划
- 提示词补充午餐/晚餐时间窗口约束(午餐11:30-13:00,晚餐17:30-19:30)
- get_travel_time 从驾车改为公共交通,阈值从30分钟调整为45分钟
2026-03-02 11:26:20 +08:00
kurihada b78063739b fix: 盲盒想法打标改为后台异步,新增 retag 补打接口
- applyTags 改为 fire-and-forget,用户投入想法立即返回(<200ms)
- 打标超时设为 60s,失败静默,由 /api/blindbox/retag 兜底
- 新增 POST /api/blindbox/retag:补打房间内所有无标签想法
2026-03-02 10:55:27 +08:00
kurihada 9d891fb702 feat: 为行程规划 agent 添加 get_travel_time 工具,调用高德驾车 API 验证交通时间
agent 之前完全靠 LLM 猜测地理距离,现在可以查询真实驾车时间,超过 30 分钟会换更近地点。
同时修复 dev 端口未生效的问题(next dev 加 --port 3721)。
2026-03-02 10:21:00 +08:00
kurihada ea49ce6081 chore: 端口从 3000 改为 3721 避免冲突 2026-03-02 01:07:45 +08:00
kurihada 7fd1005e03 feat: 行程规划改用 tool-calling agent,旧逻辑保留为降级方案
ai.ts 新增通用 runAgentLoop(),blindboxPlanGen.ts 拆分为
agent 主路径(list_ideas/search_poi/finalize_plan 三个工具)
和 legacy 降级路径,agent 失败时自动回退。
AI 思考和工具调用实时推送给前端。
2026-03-02 01:07:25 +08:00
kurihada 93499867d5 feat: 改进标签系统 — 新增品类/费用/强度/预约标签,timeSlot 参与选活动
- IdeaCategory 扩展 7→9,新增 experience(体验)和 nature(自然)
- 替换 outdoor boolean 为 costLevel/intensity/needsBooking 三个高价值字段
- AI 标注 prompt 同步更新,行程规划新增强度交替、费用平衡、预约提醒原则
- selectIdeasForSlots 重写为四优先级:timeSlot+category > category > timeSlot > 任意
- 前端想法卡片展示费用/强度/预约标签
2026-03-02 00:03:35 +08:00
kurihada bc2b0e40c6 fix: 修复生产数据库 schema 同步脚本的双重 IF NOT EXISTS bug
prisma db push 生成的 .schema 已自带 CREATE TABLE IF NOT EXISTS,
旧脚本的 sed 替换会生成 IF NOT EXISTS IF NOT EXISTS 导致 SQL 语法错误,
建表全部静默失败。现在只对 CREATE INDEX 做 IF NOT EXISTS 补充。
2026-03-01 22:44:44 +08:00
kurihada dfb7f464a0 fix: 改用 prisma db push 同步生产数据库 schema
旧的 sqlite3 手动同步脚本会静默吞掉建表失败的错误,
导致 BlindBoxMember 等表在生产环境从未创建成功。
改用 prisma db push 做 schema 同步,由 Prisma 自身保证正确性。
2026-03-01 22:12:25 +08:00
kurihada fe9a52e2e4 fix: API 500 错误返回具体原因,便于线上排查 2026-03-01 21:59:23 +08:00
kurihada 0e9d4ae43e fix: 修复 Vitest 4.x 构建兼容性问题
environmentMatchGlobs 在 Vitest 4 中已移除,改用 projects 配置;
排除 vitest.config.ts 不参与 Next.js 类型检查。
2026-03-01 21:51:14 +08:00
kurihada 3ccd1262f9 test: 添加完整测试套件(52 个文件,326 个用例)
基于 Vitest 搭建测试基础设施,覆盖后端纯函数、API 路由、
前端 hooks、UI 组件和页面级集成测试。
2026-02-28 20:19:14 +08:00
kurihada 11eeec868e Revert "feat: 从 SQLite 切换到 PostgreSQL"
This reverts commit 827fb761bd.
2026-02-28 18:27:42 +08:00
kurihada 827fb761bd feat: 从 SQLite 切换到 PostgreSQL
- Prisma provider 改为 postgresql
- docker-compose 新增 postgres 服务(带健康检查)
- Dockerfile 移除 sqlite3/template.db,改用 npm install prisma 做运行时 schema 同步
- docker-entrypoint.sh 简化为 prisma db push + node server.js
2026-02-28 17:47:01 +08:00
kurihada bf806f0891 fix: 改用 sqlite3 原生工具做 schema 同步,替代不可靠的 prisma CLI 方案 2026-02-28 17:33:49 +08:00
kurihada 3e7bb51618 fix: 房间加载失败时显示具体错误原因,便于线上排查 2026-02-28 17:30:09 +08:00
kurihada 039887547d fix: 容器启动时自动同步数据库 schema,解决线上部署后表结构不同步导致的加载失败 2026-02-28 17:24:03 +08:00
kurihada 1e39c72a63 fix(blindbox): 修复房间创建后返回大厅不可见 + 大厅房间列表管理
- 修复房主退出房间时误删整间房的问题,改为返回大厅(房间保留)
- 修复大厅页 fetchRooms 时序依赖导致导航回来不刷新的问题
- fetch 添加 cache:no-store + router.refresh() 确保数据始终最新
- 房间列表增加 max-h 滚动 + 底部渐变遮罩防溢出
- 大厅房间卡片支持内联删除/退出(··· 按钮 → 确认栏)
- rooms API 返回 creatorId 以区分房主/成员操作
2026-02-27 18:38:05 +08:00
kurihada 2d49744dd0 feat(blindbox): AI 计划生成流式进度与渐进式文案
- 新增 runPlanGeneration 与 onProgress 回调 (blindboxPlanGen.ts)
- 新增 POST /api/blindbox/plan/stream 推送 SSE 进度事件
- 前端优先走流式接口,实时展示「分析想法→搜索地点→规划路线→快好了」
- 流式失败时回退普通 POST,客户端轮播进度文案作为后备
- 规划阶段 UI 显示 planStatusMessage 替代静态文案
2026-02-27 17:37:40 +08:00