Commit Graph

34 Commits

Author SHA1 Message Date
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 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 9d891fb702 feat: 为行程规划 agent 添加 get_travel_time 工具,调用高德驾车 API 验证交通时间
agent 之前完全靠 LLM 猜测地理距离,现在可以查询真实驾车时间,超过 30 分钟会换更近地点。
同时修复 dev 端口未生效的问题(next dev 加 --port 3721)。
2026-03-02 10:21:00 +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 fe9a52e2e4 fix: API 500 错误返回具体原因,便于线上排查 2026-03-01 21:59:23 +08:00
kurihada 3ccd1262f9 test: 添加完整测试套件(52 个文件,326 个用例)
基于 Vitest 搭建测试基础设施,覆盖后端纯函数、API 路由、
前端 hooks、UI 组件和页面级集成测试。
2026-02-28 20:19:14 +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
kurihada 61ef54b2bd feat: 盲盒想法输入增加 AI 灵感推荐
输入框下方展示灵感建议标签,点击即填入,降低创作门槛:
- 房间有 ≥2 条想法时调用 DeepSeek 生成贴合调性的推荐
- 想法不足或 AI 失败时 fallback 到 18 条静态灵感随机选 4 条
- 提交新想法后自动刷新推荐,支持手动换一批
2026-02-27 16:52:59 +08:00
kurihada 9c680ec11e feat: AI 周末行程规划 — DeepSeek 智能排期 + 高德 POI + 多日翻页
- 接入 DeepSeek API,提交想法时自动 AI 打标(品类/时段/时长/搜索策略)
- 新增行程规划 API:智能选取想法 → 高德 POI 搜索 → AI 生成最优行程
- 支持多日计划("整个周末"拆分周六/周日,并行 AI 调用)
- 行程展示逐日翻页,时间线可滚动,操作按钮固定底部
- 分享卡适配多日格式,支持图片保存与原生分享
- Prisma schema 新增 WeekendPlan 模型及 BlindBoxIdea AI 标签字段
- Jenkinsfile 集成 DEEPSEEK_API_KEY 环境变量
2026-02-27 01:51:47 +08:00
kurihada fbb2c22964 feat: 场景细分为餐厅/咖啡奶茶/甜品 + 附近搜索优先 + 美食多选标签 2026-02-26 23:04:25 +08:00
kurihada deba7ab2bb fix: AudioContext 复用 + 盲盒加载错误提示 + icon 按钮 aria-label
- #27: panic/blindbox/ShareCardModal/AuthModal 中 icon-only 按钮补 aria-label
- #28: playChime 缓存复用单个 AudioContext,避免超出浏览器 ~6 个上限
- #29: 已完成(上一批次 ApiError.name = "ApiError")
- #30: blindbox lobby fetchRooms 失败时显示"加载失败/点击重试"
- #31: 已完成(theme.ts VALID_THEMES 校验)
2026-02-26 20:25:56 +08:00
kurihada cf88d3a1d2 fix: 外部 API 错误处理 + 导航 URL 校验 + reset/narrow 错误反馈
- #22: 高德 API fetch 加 try/catch,失败返回 503 而非泛化 500
- #23: buildNavUrl 校验 location.split(",") 结果长度和非空
- #24: handleReset/handleNarrow 检查 res.ok,失败时 toast 提示
2026-02-26 20:20:59 +08:00
kurihada dfb3cfa136 fix: 服务端验证强化 — 房间ID/坐标/swipe/盲盒竞态/空格
- #15: 房间 ID 扩展为 6 位字母数字,createRoom 用 P2002 重试替代 find-then-create
- #16: 盲盒编辑/删除改用 updateMany/deleteMany 原子操作,防止 TOCTOU
- #17: lat/lng 用 Number.isFinite + 范围校验 (-90~90, -180~180)
- #18: swipe action 必须为 'like' 或 'pass'
- #19: user PUT 的 JSON.parse(preferences) 加 try/catch
- #26: requireString 拒绝纯空格字符串
2026-02-26 20:19:56 +08:00
kurihada 9c7f18e0fa fix: 用户名唯一性竞态处理 + 密码长度上限 + JSON.parse 安全
- #6: register/user PUT 捕获 P2002 返回 409,apiHandler 全局兜底
- #8: GET /api/user 的 JSON.parse(preferences) 加 try/catch 防崩溃
- #12: 密码校验加 128 字符上限防 DoS
- #29: ApiError.name 设为 "ApiError" 便于调试
2026-02-26 20:14:02 +08:00
kurihada 6488c19172 fix: theme.ts 所有函数添加 SSR 守卫,校验 localStorage 合法值
- setStoredTheme/applyTheme/initTheme 添加 typeof window 检查
- getStoredTheme 校验存储值是否在白名单中,防止非法 theme 值
2026-02-26 20:11:21 +08:00
kurihada 423b94440d refactor: 拆分 ShareCardModal(951 行 → 4 个模块)
- ShareCardModal.tsx (199 行): 模态框编排逻辑(图片生成、保存、分享)
- RestaurantShareCard.tsx: 餐厅分享卡片纯展示组件
- BlindboxShareCard.tsx: 盲盒分享卡片纯展示组件
- shareImage.ts: 图片工具函数(toPng 封装、dataUrl 转换、下载)
2026-02-26 19:54:12 +08:00
kurihada 07541ed686 refactor: 提取 useGeolocation hook 和 joinRoom 工具函数
- useGeolocation: 将 PanicPage 中 ~50 行 GPS 定位逻辑(requestGps + reverseGeocode + 状态管理)提取为独立 hook
- joinRoom: 统一 3 处重复的 POST /api/room/:id/join 调用(room、invite、panic 页面)
2026-02-26 19:49:05 +08:00
kurihada 0c5676493e refactor: 提取 UserAvatar、Input、Card 三个可复用 UI 组件
- UserAvatar: 统一头像渲染(5 种尺寸),新增 resolveAvatar 工具函数,替换 SwipeDeck 和 RoomManageModal 中的重复逻辑
- Input: 统一表单输入样式(4 种尺寸 + default/purple 变体),替换 AuthModal、ProfilePage、BlindboxPage 共 12 处
- Card: 统一卡片容器样式 + 可选淡入动画和延迟,替换 ProfilePage 中 7 处重复的 motion.div
2026-02-26 19:43:07 +08:00
kurihada 9641acbcbd refactor: 提取 buildNavUrl 工具函数,统一 room API 错误处理
- 将 MatchResult.tsx 和 profile/page.tsx 中重复的导航 URL 构建逻辑提取到 src/lib/navigation.ts
- 7 个 room API 路由从 return NextResponse.json({ error }, { status }) 统一改为 throw ApiError,由 apiHandler 统一捕获
2026-02-26 19:31:00 +08:00
kurihada 1229bb849b refactor: 提取 validation.ts 和 amap.ts,统一 API 路由校验逻辑
新增 validation.ts(用户名/密码/邮箱/内容/房间名/必填字段校验)
和 amap.ts(AMAP API key 校验),消除 7 个路由中的重复验证代码。
2026-02-26 19:22:17 +08:00
kurihada 19edcaeeb5 refactor: 提取 requireUserId/requireUser/requireMembership 校验工具
- 新增 requireUserId:统一 14 处 userId 非空校验,返回 401
- 新增 requireUser:统一 4 处用户存在性检查,返回 404
- validateMembership 升级为 requireMembership,直接抛 403
- 混合校验拆分为 auth(401) + 字段(400),状态码更准确
2026-02-26 18:17:17 +08:00
kurihada 0595887480 refactor: 引入 apiHandler + ApiError,消除 20 个路由的 try/catch 样板
- 新增 src/lib/api.ts:ApiError 错误类 + apiHandler 统一包装器
- 20 个 API 路由统一使用 apiHandler,删除重复的 try/catch 块
- 验证错误改用 throw new ApiError(),减少嵌套层级
- join/manage 路由的错误码映射改为直接抛出 ApiError
- 删除已无引用的 errorResponse 辅助函数
- 净减 273 行代码
2026-02-26 18:08:47 +08:00
kurihada 12279117f3 feat: 全局主题切换(浅色/深色/跟随系统)
- CSS 变量驱动的主题系统,所有颜色响应 data-theme 属性
- 新增语义化色彩 heading/secondary/tertiary,替换硬编码 text-white/text-gray-*
- 右上角三态主题按钮(自动/浅色/深色),全局可用无需登录
- layout.tsx 内联脚本防闪烁
- 修复个人中心页面溢出无法滚动
2026-02-26 15:15:32 +08:00
kurihada 7aa6c7f792 feat: 全局用户头像徽章,所有页面右上角统一显示
- 新增 GlobalUserBadge 组件,固定在右上角,已登录显示头像+用户名,未登录显示登录按钮
- 通过 layout.tsx 全局挂载,仅在个人中心页隐藏
- userId.ts 登录/登出时派发 nowhatever_auth 事件,组件实时响应
- 移除各页面重复的用户指示器(首页、极速救场、周末契约大厅、个人中心顶栏退出按钮)
- TopNav 右侧留出空间避免与全局徽章重叠
- 头像徽章采用暗色主题风格(bg-surface/80)
2026-02-26 14:42:40 +08:00
kurihada 14b0aaece4 feat: 盲盒房间体系重构 — 强制登录、独立房间、用户归属
- 新增 BlindBoxRoom/BlindBoxMember 模型,BlindBoxIdea 增加 userId/drawnById
- 新增房间 API(创建/加入/列表/详情),所有盲盒 API 增加认证和成员校验
- 新建盲盒大厅页面(三层引导式设计:未登录氛围页/首次创建引导/房间列表)
- 新建盲盒房间页面(成员校验/邀请分享/用户归属展示/自动聚焦)
- 首页删除契约画廊和 localStorage 盲盒逻辑,周末契约跳转到 /blindbox
- 清理旧路由 /room/[id]/blindbox
- 提取共享工具 src/lib/blindbox.ts(错误响应/房间号生成/成员校验)
- AuthModal 支持 defaultTab 参数
- 更新项目规范:新项目原则、代码优雅和复用优先
2026-02-26 12:25:32 +08:00
kurihada c86a6c0909 feat: 新增「喝什么」场景,支持奶茶/咖啡/酒吧等饮品店搜索
引入场景系统(SceneType),首页增加「吃什么」「喝什么」切换 Tab,
不同场景使用不同的高德 POI 类型、热门标签、价格区间和全链路文案。
场景信息存储在房间数据中,邀请/分享/匹配结果等页面自动适配。
2026-02-25 01:12:44 +08:00
kurihada 04c7b547aa feat: 用户名密码登录注册系统
- 新增 /api/auth/register 和 /api/auth/login 接口,使用 bcryptjs 哈希密码
- User 模型改为 username + passwordHash,id 自动生成 cuid
- 新增 AuthModal 组件(登录/注册双标签页),替换旧的 ProfileSetupModal
- 重写 /profile 页面:支持修改用户名、密码、头像、绑定邮箱、退出登录
- /api/user PUT 支持密码修改(需验证当前密码)和用户名唯一性校验
- 游客模式保留,右上角显示"登录"按钮;登录后显示头像和用户名
- 全局 nickname -> username 重命名(types、SwipeDeck、RoomManageModal、buildRoomStatus)
- 新增 logout() 清除登录态并重新生成游客 UUID
2026-02-25 00:21:03 +08:00
kurihada 801e922bb6 feat: 全员一致时增加 confetti 粒子特效、庆祝音效和默契度文案 2026-02-24 22:03:49 +08:00
kurihada 07ffe42176 feat: 房间创建者管理权限——锁定房间、踢人、结束投票 2026-02-24 21:01:24 +08:00
kurihada 8c0d89af6d feat: 用 SSE 替代 SWR 轮询,实现房间状态实时推送
SSE 断连时自动降级为 2s 轮询,重连后切回 SSE。
2026-02-24 19:51:30 +08:00
kurihada f6949a062f feat: 房间 24 小时自动过期,添加 TTL 清理机制 2026-02-24 19:46:14 +08:00
kurihada 77d15f29e3 fix: 修复竞态条件、重置逻辑、无匹配终态等关键问题
- 用 Prisma $transaction 实现 atomicUpdateRoom,防止并发写入覆盖
- 新增 POST /api/room/[id]/reset 端点,修复"再来一轮"按钮死循环
- 新增 swipeCounts 字段追踪滑动进度,检测"无人匹配"终态
- 着陆页 handleCreate 增加 res.ok 检查,防止跳转到无效房间
- 匹配或无匹配后停止轮询,减少无效请求
2026-02-24 17:04:16 +08:00
kurihada d87d30ccc0 feat: 实现 NoWhatever 别说随便餐厅决策 Web App
- Framer Motion 卡片滑动 UI,带物理阻尼动画
- 多人房间系统,4位房间号 + SWR 实时轮询
- 高德地图 POI v5 API 搜索附近餐厅
- Web Share API 一键邀请,剪贴板降级方案
- SQLite/Prisma 持久化存储
- 移动端优先响应式设计 (Tailwind CSS)
2026-02-24 16:49:43 +08:00