You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

29 KiB

查价项目

新人入口文档5 分钟了解项目、跑起来、别踩红线。
权威细节以 PRD / 技术设计 / 工程任务拆解为准;本文是索引与速查。

文档版本 v1.2
更新日期 2026-06-26
产品名 美美与共报价中台(查价系统)
代码仓库 chajia

AI 项目交接文档

供下一 AI 会话快速接手。执行日志:cursor_project_rules/implementation-plan.mdcStep 10.x~11.x

1. 项目核心身份 (Project Identity)

项目名称与一句话定义

美美与共报价中台chajia — 通过 Playwright RPA 抓取 MotherShip 公开报价页,一次询价返回多档 LTL 报价,经加价引擎输出给宿主系统内嵌查价组件;中台自身提供 admin 管理端预警、RPA 运维、队列监控)。

技术栈清单(来源:package.json / docker-compose.yml

类别 技术 版本
语言 TypeScript ^5.9.2
运行时 Node.js [需人工补充: 最低 Node 版本]
Web 框架 Next.js (App Router) ^15.5.6
UI React ^19.1.1
样式 Tailwind CSS ^3.4.19
组件 shadcn/ui 风格 + Geist 字体 + @phosphor-icons/react ^2.1.10
表单 react-hook-form ^7.79.0 + zod ^3.25.76
API Next.js Route Handlers
ORM Prisma ^6.19.0
数据库 MySQL 8.0docker image mysql:8.0
缓存/队列 Redis 7-alpine + ioredis ^5.8.1 + BullMQ ^5.78.1 本机 WSL 实测 6.0.16 有警告
RPA Playwright ^1.61.0;可选 playwright-extra + stealth
队列 UI Bull Board (@bull-board/* ^8.0.0) + Hono ^4.12.25
鉴权 jose ^5.10.0 + bcryptjs ^3.0.2
测试 Vitest ^3.2.4 + @playwright/test ^1.61.0
构建/脚本 tsx ^4.20.5
部署 Docker Composemysql/redis/next-app/rpa-worker

目录结构语义化说明

路径 职责 数据流向
app/ Next.js 页面与 API Routes薄路由层 宿主/Admin HTTP → modules/*
app/api/quotes/ 询价创建与轮询 modules/quote/orchestrator → BullMQ
app/api/addresses/mothership-candidates/ 地址候选、preheat、confirm → BullMQ address-candidates job
components/ 宿主内嵌查价 UI、管理端组件 hooks → API
modules/quote/ 询价编排、校验、幂等、fallback L1→L2→RPA→L3 状态机
modules/pricing/ 加价引擎(仅 raw_freight0~30% 读 MarkupConfig → 写 QuoteRecord
modules/cache/ Redis L1/L2/L3、限流、熔断 读写 Redis
workers/rpa/ BullMQ Consumer + Playwright 填表/抓价 消费 queue → 写 MySQL/Redis
workers/rpa/quote-capture/ Network-First 报价捕获axel/quote 契约解析) submit 后监听 network → normalize
workers/rpa/address-adapter/ 地址选择抽象real/mock DOM + axel search/place API
workers/rpa/kernel/ RPA 步骤编排address/cargo/quote steps 内部状态机
lib/ prisma/redis/response/rpa env 等基础设施 被 app/modules/workers 引用
prisma/ Schema、migrations、seed MySQL 持久化
scripts/ probe、prove、smoke、录证、准确度测试 CLI 验收/排障
cursor_project_rules/ AI 编码规则 + implementation-plan 逐步日志 必读
.rpa/ storageState、session、chain-proof 产物 勿提交敏感态gitignore
.dev/logs/ worker/next 运行日志、失败截图 排障

端到端数据流

宿主 EmbeddedQuoteWidget
  → POST /api/addresses/mothership-candidatesBullMQ RPA 枚举)
  → 用户确认弹窗
  → POST /api/quotesQuoteOrchestrator
  → L1/L2 未命中 → BullMQ quote-rpa job
  → workers/rpaopenQuotePage → fillAddress → fillCargo → submit → capture axel/quote
  → 写 L2/L3 + quote_record → GET /api/quotes/{id} 轮询返回

2. 当前开发状态快照 (Current State Snapshot)

已完成模块(单测/集成/E2E 在 Mock 或隔离路径下通过)

模块 验收依据
Phase 0~4 底座 M1POST /quotes、L2 缓存、幂等、校验 400
鉴权 RBAC + Service Token middleware + 单测
三级缓存 + 限流 + 熔断 redis-cache / rate-limiter 单测
加价引擎 engine.test.ts TC-103
询价编排 + fallback + 超时 sweeper orchestrator / timeout-sweeper 单测
BullMQ 队列 + Worker 管理 API rpa status/pause
宿主内嵌查价 UI + 地址确认弹窗 embed-demo + E2E
管理端(预警/RPA/队列/指标) admin 路由
CI lint + test:unit + test:integration + build .github/workflows/ci.yml
RPA v1.2 骨架 QuotePageAdapter、selector env、Network-First capture、contract guard
阶段 0 录证 .rpa/phase0/quote-contract-summary.jsonheaded 人工可拿到 axel/quote
货物填表mock 路径) fillCargoInDrawer + cargo-reset 单测

进行中任务

任务 进度 说明
M2-v1.2 真实 RPA probe 3/3 待跑 npm run probe:rpa:3x
人工 docx 系统验收 Done npm run probe:human-doc-system 10/10Direct 优先 → Widget fallback
task-133~135 CI probe 门禁 待执行 TC-601

最近 3 次关键变更

次序 变更 原因 影响模块
1 Step 11.75~11.78 Direct 优先报价 + preknown synthetic 地址 禁止 Widget 默认路径;修复 Bridge 误点 quote-strategy.tsmothership-address-adapter.ts
2 probe:human-doc-system 系统 API 全链路验收(非 RPA 直调) scripts/probe-human-doc-system.ts
3 代码库清理 删除过时修复计划、debug 脚本、废弃 re-export docs/scripts/workers/rpa/

3. 问题与阻塞项登记 (Issues & Blockers Registry)

2026-06-26 状态:人工 docx 10 组系统验收 probe:human-doc-system 10/10 PASS.rpa/human-doc-system-probe/system-e2583d51.json。BLK-001~003 在 preknown + synthetic 路径已缓解;回归以 npm run probe:human-doc-system 为准。

问题ID 状态 问题描述 复现路径/报错信息 已尝试的解决方案(含失败原因) 下一步建议方案 相关文件路径
BLK-001 已缓解 P0 地址 DOM 点选不触发 GET place/{placeId}commit 失败 历史embed-demo → worker no_place_request description-click / keyboard / pac-dispatch 等;11.77 preknown 跳过 legacy 点选、走 synthetic 新地址回归 probe:human-doc-systemheaded 录证见 docs/真人录证-commit时刻.md mothership-address-adapter.tsaddress-commit.ts
BLK-002 已缓解 P0 填 delivery 后 pickup 丢失widget 互斥) 历史dual-address pickupLostAfterDelivery=true 交替 refill11.48preknown synthetic11.77 同上 address-side.tsaddress-commit.ts
BLK-003 已缓解 submit 后无 axel/quotecontract=0 历史commit 失败导致无 quote 根因是地址未 commitDirect-first + Widget fallback11.75 监控 worker 日志 axel/quote;勿在 commit 通前改 contract 层 quote-capture/pipeline.tsquote-strategy.ts
BLK-004 已关闭 mock/fixture 假通过误导验收 prove:rpa-chain PASS 但价非 MotherShip mock-chain-fixture 已删除11.45 验收 RPA_ADDRESS_MODE=real + 无 fixture .rpa/chain-proof-72b4e980.json(历史样例)
BLK-005 已更新 direct POST axel/quote 价与 UI 不一致 历史direct 价偏低 11.75 Direct 优先、失败再 Widget fallback 勿单独启用 Widget 并行/预热 quote-strategy.tsaxel-quote-direct.ts
BLK-006 开放 L2 缓存假阳性 创建即 done + source_type=cache 探针用 uniqueWeight 防命中空 cache 验收前换 cargo 或 FLUSHDB modules/cache/redis-cache.ts
BLK-007 开放 端到端超时 420s commit 失败时前端超时 提 timeout 不能解决 commitcommit 通后约 23 分钟/单 commit 稳定后评估 browser warm/session lib/constants/quote.ts
BLK-008 开放 WSL Redis/MySQL 间歇断连 worker ECONNREFUSED 6379/3307 keepalive + orphan 回收 长跑前 npm run dev:infra:start lib/redis.tsqueue-recovery.ts
BLK-009 开放 候选 API 60~180s 慢 POST /api/addresses/mothership-candidates 枚举优化、Worker 队列 候选慢可接受;pickBestMothershipCandidate 降权 Bridge address-candidates.tspick-mothership-candidate.ts
BLK-010 开放 storageState 货物残留 摘要 2296Lbs vs 期望 500Lbs freshCargoContext + cargo-reset real 路径验证 assertWidgetCargoSummary cargo-reset.tssession-manager.ts
BLK-011 冻结 架构过度重构拖慢排障 kernel/驻留页多轮 11.30 放弃驻留页默认路径 冻结架构;仅改 adapter + commit workers/rpa/kernel/

根因链(历史 → 当前)

[历史] placeApiHitCount=0 → commit FAILED → 无 axel/quote → 420s 超时
[当前] preknown synthetic + Direct-first → probe:human-doc-system 10/10约 2.4min 全量)

4. 架构决策记录 (ADR)

ADR-1Network-First 报价捕获(禁止 DOM 刮价)

  • 决策:报价仅来自 services.mothership.com/axel/quote 网络响应,经 quote-contract-guard + payload-decode 解析;禁止 DOM price extraction。
  • 原因MotherShip SPA 档位与 DOM 不同步;阶段 0 HAR 已验证 API 契约稳定。
  • 权衡:放弃 DOM fallbacksubmit 后必须触发真实 quote 请求,强依赖地址/货物 commit 成功

ADR-2BullMQ 统一 RPA Worker候选 + 询价同进程)

  • 决策:地址候选与询价均入 BullMQ同一 workers/rpa/index.ts 消费;withRpaSessionLock 串行。
  • 原因spawn 子进程与 worker 双浏览器争用 .rpa/mothership-storage.json,行为不一致。
  • 权衡:单 worker 吞吐低Worker 不可用时才 spawn 回退stall 60s

ADR-3MotherShip 地址须用户确认 + place API commit

  • 决策RPA 枚举候选 → 前端弹窗确认 → 询价时按 display_label 点选commit 以 GET place/{placeId} 网络证据为准。
  • 原因PRD GD 要求点选;仅 DOM 填值不满足 MotherShip widget 状态机。
  • 权衡:端到端 180~360s当前 place commit 未打通即全链路失败

ADR-4Next.js Route Handlers 薄层 + modules 业务编排

  • 决策API Route 只鉴权/校验/调 orchestrator禁止 Route 内写复杂业务。
  • 原因可测试性、分层清晰、Worker 与 API 共享 modules。
  • 权衡:无 Server Actions宿主必须 HTTP 集成。

ADR-5放弃驻留页默认路径RPA_PARKED_SESSION=false

  • 决策:候选完成后不默认 park page询价 job 独立开页 + storageStatebrowser warm 保留。
  • 原因:驻留页需 worker+confirm+同进程,验证周期 >5min 且 fetch failed 频发;网络等待占 80%+。
  • 权衡:候选→询价无法零重开;性能优化有限。

5. 新 AI 接手指令 (Onboarding Instructions)

启动/运行命令

cp .env.example .env                    # 首次
npm run dev:infra:setup                 # WSL MySQL+RedisWindows 推荐)
npm run dev:start                       # infra + migrate + seed + next + worker + scheduler

# 分项
npm run dev                             # Next.js :3000
npm run worker:rpa                      # RPA Worker另开终端
npm run worker:scheduler                # 超时清扫

# 验证
npm run smoke:connect                   # MySQL/Redis
npm run verify:rpa-stack                # 四步全栈验收
npm run prove:rpa-chain                 # 端到端 → .rpa/chain-proof-*.json
RPA_HEADLESS=false npm run probe:rpa    # headed RPA 调试

# 测试
npm run lint
npm run test:unit
npm run test:integration
npm run test:e2e
npm run go-no-go -- --mock

# 停止
npm run dev:stop

环境变量依赖(名称为准,勿写值)

变量 用途
DATABASE_URL MySQL 连接(本地通常端口 3307
REDIS_URL Redis 连接
JWT_SECRET 管理端 JWT
HOST_SERVICE_TOKENS 宿主 Service Token → customer_id 映射
MOTHERSHIP_QUOTE_URLS RPA 入口 URL 列表(必填,禁止 dashboard
RPA_SELECTOR_* 8 项 Playwright selectorPICKUP/DELIVERY/WIDGET/STREET/SUGGESTION/CARGO/SUBMIT 等)
RPA_STORAGE_STATE_PATH Playwright storageState 路径
RPA_MOCK_MODE false=真实 RPAtrue 仅 CI/单测
RPA_ADDRESS_MODE real / mockmock 不能用于验收)
RPA_HEADLESS / RPA_HEADED 有头调试
RPA_BROWSER_LOCALE 推荐 en-US
RPA_BROWSER_CHANNEL 推荐 chrome
RPA_USE_STEALTH 默认 false(曾破坏 widget
RPA_PARKED_SESSION 默认 false
RPA_QUEUE_ENABLED Worker 是否消费队列
RPA_WORKER_ID Worker 标识(空则自动生成)
MOTHERSHIP_QUOTE_API_URL_PATTERNS axel/quote telemetry 白名单
MOTHERSHIP_EMAIL / MOTHERSHIP_PASSWORD 仅 login 页时需要
DEV_INFRA_MODE native / docker / auto
MYSQL_HOST_PORT / MYSQL_ROOT_PASSWORD Docker/WSL MySQL

首要任务优先级

  1. P0 回归门禁:npm run probe:human-doc-system 10/10改地址/RPA 后必跑worker 需 dev:stop + dev:start 重载)
  2. P0 实网验收:npm run prove:rpa-chainRPA_ADDRESS_MODE=real 下 PASS非 cache、非 fixture
  3. P1 embed-demo 标准样例LA 90001 → Dallas 752012 托 500lb返回 source_type=rpa 且价与 MotherShip 页面一致
  4. P2 M2 门禁:npm run probe:rpa:3x 连续 exit 0
  5. 禁止:在 commit 未通前改 timeout/stealth/contract/kernel/驻留页;禁止 Widget 并行/预热/默认路径

项目特殊约定

类别 约定
编码前必读 cursor_project_rules/global-rules.mdcimplementation-plan.mdcdomain-rules.mdc
分层 app/api 薄路由 → modules 业务 → workers/rpa 长任务
命名 DB snake_caseTS camelCase/PascalCaseenv UPPER_SNAKE
金额 DECIMAL(12,2)ROUND_HALF_UP;禁止 float 运算
界面文案 全部中文MotherShip 抓取字段除外)
红线 一次询价=1 次 RPAcache key 不含 service_level禁止 dashboard URL禁止 RPA mock 上线
Git 禁止 main 直推;不提交 .env/.rpa/ 敏感态
完成步骤 implementation-plan.mdcDone + 两行执行记录
禁止库/模式 禁止 DOM 刮价;禁止 mock-chain-fixture禁止 default dashboard URL禁止空 catch
Windows 开发 优先 npm run dev:startPowerShellWSL native infra 优于 Docker Desktop

关键产物路径

路径 内容
.dev/logs/worker-rpa.log Worker 实网日志
.dev/logs/rpa-failure-*.png RPA 失败截图
.rpa/chain-proof-*.json prove 链路报告
.rpa/dual-address-compare-*.json 双地址 network 对比
.rpa/phase0/quote-contract-summary.json axel/quote API 契约

项目信息

做什么

通过 Playwright RPA 抓取 Mothership 公开报价页,一次询价返回 4 档报价standard/guaranteed × lowest/fastest经加价引擎输出给宿主系统内嵌查价组件。中台自身仅提供 admin 管理端预警、RPA 状态、队列监控)。

不做什么MVP 边界)

  • 不使用 Mothership 官方 API
  • 无独立客户/运营登录、无运营加价 UI
  • 无 CC 对接、多币种、下单、对账、Priority1

技术栈

选型
Web Next.js 15App Router+ React 19 + Tailwind + shadcn/ui
API Next.js Route Handlers
数据 MySQL 8 + Prisma
缓存/队列 Redis 7 + BullMQ
RPA Playwright可选 Patchright
测试 Vitest + Playwright E2E
部署 Docker Compose

核心文档(按阅读顺序)

文档 用途
查价系统-PRD.md v0.6 业务规则、GD 决策、验收标准(最高业务权威
查价系统-技术设计.md v1.2 架构、目录、API、RPA 规格(实现权威
查价系统-工程任务拆解-v1.2.md 原子任务与开发顺序
查价系统-UI设计.md 页面、交互、状态机
参考-Mothership-RPA-开源借鉴与解阻塞.md RPA 排障参考
AI 项目交接文档 完整 handoff身份/状态/阻塞/ADR/接手指令
cursor_project_rules/ AI/人工编码规则与实施日志

目录结构(关键路径)

chajia/
├── app/                    # Next.js 页面 + API Routes
├── components/             # 前端组件(含宿主内嵌查价)
├── modules/                # 业务逻辑quote/cache/pricing/alert
├── workers/rpa/            # BullMQ Consumer + Playwright
├── lib/                    # prisma/redis/response/rpa
├── prisma/                 # schema + migrations + seed
├── scripts/                # probe、smoke、go-no-go、录制
├── __tests__/              # unit / integration / e2e
├── docs/                   # 产品与工程文档
└── cursor_project_rules/   # 项目规则 + implementation-plan

角色与鉴权

角色 方式 能力
宿主系统 Authorization: Bearer <HOST_SERVICE_TOKEN> customer_id 询价、历史、加价配置
管理员 JWT + RBAC 预警、RPA 运维、/admin/*

联调样例:

  • 宿主 token.envHOST_SERVICE_TOKENS(如 demo-host-tokenCUST_001
  • 管理端:admin_demo / Demo@123(仅开发环境)

联调标准样例

字段
路线 LA(90001) → Dallas(75201)
单托重量 500 lb
单托尺寸 48×40×48 in
托盘数 2
货物类型 general_freight

常用命令

环境准备

# 复制环境变量(勿提交 .env
cp .env.example .env

# 一键启动(推荐,含 infra + app + worker
npm run dev:start

# 仅 Docker infraMySQL + Redis
docker compose up -d mysql redis

# WSL/native infra 引导Windows 开发机)
npm run dev:infra:setup

数据库

npm run db:validate      # Prisma schema 校验
npm run db:migrate       # 本地迁移(开发)
npm run db:deploy        # 生产迁移
npm run db:seed          # 种子数据

开发运行

npm run dev              # Next.js :3000
npm run worker:rpa       # RPA Worker另开终端
npm run worker:scheduler   # 超时清扫 Worker
npm run dev:stop         # 停止本地进程
npm run dev:clean        # 清理临时产物

测试与门禁

npm run lint             # TypeScript 类型检查
npm run test:unit        # 单元测试
npm run test:integration # 集成测试
npm run test:e2e         # Playwright E2E
npm run test             # 全量 Vitest

npm run smoke:connect    # MySQL/Redis 连通
npm run smoke:api        # API 冒烟
npm run smoke:rpa        # 真实 RPA 冒烟(需 env 配齐)

# RPA 探针Go/No-Go 门禁:连续 3 次 exit 0
npm run probe:rpa
npm run probe:rpa:3x
npm run probe:human-doc-system   # 人工 docx 10 组,系统 API 全链路
npm run probe:random-address-quote
npm run go-no-go         # 上线前指标检查

RPA 录制与排障

# P0 真人完整链路录证HAR+录像+Trace+Console+Network定位 place commit 瞬间)
npm run record:human-commit-baseline
# 详见 docs/真人录证-commit时刻.md

# headed 录制 Mothership 报价流程 → 更新 MOTHERSHIP_QUOTE_URLS / RPA_SELECTOR_*
npm run record:mothership

# P0 真人 vs RPA 网络差分
$env:RPA_HEADLESS="false"
npm run compare:human-rpa-network

Docker 全栈

docker compose up -d --build
docker compose exec next-app npx prisma migrate deploy
docker compose exec next-app npx prisma db seed

访问地址

入口 URL
宿主内嵌演示 http://localhost:3000/embed-demo
管理端预警 http://localhost:3000/admin/alerts
管理端 RPA http://localhost:3000/admin/rpa
队列监控 http://localhost:3000/admin/queues

编码规范

分层(禁止跨层)

app/api/*          → 薄路由,只调 modules
modules/*          → 业务编排orchestrator、pricing、cache
workers/rpa/*      → 长任务 RPA不经 HTTP 直调 DB 以外层
lib/*              → 基础设施封装
components/*       → UI经 hooks/api 调后端
  • API Route 不得写复杂业务逻辑
  • RPA Worker 不得绕过 QuoteProvider 接口直接返回假数据CI 除外 RPA_MOCK_MODE=true

命名

范围 规范 示例
DB 字段 snake_case pallet_count, raw_freight
TS 变量/函数 camelCase cargoHash, getQuote
TS 类型/组件 PascalCase QuoteRecord, QuoteForm
环境变量 UPPER_SNAKE MOTHERSHIP_QUOTE_URLS
API 路径 kebab/REST /api/quotes/{quote_id}

金额与精度

  • 存储与计算:DECIMAL(12,2)
  • 舍入:ROUND_HALF_UP,保留 2 位
  • 禁止float / number 做金额运算

API 响应

统一包络:

{ "code": 0, "message": "ok", "data": { } }

错误使用标准 error_code(见 PRD §5.6 / domain-rules.mdc §10

异步与错误

  • 所有 async 必须 catchlog(禁止空 catch
  • 用户可见操作必须有 loading + 防重复提交 + 成功/失败反馈
  • 外部调用RPA/Redis/MySQL须处理超时与失败分类

前端

  • 界面文案一律中文(除 Mothership 原文抓取字段)
  • 查价表单须支持地址联想点选、pallet_count、kg/cm 展示与 lb/in 换算
  • 轮询:GET /quotes/{id},间隔 2s最长 30s

Git

  • 禁止在 main 直接开发;使用 feature 分支
  • Commitfeat|fix|docs|refactor(module): 描述(可附 PRD/任务编号)
  • 不提交 .env.rpa/ 敏感状态(除示例模板)

变更流程

  1. 先查 PRD / 技术设计 / implementation-plan.mdc 是否已有规则
  2. 数据结构变更 → Prisma migration → 再改代码
  3. 改逻辑 → 补/跑对应测试
  4. 完成一步 → 在 implementation-plan.mdc 标记 Done + 两行执行记录

红线(绝对不能违反)

业务红线

# 规则 违反后果
R1 一次询价 = 1 次 RPA,单次必须返回 4 档 成本翻倍、验收失败
R2 service_level / rate_option 不得进入 cache key 缓存串档、价格错误
R3 地址必须联想点选,须 place_id + selected_from_suggestions=true Mothership 拒单或 RPA 失败
R4 使用 pallet_count(托盘数),禁止件数/箱数字段 与 Mothership 口径不一致
R5 加价仅对 raw_freight,上限 30%;未配置客户 0% 财务口径错误
R6 L3 stale RPA 失败降级只读,正常路径不得读 L3 展示过期价
R7 MOTHERSHIP_QUOTE_URLS 必填且 headed 录制验证;禁止默认 dashboard.mothership.com/quote RPA 100% 失败
R8 login 页且无凭据 → STRUCT_CHANGE禁止误报 SESSION_EXPIRED 排障误导、错误重试
R9 RPA selector 禁止硬编码上线;必须 RPA_SELECTOR_* env 或 lib/rpa/selector-specs.ts 统一管理 页面改版即挂
R10 RPA_MOCK_MODE=false 为验收/生产默认Mock 仅 CI/单测 假数据上线

工程红线

# 规则
E1 PRD 与代码冲突时 以 PRD 为准;实现细节以技术设计为准
E2 禁止擅自新增/修改 API 字段、错误码、表字段(须先改 PRD + migration
E3 禁止空 catch、静默失败、吞异常
E4 禁止占位 UI / 假按钮 / 「敬请期待」入口
E5 禁止物理删除业务数据;使用逻辑删除 is_deleted
E6 禁止跳过 migration 直接改库;禁止代码引用未迁移字段
E7 禁止在 main 分支直接提交;禁止 git push -f 到 main
E8 禁止提交密钥(.env、storageState、真实 token
E9 禁止未授权升级依赖或引入未评审大包
E10 多租户:customer_id 必须校验归属,禁止越权查历史/报价

安全红线

# 规则
S1 查价 API 必须校验宿主 Service Token
S2 管理端 API 必须 JWT + RBAC
S3 高危操作须审计日志(AuditLog
S4 限流:单客户 60 次/分钟(见 PRD

技术方案

架构总览

宿主系统(内嵌查价 UI
    │ Bearer Token + customer_id
    ▼
Next.js APIQuoteOrchestrator
    ├─ L1 idem:{request_id}  ──命中──► 直接返回
    ├─ L2 quote:{cargo_hash}   ──命中──► 加价后返回
    └─ 未命中 ──► BullMQ(quote-rpa) ──► RPA Worker
                        │                    │
                        │                    ├─ QuotePageAdapter多 URL 探测)
                        │                    ├─ session-managerstorageState
                        │                    └─ mothership.ts填表+四档抓取)
                        ▼
                   MySQL quote_record / Redis L2/L3

缓存策略GD-2

Key TTL 用途
L1 idem:{request_id} 24h 幂等完整响应
L2 quote:{cargo_hash} 3min 四档原始价(未加价)
L3 stale:{cargo_hash} 30min RPA 失败降级

读取顺序:L1 → L2 → RPA →失败L3

询价状态机

processing → done (cache|rpa|stale) | failed (QUOTE_UNAVAILABLE|QUOTE_TIMEOUT)
done --3min--> expired

RPA 方案v1.2

  1. QuotePageAdapterMOTHERSHIP_QUOTE_URLS 顺序探测可用入口
  2. session-manager 加载/写回 RPA_STORAGE_STATE_PATH
  3. 地址:键入 → 等待联想 → click 选项 → fill-verify
  4. 单次提交 → 结果页切换 standard/guaranteed × lowest/fastest → 抓 4 档
  5. 失败分类:入口错误 / 地址未锁定 / 验证码 / 结构变更 / 数据无效

上线门禁:probe-rpa 连续 3 次 exit 0TC-601 + §12.7)。

加价公式

markup_amount = ROUND_HALF_UP(raw_freight × markup_percent / 100, 2)
final_total   = ROUND_HALF_UP(raw_total + markup_amount, 2)

关键 API

方法 路径 调用方
POST /api/quotes 宿主
GET /api/quotes/{quote_id} 宿主(轮询)
GET /api/quotes/history 宿主
PUT /api/markup-configs/{customer_id} 宿主
GET /api/alerts 管理员

环境变量RPA 最小集)

变量 必填 说明
MOTHERSHIP_QUOTE_URLS 逗号分隔匿名报价 URL
RPA_SELECTOR_* 录制产出 selector
RPA_STORAGE_STATE_PATH 默认 .rpa/mothership-storage.json
RPA_MOCK_MODE 默认 false
RPA_HEADLESS 调试设 false
DATABASE_URL / REDIS_URL 基础设施

完整列表见 .env.example 与技术设计 §6.2。


新人上手路径

  1. 先读本文「AI 项目交接文档」 → PRD §13 → 技术设计 §1、§7
  2. cp .env.example .env,配 DATABASE_URL / REDIS_URL / HOST_SERVICE_TOKENS
  3. npm run dev:startdocker compose up -d + npm run dev
  4. 打开 http://localhost:3000/embed-demo 走通查价
  5. RPA 开发:先 npm run record:mothership,再 npm run probe:rpa
  6. 接任务前查 工程任务拆解 v1.2 当前 Phase

排障速查

现象 优先检查
embed 询价超时/failed 先看「AI 项目交接文档」§3 BLK-001~003worker 日志 no_place_request
创建即 done + cache L2 假阳性;换 cargo 或清 Redis quote:*
place commit 失败 headed 对比 networkGET place/{id} 是否触发
RPA 进登录页 MOTHERSHIP_QUOTE_URLS 是否 dashboardstorageState 是否失效
preCheck 失败 RPA_SELECTOR_* 是否过期headed 重录
地址填不进去 是否缺少 place_id;联想是否 click 而非 Enter
只返回 2 档 违反 GD-1检查四档抓取逻辑
429 限流;检查 customer_id 请求频率
Worker 不消费 Redis 连通、RPA_QUEUE_ENABLED、BullMQ 队列

失败截图目录:.dev/logs/(如 rpa-failure-*.png)。


文档维护

  • 业务变更 → 先改 PRD → 同步技术设计 → 更新本文「项目信息/红线/技术方案」摘要
  • 命令变更 → 以 package.json scripts 为准,同步本文「常用命令」
  • 规则变更 → 同步 cursor_project_rules/domain-rules.mdc