Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
24 KiB
JSON
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "big071/novadepot", "files": {"backend/.env.example": {"9a72c04d5988d008b7de63257ba7fa3a3d203690": {"t": 1785747093.0433364, "n": 815, "h": "7642fd5ba4677241", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=novadepot_user\nDB_PASSWORD=CHANGE_ME_LOCAL_DB_PASSWORD\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=CHANGE_ME_32_PLUS_RANDOM_CHARS_LOCAL_ONLY\nAPP_CORS_ALLOWED_ORIGINS=http://localhost:3100,http://127.0.0.1:3100,http://localhost:5173,http://127.0.0.1:5173\nAPP_UPLOAD_MAX_FILE_SIZE=10MB\nAPP_UPLOAD_MAX_REQUEST_SIZE=10MB\nAPP_MAX_REQUEST_BODY_BYTES=10485760\nAPP_AUTH_LOGIN_RATE_LIMIT_ENABLED=true\nAPP_AUTH_LOGIN_RATE_LIMIT_MAX_FAILURES=10\nAPP_AUTH_LOGIN_RATE_LIMIT_WINDOW_SECONDS=300\nAPP_AUTH_LOGIN_RATE_LIMIT_LOCK_SECONDS=300\nAI_PROVIDER=deepseek-chat\nAI_DEEPSEEK_ENABLED=false\nAI_DEEPSEEK_API_KEY=\nAI_DEEPSEEK_BASE_URL=https://api.deepseek.com\nAI_DEEPSEEK_CHAT_MODEL=deepseek-chat\nAI_DEEPSEEK_REASONER_MODEL=deepseek-reasoner\n"}, "321b7b4740555c19596bc443ffb6c091d3b253fc": {"t": 1785770364.4972477, "n": 815, "h": "7642fd5ba4677241", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=novadepot_user\nDB_PASSWORD=CHANGE_ME_LOCAL_DB_PASSWORD\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=CHANGE_ME_32_PLUS_RANDOM_CHARS_LOCAL_ONLY\nAPP_CORS_ALLOWED_ORIGINS=http://localhost:3100,http://127.0.0.1:3100,http://localhost:5173,http://127.0.0.1:5173\nAPP_UPLOAD_MAX_FILE_SIZE=10MB\nAPP_UPLOAD_MAX_REQUEST_SIZE=10MB\nAPP_MAX_REQUEST_BODY_BYTES=10485760\nAPP_AUTH_LOGIN_RATE_LIMIT_ENABLED=true\nAPP_AUTH_LOGIN_RATE_LIMIT_MAX_FAILURES=10\nAPP_AUTH_LOGIN_RATE_LIMIT_WINDOW_SECONDS=300\nAPP_AUTH_LOGIN_RATE_LIMIT_LOCK_SECONDS=300\nAI_PROVIDER=deepseek-chat\nAI_DEEPSEEK_ENABLED=false\nAI_DEEPSEEK_API_KEY=\nAI_DEEPSEEK_BASE_URL=https://api.deepseek.com\nAI_DEEPSEEK_CHAT_MODEL=deepseek-chat\nAI_DEEPSEEK_REASONER_MODEL=deepseek-reasoner\n"}, "d2b6092be8229dbd1140ce06f7ee2cdb0e80d811": {"t": 1785770365.8921857, "n": 403, "h": "65677c1419dcd7cb", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=root\nDB_PASSWORD=root\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=change_me_in_dev_please\nAI_PROVIDER=deepseek-chat\nAI_DEEPSEEK_ENABLED=false\nAI_DEEPSEEK_API_KEY=sk-your-api-key-here\nAI_DEEPSEEK_BASE_URL=https://api.deepseek.com\nAI_DEEPSEEK_CHAT_MODEL=deepseek-chat\nAI_DEEPSEEK_REASONER_MODEL=deepseek-reasoner\n"}, "263c940f83a3db013f296478d9a052b97e559955": {"t": 1785770367.475781, "n": 182, "h": "600e5c6493d1c127", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=root\nDB_PASSWORD=root\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=change_me_in_dev_please\n"}}, "roadmap/02-v1.2-deepseek-intelligence-core.md": {"9a72c04d5988d008b7de63257ba7fa3a3d203690": {"t": 1786067737.2009816, "n": 11423, "h": "30bba501ea0234d8", "c": "# v1.2 —— DeepSeek 仓库智能大脑\n\n> STATUS: PLANNED\n> 预估周期:8-12 周\n> 前置条件:v1.1 进销存闭环完成(购销数据是 AI 理解仓库的必要上下文)\n\n---\n\n## 1. 版本定位\n\n**把 DeepSeek 从\"占位符\"升级为 NovaDepot 的真正智能核心,让 AI 从\"关键词回复机器人\"变成\"懂仓库物流的数字专家\"。**\n\n### v1.0 AI 为什么\"笨\"\n\n| 问题 | 根因 |\n|------|------|\n| 只会关键词匹配 | `RuleAiProvider` 是 8 条 if-else,问法稍变就 miss |\n| 回答像模板填空 | 所有回复都是固定模板 + SQL 聚合结果拼接 |\n| 不理解上下文 | 问\"那个供应商的货到了吗\"——不知道\"那个\"指谁 |\n| 不会主动查数据 | 只能走预定义的规则查询,不能根据对话动态决定查什么 |\n| 多轮对话记忆弱 | 每轮独立处理,不记得上一轮说了什么 |\n| DeepSeek 根本没接入 | `DeepSeekChatAiProvider` 是纯占位符,返回固定字符串 |\n| 没有流式输出 | 用户等 2-8 秒看到完整回复,体验像\"系统卡了\" |\n| 不会调用工具 | AI 无法主动查询库存/订单/客服工单——只能等 RuleProvider 喂数据 |\n\n### v1.2 目标对比\n\n| 维度 | v1.0 (RuleAiProvider) | v1.2 (DeepSeek Intelligence) |\n|------|----------------------|------------------------------|\n| 理解方式 | 关键词匹配 | 自然语言语义理解 |\n| 回答来源 | 固定模板 + SQL 拼装 | LLM 推理 + 工具查询 + 知识库引用 |\n| 上下文 | 单轮无记忆 | 多轮对话上下文保持 |\n| 数据能力 | 仅库存/库存流水 2 张表 | 库存 + 采购 + 销售 + 工单 + 知识库全链路 |\n| 主动性 | 被动响应 | 可主动发现异常 + 推送预警 |\n| 输出体验 | 一次性返回全文 | 流式打字机输出 |\n| 底层引擎 | if-else 规则 | DeepSeek API(HTTP 调用) |\n\n---\n\n## 2. 核心矛盾\n\n| 矛盾 | 现状 | 目标 |\n|------|------|------|\n| AI 不懂仓库业务 | 关键词匹配,覆盖率 < 30% | DeepSeek 理解自然语言仓库问题,覆盖率 > 90% |\n| DeepSeek 从未对接 | Provider 是占位符,无 HTTP 调用 | 真实 HTTP API 集成 + 流式输出 + 降级策略 |\n| AI 不能主动查数据 | 只能走预定义 SQL 规则 | Function Calling:AI 自主决定查询哪些业务数据 |\n| 多轮对话无记忆 | 每轮独立处理 | 会话级上下文窗口 + 历史消息管理 |\n| 没有运营可视性 | 无报表/通知/预警 | 报表中心 + 通知中心 + Agent 定时巡检 |\n\n---\n\n## 3. 功能范围\n\n### 3.1 DeepSeek 真实接入 ⚠️ 核心改造\n\n> **目标**:用 DeepSeek API 替换占位符,实现真正的 LLM 推理。\n\n#### 3.1.1 HTTP 客户端集成\n\n| 能力 | 说明 |\n|------|------|\n| HTTP 调用 | 使用 Spring Boot `RestClient` 或 OkHttp 调用 DeepSeek Chat Completions API |\n| 端点 | `https://api.deepseek.com/v1/chat/completions` |\n| 认证 | Bearer Token,从 `app.ai.deepseek.api-key` 环境变量读取 |\n| 模型 | `deepseek-chat`(默认);管理员可切换 `deepseek-reasoner` |\n| 超时 | 连接超时 5s,读取超时 30s |\n| 重试 | 失败后自动重试 1 次(间隔 1s) |\n| 用量日志 | 每次调用记录 token 消耗 + 延迟,写入 `ai_usage_logs` 表 |\n\n#### 3.1.2 System Prompt 领域注入\n\n> **核心**:让 DeepSeek 知道自己在一个仓库管理系统里,理解业务上下文。\n\n```text\n## 角色\n你是 NovaDepot 仓库智能助手,服务于一个仓库管理团队(3-15 人)。\n你了解仓库管理、库存、采购、销售、客服工单等业务。\n\n## 当前上下文\n- 当前时间:{currentTime}\n- 当前用户:{userName},角色:{role}\n- 仓库:{warehouseName},SKU 总数:{totalSku},库存条目数:{totalItems}\n\n## 能力边界\n- 你可以查询系统内的库存、采购单、销售单、工单等数据\n- 你可以给出业务建议,但最终决策由人工确认\n- 如果你不确定某个数据是否存在,请使用工具函数查询\n- 所有回答基于系统数据,不凭空编造\n\n## 回答风格\n- 简洁、专业、结构化\n- 数据用表格或列表展示\n- 不确定时明确说明,不做猜测\n```\n\n#### 3.1.3 降级策略\n\n```\n用户提问\n → AiService 路由到 DeepSeekChatAiProvider\n → DeepSeek API 调用\n ├─ 成功(2s 内)→ 流式返回\n ├─ 超时(30s)→ 降级到 RuleAiProvider + 提示 \"DeepSeek 响应较慢,已切换为规则引擎\"\n ├─ 4xx 错误 → 降级到 RuleAiProvider\n ├─ 5xx 错误 → 重试 1 次 → 仍失败则降级\n └─ 网络不可达 → 降级到 RuleAiProvider\n```\n\n### 3.2 流式输出(SSE)⚠️ 核心改造\n\n> **目标**:用户发送消息后,AI 逐字输出,体验像聊天应用而非\"等结果\"。\n\n| 能力 | 说明 |\n|------|------|\n| 后端 SSE 端点 | `POST /api/v1/ai/chat/stream` 返回 `text/event-stream` |\n| 前端 EventSource | 使用 `EventSource` 或 `fetch` + `ReadableStream` 消费 SSE |\n| 打字机渲染 | 前端逐字符追加到消息气泡,不阻塞 UI |\n| 中断支持 | 用户可点击\"停止生成\"中断流式输出 |\n| 流式降级 | SSE 不可用时(如某些代理环境),降级为非流式请求 |\n\n**SSE 事件格式**:\n```\nevent: token\ndata: {\"content\": \"当前\"}\n\nevent: token \ndata: {\"content\": \"库存\"}\n\nevent: done\ndata: {\"conversationId\": 42, \"tokens\": 156}\n```\n\n### 3.3 Function Calling(工具调用)⚠️ 核心改造\n\n> **目标**:让 AI 能自主决定查询哪些业务数据,而非仅走预定义规则。\n\n#### 3.3.1 工具函数清单\n\n| 工具名 | 功能 | 输入参数 | 返回数据 |\n|--------|------|----------|----------|\n| `query_inventory` | 查询库存 | `productName?`, `warehouseId?`, `lowStock?` | 库存列表(产品/仓库/数量/可用数) |\n| `query_inbound` | 查询入库单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 入库单列表 |\n| `query_outbound` | 查询出库单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 出库单列表 |\n| `query_purchase` | 查询采购单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 采购单列表 |\n| `query_sale` | 查询销售单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 销售单列表 |\n| `query_tickets` | 查询客服工单 | `status?`, `assignee?`, `dateFrom?` | 工单列表 |\n| `query_product` | 查询产品 | `name?`, `sku?`, `category?` | 产品详情 |\n| `query_partner` | 查询往来单位 | `name?`, `type?` | 往来单位信息 |\n| `get_inventory_stats` | 库存统计概览 | `warehouseId?` | 总SKU/总数量/低库存数/滞销数 |\n| `get_daily_report` | 今日运营概览 | 无 | 今日入库/出库/新增工单/应收应付汇总 |\n\n#### 3.3.2 Function Calling 流程\n\n```\n用户:\"最近一周有哪些采购单还没到货?\"\n → DeepSeek 理解意图:查询最近7天状态为CONFIRMED/PARTIAL的采购单\n → DeepSeek 生成 function_call: query_purchase(status=\"CONFIRMED,PARTIAL_RECEIVED\", dateFrom=\"7天前\")\n → AiService 执行 query_purchase → 返回数据\n → DeepSeek 用数据生成自然语言回复:\"最近一周有3笔采购单尚未完全到货:\\n1. PO-20260420-001...\"\n```\n\n**OpenAI-compatible Function Calling 格式**(DeepSeek 兼容):\n```json\n{\n \"tools\": [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"query_inventory\",\n \"description\": \"查询当前库存情况,可按产品名称、仓库、是否低库存筛选\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"productName\": {\"type\": \"string\", \"description\": \"产品名称(模糊匹配)\"},\n \"warehouseId\": {\"type\": \"integer\", \"description\": \"仓库ID\"},\n \"lowStock\": {\"type\": \"boolean\", \"description\": \"是否仅查询低库存商品\"}\n }\n }\n }\n }\n ]\n}\n```\n\n### 3.4 多轮对话上下文\n\n| 能力 | 说明 |\n|------|------|\n| 会话历史 | 每个 conversation 保留最近 20 轮对话(40 条消息) |\n| 上下文窗口 | 将历史消息注入 DeepSeek 请求的 `messages` 数组 |\n| 上下文压缩 | 超过 20 轮后,对早期消息做摘要压缩(调用 DeepSeek 生成摘要) |\n| 会话切换 | 用户可新建会话、切换历史会话 |\n| 会话过期 | 24 小时无活动自动归档 |\n\n### 3.5 Agent 定时巡检 + 主动预警 ⚠️ 保留原规划\n\n> **前置**:Function Calling 已就绪,Agent 可以用同样的工具函数做巡检。\n\n| 能力 | 说明 |\n|------|------|\n| 低库存巡检 | 每小时检查所有产品库存,低于阈值自动生成预警通知 |\n| 单据超时预警 | 待审核超过 24h / 待执行超过 48h 的单据自动预警 |\n| 工单超时预警 | 待处理工单超过 4h 自动预警 |\n| 异常检测 | 库存为负 / 单次变动超过阈值 → 自动告警 |\n| 推送方式 | 站内通知中心 |\n\n**实现方式**:Spring `@Scheduled` 定时任务 → 调用 `AiService` 的工具函数查询 → 生成通知。\n\n### 3.6 报表中心\n\n| 报表 | 维度 | 说明 |\n|------|------|------|\n| 库存周转报表 | 产品/仓库/时间段 | 周转率、周转天数 |\n| 出入库日报/周报 | 时间汇总 | 入库量、出库量、净变化 |\n| 购销汇总 | 往来单位/时间段 | 采购总额、销售总额 |\n| 工单处理效率 | 客服/时间段 | 平均处理时长、关闭率 |\n\n- 图表:ECharts 柱状图/折线图/饼图\n- 支持日期范围筛选和 CSV 导出\n\n### 3.7 站内通知中心\n\n| 能力 | 说明 |\n|------|------|\n| 通知铃铛 | 页面顶部未读数量 badge |\n| 通知列表 | 全部/未读筛选、标记已读/全部已读 |\n| 通知类型 | 异常告警、超时催办、审核通知、Agent 巡检结果 |\n| 关联跳转 | 点击通知跳转到对应单据/工单页面 |\n\n### 3.8 前端优化\n\n| 优化 | 说明 |\n|------|------|\n| 骨架屏 | DataTable/图表/Dashboard 卡片首次加载用骨架屏替代 spinner |\n| ECharts 懒加载 | `defineAsyncComponent` + Vite `manualChunks` 独立拆包 |\n| API 错误中文映射 | `frontend-vue/src/utils/errorMapping.ts` 统一映射后端错误信息 |\n| 乐观更新 | 通知已读/状态切换先更新 UI 再异步确认后端 |\n| 流式渲染 | AI 对话页面接入 SSE 打字机效果 |\n\n### 3.9 打印模板\n> 从 v1.1 延续,本版本完善拣货单打印。\n\n### 3.10 审计日志清理\n\n| 能力 | 说明 |\n|------|------|\n| 保留策略 | 可配置保留天数(默认 90 天) |\n| 定时清理 | Spring `@Scheduled` 每日凌晨清理过期审计日志 |\n\n---\n\n## 4. 涉及页面\n\n| 页面 | 路由 | 操作 |\n|------|------|------|\n| AI 助手 | `ai/enterprise` | **重写**(接入流式输出 + Function Calling 结果展示) |\n| Agent 中心 | `agent/center` | 修改(增加定时巡检配置 + 预警规则管理) |\n| 通知中心 | `/notifications` | **新增** |\n| 报表中心 | `/reports` | **新增**(4 类报表 + ECharts 图表) |\n| Dashboard | `/dashboard` | 修改(预警卡片 + 通知入口 + 今日概览图表) |\n| AI Provider 配置 | `/settings/ai` | **新增**(切换 Provider、配置 API Key、查看用量) |\n| 所有单据详情页 | `/wms/*`, `/erp/*` | 修改(打印按钮) |\n\n---\n\n## 5. 涉及后端模块\n\n| 模块 | 操作 |\n|------|------|\n| `modules.ai.provider.DeepSeekChatAiProvider` | **重写**(真实 HTTP 调用 + System Prompt + 流式输出) |\n| `modules.ai.provider.DeepSeekReasonerAiProvider` | **重写**(同上,使用 deepseek-reasoner 模型) |\n| `modules.ai.service.AiService` | 修改(增加流式路由、Function Calling 编排、工具注册) |\n| `modules.ai.tools` | **新增**(10 个工具函数实现) |\n| `modules.ai.streaming` | **新增**(SSE 端点 + 流式响应管理) |\n| `modules.agent` | 修改(定时巡检调度 + 预警规则) |\n| `modules.notifications` | **新增**(站内通知 CRUD + 已读/未读) |\n| `modules.reports` | **新增**(报表聚合查询 + CSV 导出) |\n| `modules.auditlogs` | 修改(定时清理任务) |\n| `modules.settings` | 修改(AI Provider 配置 + API Key 管理) |\n\n---\n\n## 6. 涉及数据表\n\n| 表名 | 操作 | 说明 |\n|------|------|------|\n| `ai_usage_logs` | 新增 | AI 调用用量日志(provider/model/tokens/latency) |\n| `ai_tool_definitions` | 新增 | 工具函数注册表(可选,也可代码注册) |\n| `notifications` | 新增 | 站内通知 |\n| `agent_alert_rules` | 新增 | 预警规则配置 |\n| `report_cache` | 新增 | 报表查询结果缓存(可选) |\n| `ai_provider_config` | 新增 | AI Provider 配置(API Key/模型/参数) |\n\n---\n\n## 7. 配置项\n\n```yaml\n# application.yml 新增/修改\napp:\n ai:\n deepseek:\n enabled: true # 默认启用\n api-key: ${DEEPSEEK_API_KEY} # 环境变量\n chat-model: deepseek-chat\n reasoner-model: deepseek-reasoner\n timeout-seconds: 30\n max-retries: 1\n fallback-to-rule: true # 降级到 RuleAiProvider\n streaming:\n enabled: true\n buffer-size: 1024\n context:\n max-history-rounds: 20 # 多轮对话保留轮数\n session-ttl-hours: 24 # 会话过期时间\n tools:\n max-calls-per-turn: 5 # 单轮对话最多调用工具次数\n agent:\n patrol:\n low-stock-cron: \"0 0 * * * ?\" # 每小时\n overdue-order-cron: \"0 0 */4 * * ?\" # 每4小时\n audit:\n retention-days: 90 # 审计日志保留天数\n```\n\n---\n\n## 8. Provider 架构升级对比\n\n```\nv1.0 架构:\n 用户提问 → AiService → RuleAiProvider (if-else 关键词匹配)\n └── (DeepSeekChatAiProvider 是占位符,从未调用)\n\nv1.2 架构:\n 用户提问 → AiService → DeepSeekChatAiProvider\n ├── 构建 System Prompt(注入当前仓库上下文)\n ├── 构建 messages(历史对话 + 当前问题)\n ├── 注册 tools(10 个业务查询函数)\n ├── POST https://api.deepseek.com/v1/chat/completions\n ├── [如返回 function_call] → 执行工具函数 → 再次调用 DeepSeek 生成最终回复\n ├── [流式模式] → SSE 逐 token 推送\n └── [降级] → RuleAiProvider(兜底)\n```\n\n---\n\n## 9. 实施阶段\n\n### 阶段 A:DeepSeek 接入基础(第 1-3 周)\n\n```\nWeek 1-2: HTTP 集成 + System Prompt\n ├── RestClient 接入 DeepSeek API\n ├── System Prompt 模板管理\n ├── 非流式 chat 端点验证(先不做 Function Calling)\n ├── 降级策略实现\n └── 用量日志记录\n │\nWeek 3: 流式输出\n ├── 后端 SSE 端点\n ├── 前端 EventSource 消费\n ├── 打字机渲染\n └── 中断控制\n```\n\n### 阶段 B:Function Calling + 多轮对话(第 4-6 周)\n\n```\nWeek 4-5: Function Calling\n ├── 10 个工具函数实现\n ├── Tools JSON Schema 注册\n ├── Function Calling 编排(多轮调用)\n └── 工具调用结果注入回复\n │\nWeek 6: 多轮对话上下文\n ├── 历史消息管理\n ├── 上下文窗口限制\n └── 会话过期/归档\n```\n\n### 阶段 C:Agent 巡检 + 通知 + 报表(第 7-9 周)\n\n```\nWeek 7: Agent 定时巡检\n ├── 低库存/超时单据/异常检测定时任务\n └── 预警规则配置\n │\nWeek 8: 通知中心\n ├── 通知 CRUD + 铃铛 UI\n └── 关联跳转\n │\nWeek 9: 报表中心\n ├── 4 类报表聚合查询\n └── ECharts 图表 + CSV 导出\n```\n\n### 阶段 D:前端优化 + 打印 + 清理 + 回归(第 10-12 周)\n\n```\nWeek 10-11: 前端体验升级\n ├── 骨架屏 + ECharts 懒加载\n ├── 错误映射 + 乐观更新\n └── 打印模板完善\n │\nWeek 12: 审计清理 + 全量回归\n ├── 审计日志定时清理\n ├── E2E 全量回归\n └── Docker 部署验证\n```\n\n---\n\n## 10. 验收标准\n\n### DeepSeek 智能核心\n1. DeepSeek API 真实调用成功,能理解\"最近一周入库了多少货\"这类自然语言问题。\n2. AI 回答能主动查询库存/采购/销售/工单数据(Function Calling 正常执行)。\n3. 流式输出逐字展示,体验流畅,支持中断。\n4. 多轮对话能记住上下文(\"刚才说的那个供应商\"能被正确理解)。\n5. System Prompt 正确注入当前仓库/用户上下文。\n6. DeepSeek 不可用时自动降级到 RuleAiProvider,不中断服务。\n\n### 运营工具\n7. 报表中心提供 4 类报表 + 图表 + CSV 导出。\n8. 通知中心可见历史通知,标记已读,点击跳转关联页面。\n9. Agent 定时巡检自动发现低库存/超时单据并推送通知。\n\n### 前端体验\n10. AI 对话页面支持流式打字机效果 + 工具调用过程可视化。\n11. 骨架屏在 DataTable/Dashboard 加载时正确显示。\n12. API 错误信息展示中文友好文案。\n13. 打印模板在所有单据详情页可用。\n\n### 稳定性\n14. 现有 E2E 测试不回退。\n15. Docker 一键启动不受影响。\n16. 审计日志按时清理,不无限增长。\n\n---\n\n## 11. 不做什么(严格)\n\n1. 不做 RAG / 向量数据库 / 知识图谱。\n2. 不做 AI 模型训练/微调/LoRA。\n3. 不做多模型对比/AB 测试平台。\n4. 不做邮件/短信/企微等外部推送渠道。\n5. 不做自定义报表设计器 / BI 分析 / 实时大屏。\n6. 不做独立移动端 App / 离线模式 / 响应式适配。\n7. 不做通知订阅偏好配置。\n8. 不做多租户 / 计费(留到 v2.0)。\n\n---\n\n## 12. 风险与应对\n\n| 风险 | 应对 |\n|------|------|\n| DeepSeek API 不稳定/限流 | 自动降级 RuleAiProvider;用量日志追踪;API Key 多备 |\n| Function Calling 不准确 | 先用小范围工具测试,逐步扩展;每轮最多调用 5 次防无限循环 |\n| 流式输出在代理环境下不可用 | 检测 SSE 不可用时降级为非流式 |\n| System Prompt 被 LLM 忽略/绕开 | 回复中强制展示引用数据来源(工具查询结果原文) |\n| DeepSeek 回答内容不可控(编造数据) | 所有数据类回答必须来源于工具查询结果,AI 不允许凭空生成数字 |\n| token 成本不可控 | 用量日志 + 前端展示消耗;单次调用上限 4096 tokens |\n| Agent 定时任务增加 DB 负载 | 低频巡检(每小时/每4小时),使用只读从库查询 |\n| 上下文过长导致 token 浪费 | max-history-rounds=20,超限自动摘要压缩 |\n\n### 回滚策略\n- AI Provider 可一键切回 RuleAiProvider(管理后台配置)。\n- Agent 定时巡检可关闭。\n- 通知中心独立模块,关闭不影响主链路。\n- 流式输出可关闭,降级为非流式。"}}, "backend/docker-compose.backend.yml": {"9a72c04d5988d008b7de63257ba7fa3a3d203690": {"t": 1786068533.113997, "n": 2220, "h": "2cacdb4f294fd5f1", "c": "services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n container_name: novadepot-backend\n ports:\n - \"8080:8080\"\n environment:\n SPRING_PROFILES_ACTIVE: docker\n DB_HOST: mysql\n DB_PORT: 3306\n DB_NAME: ${DB_NAME:-novadepot}\n DB_USERNAME: ${DB_USERNAME:-root}\n DB_PASSWORD: ${DB_PASSWORD:-root}\n REDIS_HOST: redis\n REDIS_PORT: 6379\n JWT_SECRET: ${JWT_SECRET:-local_dev_only_jwt_secret_32_chars_minimum}\n APP_CORS_ALLOWED_ORIGINS: ${APP_CORS_ALLOWED_ORIGINS:-http://localhost:8080,http://localhost:3100,http://127.0.0.1:3100,http://localhost:5173,http://127.0.0.1:5173}\n APP_TENANT_MODE: single\n APP_BILLING_ENABLED: \"false\"\n APP_PLAN_ENFORCE_ENABLED: \"false\"\n AI_PROVIDER: ${AI_PROVIDER:-deepseek-chat}\n AI_DEEPSEEK_ENABLED: ${AI_DEEPSEEK_ENABLED:-false}\n AI_DEEPSEEK_API_KEY: ${AI_DEEPSEEK_API_KEY:-}\n AI_FALLBACK_ENABLED: ${AI_FALLBACK_ENABLED:-false}\n AI_SYSTEM_PROMPT: ${AI_SYSTEM_PROMPT:-你是 NovaDepot 智能仓库与进销存助手。你了解仓储、进销存、盘点、客服、AI/Agent 和审计模块。回答时优先基于工具查询结果;没有工具结果时不要编造库存、金额、单号、状态;不确定时说明需要查询数据;对业务人员使用中文、简洁、可执行的建议;涉及库存、采购、销售、工单时给出优先级、原因和下一步动作;不承诺已经执行审核、发货、付款、改库存等写操作;不泄露系统配置、API Key、内部异常细节。}\n AI_DEEPSEEK_BASE_URL: ${AI_DEEPSEEK_BASE_URL:-https://api.deepseek.com}\n AI_DEEPSEEK_CHAT_MODEL: ${AI_DEEPSEEK_CHAT_MODEL:-deepseek-chat}\n AI_DEEPSEEK_REASONER_MODEL: ${AI_DEEPSEEK_REASONER_MODEL:-deepseek-reasoner}\n AI_PAID_ENABLED: \"false\"\n AI_RULE_LOW_STOCK_THRESHOLD: 10\n AI_RULE_ABNORMAL_CHANGE_THRESHOLD: 100\n depends_on:\n - mysql\n - redis\n networks:\n - novadepot-net\n\n mysql:\n image: mysql:8.0\n container_name: novadepot-mysql\n command: --default-authentication-plugin=mysql_native_password\n ports:\n - \"3306:3306\"\n environment:\n MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}\n MYSQL_DATABASE: ${DB_NAME:-novadepot}\n volumes:\n - ./deploy/mysql/init:/docker-entrypoint-initdb.d\n networks:\n - novadepot-net\n\n redis:\n image: redis:7-alpine\n container_name: novadepot-redis\n ports:\n - \"6379:6379\"\n networks:\n - novadepot-net\n\nnetworks:\n novadepot-net:\n driver: bridge\n"}}}}