- HANDOVER.md: 完整交接文档(架构/数据模型/API/业务流/已知坑/工作区状态/待办) - PRD-智能比价助手.md: 比价功能产品需求文档(供外部平台参考) - 数据维护脚本: 清理AI垃圾品类SQL、修复损坏标题SQL、线索重分类/重抓脚本
25 KiB
平台助手 — 项目交接文档
交接日期: 2026-09-30 交接对象: 接手继续开发的智能体 / 开发者 文档目标: 让接手方无需历史对话即可完整了解项目现状、架构、业务逻辑、已知问题与待办事项,可直接开始开发。
1. 项目是什么
平台助手(内部代号 pingtai) 是面向 B2B 采购场景的智能询比价工作台:
- 采集:自动抓取 3 家央企招标公告(中电建 / 新矿集团 / 中核集团),关键词+AI 双通道分类入库
- 线索管理:线索列表 / 详情 / 星级评分 / 状态流转(待复核 → 询价中 → 协作中)/ 跟进日志
- 询价发布:勾选线索一键发布到外部 B2B 产业平台(通过 MCP 通道调
publish_rfq),含发布前确认弹窗(补联系人/电话/地址)、物料清单 AI 提取、超长标题 AI 压缩 - 比价:供应商报价 Excel/CSV 上传 → 自动解析 → 商品对齐去重 → 三种采购策略对比(集中/拆分/限 K 家)→ 采购建议报告 + CSV 导出
- 生图:商品图片三阶段生成(图库 → Bing 搜索 → MiniMax AI 生成)
- 品类库:关键词优先 + AI 反哺的品类字典(ProductCategory)
- 管理后台:租户/用户/系统配置/计划/MCP 对接配置
在线地址(生产): https://direv.cloud(Nginx → Next.js 3001 / NestJS 4000)
演示账号: admin / admin123(username + password,不是 email)
2. 技术栈与架构
| 层 | 技术 | 说明 |
|---|---|---|
| 前端 | Next.js 14 App Router + React 18 + Tailwind CSS 3 | SPA 无路由,useState 切换 14 个页面组件 |
| 后端 | NestJS 10 + TypeScript | 13 个子模块,端口 4000 |
| 数据库 | SQLite + Prisma ORM | apps/api/prisma/dev.db,15 个模型 |
| 采集脚本 | Node.js / Python | scripts/tender-fetcher/,CrawlerService 用 execSync 调度 |
| AI | MiniMax M2.7 (推理模型) | 品类分类 / 物料提取 / 标题压缩,endpoint https://api.minimaxi.com/v1/chat/completions |
| 外部对接 | MCP (Streamable HTTP, POST) | 集成 Integration 表 → product_network B2B 平台 |
| 部署 | 腾讯云 172.81.241.109 + PM2 + Nginx + certbot | scripts/deploy.sh 一键部署 |
架构图
┌─────────────────────────────┐
浏览器(3001) ←│ Next.js 14 (pingtai-web) │
└─────────────────────────────┘
│ /api/*
┌────────▼─────────────────────┐
│ NestJS 10 (pingtai-api:4000) │
│ ├─ crawler: execSync 调脚本 │
│ ├─ lead: 评分/状态/发布 │
│ ├─ integration: MCP client │
│ └─ comparison/image/... │
└────────┬─────────┬───────────┘
│ │
SQLite(dev.db) MiniMax API
│
┌────────▼─────────────────────┐
│ MCP server (devbox:3002/8095)│
│ → product_network B2B 平台 │
└──────────────────────────────┘
⚠️ MCP server 端口 3002(Node)/8095(Java) 都在 devbox 开发机上,不是本地端口。平台助手本地 web 是 3001、API 是 4000。两套 MCP server 后端数据库不同,appId/appSecret 互不通用。
3. 目录结构
平台助手/
├── apps/
│ ├── web/ # Next.js 14 SPA
│ │ └── src/
│ │ ├── app/page.tsx # SPA 根,useState<Page> 切换页面
│ │ ├── components/ # 14 个页面 + AuthProvider/Sidebar/Providers/ErrorBoundary
│ │ └── lib/apiBase.ts# API_BASE (NEXT_PUBLIC_API_URL,本地回退 localhost:4000)
│ └── api/ # NestJS 10
│ ├── prisma/
│ │ ├── schema.prisma # 15 个模型
│ │ └── dev.db # SQLite
│ └── src/
│ ├── admin/ audit-log/ auth/ common/ comparison/ crawler/
│ ├── image/ inquiry/ integration/ lead/ product/ product-category/
│ ├── reports/ rules/ users/ prisma/
│ └── app.module.ts / main.ts
├── packages/shared/ # 共享 TS 类型(编译型,无运行时依赖)
└── scripts/
├── tender-fetcher/ # fetch-v1.2.js(中电建) fetch-xkgroup.py(新矿) fetch-cnncecp.py(中核)
├── direv-publish/ # direv 平台发布脚本(10 个 .py,历史保留)
├── parse_products.py # Excel/CSV → JSON(比价用)
├── search_image.py / process_image.py # 生图辅助
├── backfill_category.js / clean_category.js / reclassify_leads.js 等 # 数据维护
└── deploy.sh # 一键部署
4. 开发环境搭建
npm run setup # npm install + db:init(prisma generate → migrate → seed)
npm run dev # 同时启动前端(3001)和后端(4000)
npm run dev:api # 仅后端(nest start --watch,用 dist/ 编译产物)
npm run dev:web # 仅前端
npm run db:init # 改 schema 后必跑
npm run db:reset # 删 db 重来
npm run build # nest build + next build
npm run typecheck # tsc --noEmit 所有包(无 root tsconfig,各包独立)
npm run lint
npm run dev:daemon # nohup 后台启动(PID 写入 .dev-api.pid / .dev-web.pid)
npm run dev:stop # kill PID 文件记录的进程
端口速查(本地): web=3001, api=4000。⚠️ 本地 next dev 偶发 fallback 到 3000(3001 被 admin_new Vite 项目占用时),以终端实际打印为准。
后端陷阱
nest start --watch用dist/编译产物:Prisma schema 变更后必须npm run build -w apps/api重建 dist 再重启,单纯prisma generate不够- 端口 4000 残留进程:
dev:stop只杀 PID 文件进程,多余进程lsof -ti:4000 | xargs kill -9 - Prisma 变更流程:改 schema →
npm run db:init - 后端无测试框架
前端陷阱
- SPA 无路由:
page.tsx用useState<Page>切换,导航走onNavigateprop,参数走 props - 路径别名
@/→src/ - Prettier: noSemi, singleQuote, trailingComma: all, printWidth: 100
- Tailwind Token:
secondary(#0051d5),border-subtle(#E2E8F0),surface-container系
5. 数据库模型(15 个)
| 模型 | 用途 | 关键字段 |
|---|---|---|
| Lead | 线索核心表 | title/noticeId/detailUrl/level(C-B-A)/status/star/amount/category/organization/region/regionDetail/source/contact/phone/deadline/quantity/unit/notes/aiScore/scoringDetails/publish/publishTime/inquiryNo/direvUrl/assignedTo/followLogs;@@unique([source, noticeId]) 去重键 |
| Rule | 规则中心 | name/type/config(JSON)/enabled |
| RuleVersion | 规则版本 | ruleId/version/config/userId |
| Report | 报表 | title/type/status/config/channels/fileUrl |
| AuditLog | 审计日志 | action/detail/operator/ip |
| CrawlerConfig | 采集器配置 | name/targetUrl/status/type(bid_xxx)/sourceName/scriptPath/schedule(cron)/keywords/categories(JSON品类名数组)/lastRunAt/totalRuns/successRuns/failedRuns |
| Inquiry | 询价(历史表) | 类似 Lead,冗余保留 |
| Product | 供应商报价条目(比价) | name/spec/unit/price/quantity/category/brand/supplier/minOrder/imageUrl |
| Tenant | 租户 | companyName/plan/status/validUntil/platformUrl/apiKey |
| User | 用户 | email/username/password/role/tenantId |
| GeneratedImage | 生成图片 | productName/url/status/style/sourceHash |
| ImageLibrary | 图库 | productName/keyword/filePath/source(baidu)/style/ratio |
| SystemConfig | 系统配置 | key(unique)/value/group |
| Integration | MCP 对接配置 | name/endpoint/appId/apiKey(AES-256-GCM 加密)/customerCode/status/tools/companyUserId |
| ProductCategory | 品类字典 | name(unique)/keywords(JSON数组)/isAIGenerated |
种子数据(seed.ts)
- 15 电缆型号 × 5 供应商 = 75 Product + 管理用户(admin/admin123)
- crawlerConfig 3 条:中电建 + 新矿集团 + 中核集团(中核默认 paused)
6. API 端点总览
认证 /api/auth
| POST /api/auth/login | 登录(username+password,JWT 存 localStorage auth) |
| GET /api/auth/profile | 当前用户 |
线索 /api/leads(核心)
| GET /api/leads | 列表(query: status/level/search/star/source/category/assignedTo/timeRange + 分页) |
| GET /api/leads/stats | 统计(OverviewPage 用) |
| GET/PUT/DELETE /api/leads/:id | 详情/更新/删除 |
| POST /api/leads/:id/to-rfq, /to-collab | 状态流转:转询价 / 转协作 |
| POST /api/leads/:id/publish | 发布到 B2B 平台,可选 body {contactPhone?, contactName?, deliveryAddress?} |
| POST /api/leads/batch-publish | body {ids: string[]},循环调 publish |
| POST /api/leads/:id/follow-up (+ /:index/delete) | 跟进日志 |
| POST /api/leads/:id/level | 改优先级 |
| POST /api/leads/calculate-score | 重算 AI 评分 |
采集器 /api/crawlers
GET/POST/PUT /api/crawlers(:id) | CRUD POST /api/crawlers/:id/run, /pause, /resume | 运行/暂停/恢复(联动 cron 注册)
比价 /api/comparison
GET /api/comparison | 商品分组比价数据 POST /api/comparison/upload | multipart file+supplier 上传报价 POST /api/comparison/suggestion | 生成采购建议报告
品类 /api/categories
GET/POST/PUT/DELETE | ProductCategory CRUD(InquiryPage 筛选项动态加载)
其他
/api/products+ upload-image(商品管理)/api/imagesgenerate/parse/approve/regenerate(生图)/api/integrations+ :id/connect/disconnect/call-tool + test(MCP 配置)/api/admintenants/users/plan-config/configs/stats(管理后台)/api/rules+ versions/rollback/api/reports+ :id/send/api/inquiries//api/users//api/audit-logs//api/health/api/lead-notes/extract/:leadId(notes 提取)
7. 前端页面清单(14 个)
| 页面组件 | 功能 | 数据对接状态 |
|---|---|---|
| LoginPage | 登录 | ✅ POST /api/auth/login |
| OverviewPage | 概览(统计卡片+线索列表) | ✅ Promise.all([leads/stats, leads]) |
| InquiryPage | 询价列表 + 筛选/搜索/星级/批量发布 + 发布前确认弹窗 | ✅ leads + publish(含弹窗传 overrides) |
| LeadDetailPage | 线索详情 + 状态流转 + 跟进日志 | ✅ leads/:id + 各流转端点 |
| ComparisonPage | 比价三步向导(上传→对比→建议) | ✅ comparison 三端点 |
| ProductPage | 商品管理 + 生图 | ✅ products + upload-image |
| ImagePage | 图片库/生成 | ✅ images |
| RuleCenterPage | 规则中心 + 采集器配置 Tab(品类多选框) | ✅ crawlers + categories |
| ReportCenterPage | 报表 | ⚠️ 纯 mock |
| SystemMonitorPage | 系统监控 | ⚠️ 纯 mock |
| AdminPage | 管理后台(5 子区块:租户/用户/统计/configs/计划,configs 含 MCP 对接配置) | ✅ 已实现 |
| Sidebar / Providers / AuthProvider / ErrorBoundary | 框架 | — |
8. 核心业务流程
8.1 采集入库(crawler.service.ts)
CrawlerService.run(config)
├─ type=bid_powerchina → runPowerChina(): execSync('node fetch-v1.2.js --keyword "X"')
├─ type=bid_xkgroup → runGenericScript(): execSync('python3 fetch-xkgroup.py')
└─ 其他 bid_xxx → runGenericScript()(脚本名从 type 推断)
↓
results → categoryInference.batchInfer() # 品类推断(关键词匹配 → 未命中走 MiniMax)
↓
upsert 到 Lead(去重键 @@unique([source, noticeId]))
关键词解析(resolveKeywords,最近重构):
- 优先
config.categories(品类名数组)→ 查 ProductCategory 表把每个品类的 keywords 展开合并 - 兜底
config.keywords(旧字段,直接解析) - 都没有 →
[''](抓全部)
中电建特殊处理: 每个关键词有独立状态文件 downloaded_<keyword>.json(不是只有一个 downloaded.json);结果从 ~/Desktop/招标公告/<date>/downloaded_<kw>.json 读取。~/desktop 是 symlink → /data/pingtai(生产持久化)。
公告 ID 提取坑: substr(summary, instr(summary, '公告ID:') + 6, 32)(+6 而非 +8,字节/字符偏移曾出 bug)。
8.2 品类分类(品类方案 C:关键词优先 + AI 反哺)
采集入库/手动回填时对线索标题:
1. 关键词匹配 ProductCategory.keywords contains 标题 → 命中直接写
2. 未命中 → MiniMax API 分类 → 写品类 + 反写关键词到 ProductCategory
3. 同类标题下次直接走关键词,不再调 AI
- 关键文件:
product-category/category-inference.service.ts(AI 推断+反写)、crawler.service.ts batchInfer()、notes-extractor.service.ts(PDF/HTML 提取要点) - MiniMax 配置:endpoint
https://api.minimaxi.com/v1/chat/completions,modelMiniMax-M2.7(envMINIMAX_MODEL可覆盖),key 在apps/api/.env的MINIMAX_API_KEY - ⚠️ M2.7 是推理模型:max_tokens 要够(物料提取正文 2000、标题提取 800),否则输出全被
<think>吃掉;输出常混<think>、让我分析、**加粗**等解释文字,需要清洗 - 历史经验:AI 不可全信,2026-07-01 曾批量回填 507 条,结果 AI 新建 ~25 个细分类需人工 review。决策:新数据走关键词,老数据人工 review
8.3 发布询价到 B2B 平台(lead.service.ts publishToDirev)
POST /api/leads/:id/publish { contactPhone?, contactName?, deliveryAddress? }
→ publishToDirev(id, overrides)
1. 组装 publishArgs(title/description/qty/notes/attachments/deadline/deliveryDate/contact...)
2. 企业级硬编码字段:
inquiryParty='郑州巨变网络科技有限公司', freightFlag=1(含运费), procurementType=1(公开采购),
invoiceType=2(增值税专票), quotationDemand=1(需要报价), validDays=7
⚠️ paymentMethod 不传(传了报"企业字典找不到")
⚠️ 上述 flag 必须 int,传字符串会报错(已修复过的坑)
3. 超长标题(>50字)→ TitleCompressorService.compress() AI 压缩 → 失败硬截断兜底
4. MaterialExtractorService.extractItems() 实时提取物料清单 items
5. integrationService.executeTool('publish_rfq', publishArgs)(retries:2)
6. 成功 → 更新 lead 状态(published/inquiryNo/direvUrl);失败 → ServiceUnavailableException
publishArgs 字段映射细节:
| 字段 | 来源 | 备注 |
|---|---|---|
| title | lead.title(>50 字先 AI 压缩) | 平台 varchar(50) 限制 |
| description | lead.notes → summary → title | W31 P1 |
| qty | lead.quantity || 1 | |
| notes | lead.notes | 商家报价时看到 |
| attachments | lead.attachments(JSON) || [detailUrl] | |
| deadline | lead.deadline 前 10 位 | YYYY-MM-DD |
| deliveryDate | deadline + 30 天 | |
| contactName | overrides.contactName → lead.contact → '待补充' | 弹窗可编辑 |
| contactPhone | overrides.contactPhone → lead.phone → '待补充' | 必填,弹窗补全 |
| deliveryAddress | overrides.deliveryAddress → regionDetail → region | 弹窗可编辑 |
| userId/enterpriseId | Integration.companyUserId | MCP connect 时获取 |
8.4 MCP 集成(integration.service.ts)
- 协议:Streamable HTTP(
StreamableHTTPClientTransport),POST 方法 - 认证头:
x-app-id+x-app-secret(多租户 APIKey,替代旧x-api-key),AES-256-GCM 加密存储(ENCRYPT_KEYin .env,32 bytes hex) - Session 管理(已实现):
buildSessionAwareFetch(integrationId)自定义 fetch wrapper——从 initialize 响应头提取mcp-session-id缓存 → 后续请求自动注入 → disconnect/重连清理 - charset 修复(已实现):wrapper 检测 content-type 缺 charset 时补
application/json; charset=utf-8(否则 Java 解析器中文 Content-Length 不匹配报 JSON 错误) - 17 个 MCP tool(询价5/商品4/比价4/推理4),发布调
publish_rfq
8.5 标题压缩(TitleCompressorService,新增)
- 位置:
apps/api/src/lead/title-compressor.service.ts(已注册到 LeadModule) - 逻辑:
compress(title, maxLength):title.length <= maxLength直接返回(≤50 字不调 AI)- 未配
MINIMAX_API_KEY→ 硬截断title.slice(0, maxLength) - 调 MiniMax,要求 JSON 结构化输出
{"title":"..."}(对抗 M2.7 多变思考噪音,行级正则过滤不可靠) extractJsonTitle()正则提取 title 字段;解析不到 → 硬截断- 结果仍超长 → slice 截断兜底
- max_tokens 800(400 会被明文思考耗尽导致答案截断)
- 生产验证:6 个真实标题全部压缩达标(62字→25字等)
8.6 比价(comparison.service.ts)
上传报价 (POST upload: file+supplier)
→ parse_products.py 解析 Excel/CSV → Product 入库
→ GET /api/comparison:
按 name.trim().toLowerCase() 分组 → 组内按 supplier 去重留最低价
→ 每组算 bestPrice/bestSupplier/savings/priceSpread
→ POST /api/comparison/suggestion:
三种策略对比:
A. 无限制拆分(每 SKU 选最低总价供应商)
B. 单一供应商(Σ 全 SKU 总价排名,取第 1)
C. 限制 K 家(C(n,K) 组合枚举 + 每 SKU 取组合内最低价,K=2/3/4)
→ recommendations 自然语言建议 + CSV 导出
8.7 生图(image.service.ts)
三阶段:图库(ImageLibrary) → Bing 搜索(search_image.py) → MiniMax AI 生成;process_image.py 去水印+裁剪+白底合成。
9. 已知问题 / 坑(接手必读)
9.1 生产部署相关(⚠️ 最近出现)
- 页面打开报"服务器内部错误" /
Failed to find Server Action(web 日志常见):- 根因:本地 build 的
.next/直接 rsync 到生产,生产node_modules版本与本地不一致 → Server Action ID 对不上 → 页面交互报错 - 解决办法(AGENTS.md 明确记录):在生产服务器上执行
cd /opt/pingtai/apps/web && npx next build重建.next,再pm2 restart pingtai-web - 若浏览器缓存旧 HTML 导致,提示用户强刷(Cmd+Shift+R)
- 根因:本地 build 的
- deploy.sh 不含 DB 迁移:Prisma 变更部署前,需在生产
apps/api/下手动npx prisma migrate deploy && npx prisma generate,否则 schema 不同步 pm2 restart默认不更新环境变量,需--update-env(deploy.sh 已带)
9.2 数据质量(采集器只抓列表页)
| 字段 | 填写率(2026-07-16 生产统计 815 条) | 说明 |
|---|---|---|
| contact | 0% | 采集器未访问详情页 |
| phone | 0% | 同上 |
| quantity | 0% | 同上 |
| unit | 0% | 同上 |
| notes | 0% | 同上 |
当前应对:发布前弹窗手动补全。自动化提取(类似 notes-extractor 的详情页 AI 提取)待实现。
9.3 MiniMax / AI
- M2.7 输出噪音(
<think>、让我分析、**加粗**)——所有 AI 调用都要清洗 - 生产
.env已配MINIMAX_API_KEY+MINIMAX_MODEL;本地.env需自行配置,否则走兜底 - 若
MAX_COMPRESS_LEN等常量调整,注意 PROMPT 里'45'是字符串 replace,保持一致
9.4 采集器
- 中电建 state 文件 key:
systemId_招采公告,不要手动删除 - 新矿集团脚本偶尔
ReadTimeout(日志见 Python traceback),不影响页面,重跑即可 - 新增采集器通用流程:放脚本到
tender-fetcher/,输出~/Desktop/招标公告/<date>/xxx_downloaded.json,前端新建 CrawlerConfig(type=bid_xxx、sourceName、scriptPath),无需改代码 - cron 用 6 字段格式(兼容 cron@4.4.0)
9.5 MCP / B2B 发布
code:10021 "未获取到用户信息":产业平台修复中(创建 APIKey 已关联 companyUserId,后端直接使用)paymentMethod传 "23" 报"企业字典找不到" → 不传,后端用默认- 字段类型必须是 int(freightFlag/procurementType/invoiceType),字符串会报错
- title 超 50 字已由 TitleCompressorService 前置处理
10. 当前工作区状态(未提交改动,2026-09-30)
⚠️ 接手第一件事:决定这些改动是否保留/提交/继续开发。
已改文件(未 commit)
| 文件 | 改动内容 | 状态 |
|---|---|---|
apps/api/src/lead/title-compressor.service.ts |
新文件:标题 AI 压缩服务(JSON 结构化输出方案) | ✅ 已实现+生产实测通过 |
apps/api/src/lead/lead.module.ts |
注册 TitleCompressorService | ✅ |
apps/api/src/lead/lead.service.ts |
publishToDirev 集成标题压缩(>50 字先压缩再校验) | ✅ |
apps/api/src/crawler/crawler.service.ts |
resolveKeywords(品类→关键词展开)+ 每关键词独立状态文件 + 日志增强 | ✅ |
apps/web/src/components/InquiryPage.tsx |
新增搜索框 fSearch → GET /api/leads?search= | ✅ |
apps/web/src/components/RuleCenterPage.tsx |
采集器配置从 keywords 改为 品类多选框(categories JSON 数组) | ✅ |
scripts/tender-fetcher/fetch-v1.2.js |
中电建脚本增强(过滤/回溯) | ✅ |
未跟踪文件
scripts/cleanup_garbage_categories.sql— 清理 AI 垃圾品类scripts/fix_corrupted_titles.sql— 修复损坏标题scripts/reclassify_leads.js/scripts/refetch_corrupted.js— 历史数据维护PRD-智能比价助手.md— 比价功能 PRD(供外部平台参考)
工作区 vs 生产差异
- 本地有大量未提交改动,生产未部署(生产
.next/构建于 2026-09-03) - 若需上线这些改动:
npm run typecheck→bash scripts/deploy.sh→ 生产重建 web.next(见 9.1)
11. 生产部署与运维
- 服务器:172.81.241.109(
SSH_HOST在 deploy.sh,如 IP 变更改这里) - SSH:
sshpass -p 'Jubianshuzi@2026' ssh ubuntu@172.81.241.109 - 一键部署:
bash scripts/deploy.sh(build + rsync dist/.next/源码 + pm2 restart --update-env) - 路径:代码
/opt/pingtai/,数据/data/pingtai/(dev.db / uploads / library / 招标公告) - 进程:pm2 托管
pingtai-api(4000) +pingtai-web(3001),systemd 自启 - 反代:Nginx 80/443 → 3001;
/api/*→ 4000;/uploads/*→/data/pingtai/uploads/ - HTTPS:Let's Encrypt,certbot 自动续期 timer 已开
- 常用操作:
pm2 list / pm2 logs pingtai-api / pm2 restart pingtai-api --update-env tail -f /var/log/pingtai/api.out-1.log sqlite3 /data/pingtai/dev.db # 直接查 DB tar czf pingtai-backup-$(date +%Y%m%d).tgz /data/pingtai/ - 历史包袱:服务器上旧 Postgres/Redis 部署备份在
/home/ubuntu/platform-assistant.bak-*,旧 nginx conf 在/etc/nginx/conf.d/platform.conf.bak-*,可回退 - 采集目录 symlink:
~/desktop -> /data/pingtai(必须指向/data/pingtai,不是/data/pingtai/招标公告,否则双层嵌套)
12. 待办事项 / 建议的下一步
- 决策未提交改动:title-compressor + crawler 品类化 + InquiryPage 搜索 + RuleCenterPage 品类多选框,是否继续/提交/部署
- 修复生产页面 500:若线上仍有 Server Action 报错,生产
npx next build重建(见 9.1) - 详情页内容提取(P1 数据质量):采集器入库后加类似 notes-extractor 的 AI 提取步骤,补 contact/phone/quantity/unit(当前全缺)
- 空品类历史线索 review:AdminPage 品类管理人工 review AI 新建的细分类(合并/删除)
- ReportCenterPage / SystemMonitorPage:仍是 mock,可接真实数据
- 比价模块增强(参考 PRD-智能比价助手.md):报价有效期、供应商画像权重、多租户
- MCP 发布卡点跟进:
code:10021等产业平台修复状态
13. 协作约定(对后续智能体)
- 语言:中文(对话/注释/文档/commit)
- 改动前必须对齐:涉及具体修改按 AGENTS.md 协作流程(7 个技术维度:场景/触发/重要程度/数据/边界/样式/部署),不擅自开干
- 例外:拼写错误、单文件 typo、用户明确"按你判断做"、紧急 bug
- 改完必须端到端验证,不只"代码看起来对"
- 涉及数据库结构、生产配置、依赖升级要明确告知用户
- 提交信息用中文
结束语: 本项目最核心的链路是 采集 → 分类 → 询价 → MCP 发布,接手时建议先跑通这条链路的本地/生产实测,再动其他模块。祝顺利!