← 返回首页

业务跑通手册

docs/业务跑通手册.md

# wm-geo 业务跑通手册

> 按角色列出页面路径、核心 API、演示脚本与定时任务。本地/预发「全链路能跑通」以 **`scripts/demo-full-business-path.sh`** 为准。  
> 产品向「已交付 vs PRD P0 仍缺」见 **[`当前交付边界.md`](./当前交付边界.md)**。  
> **上线前 env / Cron / 安全头**:见 **[`上线配置清单.md`](./上线配置清单.md)**(每项「不配则怎样」)。  
> 仓库路径:`/Users/wb/Desktop/1/wm-geo`

---

## 0. 前置与环境

| 项 | 说明 |
|----|------|
| 数据库 | `DATABASE_URL` 已配置;`npx prisma migrate deploy`(含 `contact_inquiries` 等迁移) |
| 开发服务 | `npm run dev` 或 `npm run start`,默认 `http://127.0.0.1:3000` |
| 密钥 | `JWT_SECRET`(≥16)、`INTERNAL_JOB_SECRET`(≥16,异步机/Cron) |
| 本地运营 | 建议 `ADMIN_DEV_BYPASS=1`(admin 指派/撤稿免单独会话) |
| LLM | `MOCK_LLM=1` 或配置 `OPENAI_API_KEY` / 六家 Key(见 `.env.example`) |
| 工具 | `curl`、`jq` |

**一键全链路演示**(推荐验收入口):

```bash
cd /Users/wb/Desktop/1/wm-geo
chmod +x scripts/run-demo-full-business-path.sh scripts/demo-full-business-path.sh
./scripts/run-demo-full-business-path.sh
```

包装脚本默认导出 `INTERNAL_JOB_SECRET`、`ADMIN_DEV_BYPASS=1`、`WECHAT_PAY_DEV_MOCK=1`、`WECHAT_PAY_DEV_NOTIFY=1`、`WM_GEO_CHANNEL_OAUTH_DEV_BYPASS=1`(与 E2E 对齐,可覆盖)。亦可手写:

```bash
export INTERNAL_JOB_SECRET='your-local-secret-at-least-16-chars'
export ADMIN_DEV_BYPASS=1
./scripts/demo-full-business-path.sh
```

脚本覆盖(**15 步**):健康检查 → 匿名诊断 → 租户 dev 登录 → 品牌/关键词 → 扫描/报告 → **step 6 报告 PDF**(`GET …/export?format=pdf`,校验 `%PDF-` 魔数)→ 公开报告 API → 内容生成+异步机 → 发文发布 → **step 11 知乎 OAuth + platform-publish-via-api**(`POST channels/zhihu/oauth/start` + dev bypass callback + `POST …/platform-publish-via-api`,`GET demo/extension-oauth-steps` / `GET demo/platform-publish-steps` / **`GET demo/extension-real-publish-steps` + `GET extension/real-publish-checklist-summary`**)→ 代发下单 → 运营指派 → 供应商履约 → 撤稿批准;末尾 echo 含 **Settings 扩展 OAuth / platform publish / 扩展真发 checklist**、**`/docs/demo-script#extension-real-publish-steps`**、**发布扩展引导**、**发文详情 / live_url** URL。

**CI / Playwright 对齐**(`.github/workflows/e2e.yml`):

1. Postgres service → `npx prisma migrate deploy`
2. `npm run build` → `npm run start`(`127.0.0.1:3000`)
3. 等待 `GET /api/v1/health` 返回 200
4. `npx playwright test e2e/demo-script-smoke.spec.ts` — 与脚本前 5 步 API 对齐(health → diagnose → dev-session → 品牌/关键词 → scans → **GET /app/scans/:id**);**须 `DATABASE_URL`**
5. `npx playwright test e2e/demo-script-report-inline-url-flow.spec.ts` — 与脚本 step 4c 对齐(**GET reports/:id/export?inline=1** → 200 + HTML)
5. `npx playwright test e2e/publication-body-plain.spec.ts` — `POST bodyPlain` 竖切
6. `npx playwright test e2e --grep-invert "demo script smoke|POST bodyPlain"` — 其余 E2E(全量 **129·0·0**)

本地复现 demo 冒烟:

```bash
cd /Users/wb/Desktop/1/wm-geo
npm run build && npm run start   # 另开终端
npx playwright test e2e/demo-script-smoke.spec.ts
```

### 0.1 历史 brand_id 回填(可选)

迁移 `20260521140000` 后为 `publications` / `sourcing_orders` 补列 `brand_id`;迁移 `20260521150000` 为 `orders` 补列 `brand_id`;`generations` 表自 init 即有该列。若历史行 `brand_id=null`,可用脚本按**各用户最近品牌**(`brands.createdAt desc`)回填:

```bash
cd /Users/wb/Desktop/1/wm-geo
# 默认 dry-run,仅打印将更新的行
node scripts/backfill-brand-id.mjs
# 确认无误后写入
node scripts/backfill-brand-id.mjs --execute
```

覆盖表:`publications`、`sourcing_orders`、`generations`。无品牌的用户行会 skip 并打印 `[skip]`。

---

## 1. 租户(`/app` 应用端)

登录:`/login`(OTP / 微信 dev bypass / 开发一键 `dev-session`)。登录后默认工作台 `/app`。

### 1.0 品牌上下文 brandId URL 导航

租户多品牌场景下,可在任意 `/app/*` 路径追加查询参数 **`?brandId=<UUID>`** 作为「当前品牌上下文」。工具函数见 `lib/app/brand-id-from-search-params.ts`:

| 函数 | 用途 |
|------|------|
| `brandIdFromSearchParams` | 从 URL 读取合法 UUID;非法或空串返回 `""` |
| `appendBrandIdToHref(href, brandId)` | 为任意 href 追加 `?brandId=` 或 `&brandId=`(侧栏、工作台 8 卡快捷入口等) |
| `appHrefWithBrandId` | 仅对 `/app/generate`、`/app/publish`、`/app/sourcing` 追加 brandId(历史快捷链) |

**页内自动应用筛选**(mount 读 URL `?brandId=` → 品牌下拉 / 列表 API 带同一 brandId):`KeywordsPage`、`ReportsPage`、`CompetitorsPage`、`SuggestionsPage`、`DashboardPage`(`dashboard-summary?brandId=`)、`PublishedPage`、`SourcingOrdersPage`、**`NewPublicationPage`**(新建草稿品牌下拉预填)。

**导航保留 / 清除**:

1. **`AppShell` 侧栏主 Nav**:经 `appendBrandIdToHref`,切换页时保留当前 URL 的 `brandId`。
2. **`AppShell` M4 发布分组侧栏摘要**:platform publish / 扩展真发 / **fillDraft/submitDraft** / 扩展连接诊断 checklist 摘要(已就绪/待补 badge → `/app/settings` 保留 brandId;fillDraft/submitDraft 见 checklist `appshell_fill_submit_draft_sidebar_summary`)。
3. **`AppShell` 底栏**(设置、首次引导、我的代发订单):**不**追加 `brandId`(`preserveBrandId={false}`);顶栏 `NotificationBell` 无出站 Link。
3. **顶栏品牌标签**:URL 含 `brandId` 时展示当前品牌名;**品牌名链 `/app/brands/[id]`**(`aria-label`「当前品牌:…」);**X 按钮**清除筛选(同路径无 query);清除后顶栏展示**「恢复筛选:{name}」**回链(`sessionStorage`)。侧栏 URL 含 `brandId` 时展示**「当前品牌」卡片**链品牌详情。
4. **`DashboardPage` 工作台**:应用品牌筛选后,顶部 8 卡快捷入口均经 `appendBrandIdToHref` 携带 `appliedBrandId`(**「优化建议」链 `/app/m3/suggestions`**);**「M3 建议模块」说明卡**(`GET /api/v1/app/m3/module-status`);**「platform publish 状态」汇总卡**(`GET /api/v1/app/dashboard/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**四指标卡**(可见度/关键词/生成/告警)与「查看全部」「一键生成提权内容」亦保留 brandId;筛选区「当前品牌」链 `/app/brands/[id]`;**有 scan 时「最近监测」卡 +「查看监测详情」链 `/app/scans/[id]` +「内嵌报告」链 `export?inline=1`**;**底部「下一步」CTA(keywords/reports/优化建议→m3/suggestions/监测详情/内嵌报告)保留 brandId** + **空状态「查看品牌详情」链**。
5. **`BrandDetailPage`**:详情页快捷链均经 `appendBrandIdToHref(路径, data.id)`(keywords / reports / competitors / **优化建议→`/app/m3/suggestions`** / **M3 模块→`/app/m3`** / dashboard / generate / publish / sourcing);**「M3 建议模块」说明卡**(`GET /api/v1/app/m3/module-status` + checklist `brand_detail_m3_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=` + checklist `brand_detail_citation_monitoring_card`);**「品牌30天引用趋势」卡**(`GET /api/v1/app/brands/:id/citation-trend-context` + checklist `brand_detail_citation_trend_card`);**有监测时「查看监测详情」链 `/app/scans/[latestScanId]`** + **「内嵌报告」链 `export?inline=1`(latestReportId)**;**底部「下一步」优化建议链 `/app/m3/suggestions`**。
6. **`PublicationDetailPage`**:`brandId` 存在时品牌名链 `/app/brands/[brandId]`;**GET `/app/publications/:id` 含 latestScanId/latestReportId**;**「platform publish 状态」汇总卡**(`GET …/platform-publish-status-context` + 链 Settings / 扩展引导 / 发布中心);**「platform publish API 结果」卡**(`GET …/platform-publish-result-context`);**「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis`;checklist `publication_detail_extension_connection_diagnosis`);**「最近监测」→「查看监测详情」/「内嵌报告」**;**「返回内容库」链 `/app/publications?brandId=`**;**底部「下一步」CTA(publish/published/generate/监测详情/内嵌报告)经 `appendBrandIdToHref` 保留 brandId**。
6a. **`PublicationsPage`(内容库列表)**:**`GET /app/publications/list` 行含 `platformPublishReadiness` / `platformPublishPublishedUrl`**(`metrics_json.platformPublishResult`);列表行 **platform publish 状态 badge**(已写回 / API 就绪 / 待 OAuth / 无映射)。
7. **`GenerateDetailPage`**:`brandId` 存在时品牌名链 `/app/brands/[brandId]`;「转为发文草稿」POST 携带同源 `brandId`;**「返回生成中心」+ 底部「下一步」CTA(publish/publications/suggestions)保留 brandId**。
8. **`SettingsPage`**:「品牌与订阅」→「管理品牌库」经 `appendBrandIdToHref("/app/brands", …)`(URL brandId 或最近国内单 brandId);**`?brandId=` 时「返回工作台」链 `/app?brandId=`**;**底部「下一步」CTA(brands/keywords/reports)保留 brandId**;**`?brandId=` 时「最近监测」卡 + 底部 CTA「监测详情」/「内嵌报告」链**(有 scan/report 时)。

**演示 URL**(将 `BRAND_UUID` 换为 `GET /api/v1/app/brands` 返回的 id):

```bash
open 'http://127.0.0.1:3000/app/reports?brandId=BRAND_UUID'
open 'http://127.0.0.1:3000/app/scans/SCAN_UUID'          # 监测详情(demo 脚本末尾 echo scanId)
open 'http://127.0.0.1:3000/app/sourcing/orders/ORDER_UUID' # 代发单订单详情(demo 脚本末尾 echo orderId)
open 'http://127.0.0.1:3000/app?brandId=BRAND_UUID'   # 工作台 8 卡链出仍带 brandId
```

E2E 竖切:`npx playwright test e2e/appshell-fill-submit-draft-sidebar-summary-flow.spec.ts`(**AppShell M4 侧栏 fillDraft/submitDraft checklist 摘要 + 链 Settings 保留 brandId**);`npx playwright test e2e/appshell-brand-enhance-flow.spec.ts`(**AppShell 顶栏品牌名链品牌详情 + X 清除 + 恢复筛选回链 + 侧栏当前品牌卡片**);`npx playwright test e2e/brand-url-prefill-flow.spec.ts`(reports 预填、侧栏保留 brandId、底栏设置无 brandId、BrandDetail 快捷链、顶栏 X 清除、published / sourcing/orders 预填);`npx playwright test e2e/brand-detail-shortcuts-flow.spec.ts`(BrandDetail → publications / published / sourcing/orders 快捷链带 brandId);`npx playwright test e2e/brand-detail-cta-brand-flow.spec.ts`(**`/app/brands/[id]` 返回品牌库 + 底部 CTA 保留 brandId**);`npx playwright test e2e/brand-detail-scan-flow.spec.ts`(**POST scans → GET brands/:id latestScanId + `/app/brands/[id]`「查看监测详情」链 `/app/scans/[id]`**);`npx playwright test e2e/brand-detail-report-inline-flow.spec.ts`(**POST scans → GET brands/:id latestReportId + `/app/brands/[id]`「内嵌报告」链 `export?inline=1`**);`npx playwright test e2e/settings-cta-brand-flow.spec.ts`(**`/app/settings?brandId=` 返回工作台 + 底部 CTA 保留 brandId**);`npx playwright test e2e/settings-m3-module-card-flow.spec.ts`(**GET m3/module-status checklist settings_m3_card + `/app/settings?brandId=`「M3 建议模块」卡 + hub/suggestions/底部优化建议/M3 模块链保留 brandId**);`npx playwright test e2e/settings-scan-link-flow.spec.ts`(**POST scans → GET /app/settings?brandId= latestScan + `/app/settings?brandId=`「最近监测」+ 底部 CTA 监测详情/内嵌报告链**);`npx playwright test e2e/pricing-scan-link-flow.spec.ts`(**POST scans → GET /app/brands 匹配项 latestScanId + `/pricing?brandId=`「最近监测」+ 底部 CTA 监测详情/内嵌报告链**);`npx playwright test e2e/pricing-m3-module-card-flow.spec.ts`(**GET m3/module-status checklist pricing_m3_card + `/pricing?brandId=` 登录态「M3 建议模块」卡 + hub/suggestions/底部优化建议/M3 模块链保留 brandId**);`npx playwright test e2e/scan-detail-m3-module-card-flow.spec.ts`(**GET m3/module-status checklist scan_detail_m3_card + `/app/scans/[id]`「M3 建议模块」卡 + hub/suggestions/底部优化建议/M3 模块链保留 brandId**);`npx playwright test e2e/report-brand-id-flow.spec.ts`(scan → 列表/导出 JSON brandId + reports 页品牌链);`npx playwright test e2e/reports-list-scan-link-flow.spec.ts`(**`/app/reports?brandId=` 行内「关联监测」/「内嵌报告」+ 底部「监测详情」保留 brandId**);`npx playwright test e2e/scan-detail-brand-flow.spec.ts`(**GET /app/scans/:id 含 brandId/brandName + `/app/scans/[id]` 返回历史报告 + 底部 CTA 优化建议→m3/suggestions 保留 brandId**);`npx playwright test e2e/scan-detail-cta-brand-flow.spec.ts`(**`/app/scans/[id]` 顶部「返回工作台」+ 顶栏 generate/publish + 底部 CTA(generate/publish/published/keywords/competitors/优化建议→m3/suggestions/M3 模块/reports)保留 brandId**);`npx playwright test e2e/scan-detail-report-inline-flow.spec.ts`(**监测详情「查看报告」→ export?inline=1 →「返回监测详情」回链 + 底部 CTA 查看报告**);`npx playwright test e2e/report-export-detail-brand-flow.spec.ts`(export?inline=1 HTML 品牌链 + reports 行「品牌详情」);`npx playwright test e2e/report-export-inline-cta-brand-flow.spec.ts`(**export?inline=1 工具栏「返回历史报告」+ 底部 CTA 保留 brandId**);`npx playwright test e2e/reports-cta-brand-flow.spec.ts`(`/app/reports?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」链);`npx playwright test e2e/publication-brand-id-flow.spec.ts`(创建带 brandId → 列表/详情 API;`/app/publications/new?brandId=` 预填;详情页品牌名链品牌详情);`npx playwright test e2e/new-publication-scan-link-flow.spec.ts`(**POST scans → GET /app/brands 匹配项 latestScanId + `/app/publications/new?brandId=`「最近监测」/底部监测详情/内嵌报告链**);`npx playwright test e2e/new-publication-platform-publish-status-flow.spec.ts`(**GET publications/new/platform-publish-status-context checklist new_publication_platform_publish_status_card + `/app/publications/new?brandId=` platform publish 汇总卡 + 链 Settings / 扩展引导 / 发文详情 platform publish 结果卡**);`npx playwright test e2e/publish-extension-platform-publish-status-flow.spec.ts`(**GET publish/extension/platform-publish-status-context checklist publish_extension_platform_publish_status_card + `/app/publish/extension?brandId=` platform publish 汇总卡 + 链 Settings / 内容库 / 发文详情 platform publish 结果卡**);`npx playwright test e2e/publications-list-brand-id-flow.spec.ts`(`GET publications/list` 行 brandId/brandName + `/app/publications?brandId=` 当前品牌/行内品牌链);`npx playwright test e2e/publications-list-platform-publish-status-flow.spec.ts`(**POST platform-publish-via-api → list 含 platformPublishReadiness + `/app/publications` 列表 badge**);`npx playwright test e2e/publications-cta-brand-flow.spec.ts`(`/app/publications?brandId=` 底部 CTA 保留 brandId + 卡片「品牌详情」+ 查看详情保留 brandId);`npx playwright test e2e/publications-published-m3-module-card-flow.spec.ts`(**GET m3/module-status checklist publications_m3_card + published_m3_card + `/app/publications?brandId=` 与 `/app/published?brandId=`「M3 建议模块」卡 + 底部 hub/suggestions 链保留 brandId**);`npx playwright test e2e/publish-list-brand-id-flow.spec.ts`(预约后 publish/list 行 brandId/brandName + `/app/publish?brandId=` 品牌链);`npx playwright test e2e/publish-cta-brand-flow.spec.ts`(`/app/publish?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」/「新建草稿」保留 brandId);`npx playwright test e2e/published-page-brand-flow.spec.ts`(发布带 brandId → `/app/published?brandId=` 当前品牌/卡片「品牌详情」/查看详情保留 brandId);`npx playwright test e2e/published-cta-brand-flow.spec.ts`(`/app/published?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」链);`npx playwright test e2e/published-scan-link-flow.spec.ts`(**POST scans → GET publish/list latestScan + `/app/published?brandId=`「最近监测」/底部监测详情/内嵌报告链**);`npx playwright test e2e/generation-brand-id-flow.spec.ts`(`generate/run` + 异步机 → 列表/详情 API;转为草稿保留 brandId;详情页品牌名链品牌详情);`npx playwright test e2e/generate-list-brand-id-flow.spec.ts`(`generate/list` 行 brandId/brandName + `/app/generate?brandId=` 当前品牌/最近生成行品牌链);`npx playwright test e2e/sourcing-order-detail-brand-flow.spec.ts`(`GET sourcing/orders/:id` brandId/brandName + 订单页「当前品牌」/「品牌详情」链);`npx playwright test e2e/sourcing-orders-cta-brand-flow.spec.ts`(`/app/sourcing/orders?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」链);`npx playwright test e2e/sourcing-order-single-detail-cta-brand-flow.spec.ts`(**`/app/sourcing/orders/[id]` 返回订单管理 + 底部 CTA 保留 brandId + 品牌名链**);`npx playwright test e2e/vendor-settlements-brand-flow.spec.ts`(**履约完结 → GET vendor/settlements/list 与 :id 含 brandId/brandName + `/vendor/settlements` UI 展示品牌**);`npx playwright test e2e/dashboard-brand-id-flow.spec.ts`(`/app?brandId=` 指标卡/洞察 CTA/当前品牌链保留 brandId);`npx playwright test e2e/keywords-cta-brand-flow.spec.ts`(`/app/keywords?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」链);`npx playwright test e2e/keywords-scan-link-flow.spec.ts`(**POST scans → GET keywords?brandId= latestScanId + `/app/keywords?brandId=`「最近监测」/底部监测详情/内嵌报告链**);`npx playwright test e2e/competitors-cta-brand-flow.spec.ts`(`/app/competitors?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」链);`npx playwright test e2e/competitors-scan-link-flow.spec.ts`(**POST scans → GET competitors?brandId= latestScanId + `/app/competitors?brandId=`「最近监测」/底部监测详情/内嵌报告链**);`npx playwright test e2e/generate-cta-brand-flow.spec.ts`(`/app/generate?brandId=` 底部 CTA 保留 brandId + 空状态「查看品牌详情」链);`npx playwright test e2e/generate-detail-cta-brand-flow.spec.ts`(`/app/generate/[id]` 返回生成中心 + 底部 CTA 保留 brandId);`npx playwright test e2e/generate-scan-link-flow.spec.ts`(**POST scans → GET generate/list latestScan + `/app/generate?brandId=`「最近监测」/底部监测详情/内嵌报告链**);`npx playwright test e2e/generate-detail-scan-link-flow.spec.ts`(**POST scans + generate/run → GET generate/:id latestScan + `/app/generate/[id]`「最近监测」/底部监测详情/内嵌报告链**)。

### 1.1 页面路径

| 路径 | 用途 |
|------|------|
| `/app` | 工作台仪表盘 / KPI;**「M3 建议模块」说明卡**(`GET /api/v1/app/m3/module-status` + hub/suggestions 链);**「platform publish 状态」汇总卡**(`GET dashboard/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `dashboard_fill_submit_draft_summary`);**「定时重测」Cron 摘要卡**(`GET /api/v1/app/monitor/schedule-status?brandId=`;compact checklist + 链 Prompt 矩阵/Cron 运维说明);**「定时 Cron 产品化」汇总卡**(`GET /api/v1/app/monitor/cron-productization-context?brandId=`;checklist `dashboard_cron_productization_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `dashboard_citation_monitoring_card`;L1 URL 规则扫描 MVP + D+ 节点 badge +「查看内容库」链);**「跨品牌引用对比」看板卡**(`GET /api/v1/app/brands/citation-comparison-context?brandId=`;checklist `dashboard_citation_comparison_card`;30 天 citation_hits 排行 · 高亮当前品牌 · 链品牌详情/趋势);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `dashboard_report_export_oss_card`) |
| `/app/onboarding` | 首次引导 |
| `/app/brands` | 品牌库(创建/编辑竞品,见下) |
| `/app/brands/[id]` | 品牌只读详情;**「定时重测」Cron checklist 卡**(`GET schedule-status` + 全量 checklist);**「定时 Cron 产品化」汇总卡**(`GET cron-productization-context?brandId=`;checklist `brand_detail_cron_productization_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `brand_detail_report_export_oss_card`);**「platform publish 状态」汇总卡**(`GET brands/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `brand_detail_fill_submit_draft_summary`) |
| `/app/keywords` | Prompt 矩阵;**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `keywords_fill_submit_draft_summary`);**「定时重测」Cron checklist 卡**(`GET /api/v1/app/monitor/schedule-status`;链 `/docs/business-runbook`);**「定时 Cron 产品化」汇总卡**(`GET /api/v1/app/monitor/cron-productization-context?brandId=`;checklist `keywords_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `keywords_pay_checklist_card`);**「platform publish 状态」汇总卡**(`GET keywords/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**「扩展真发 checklist」汇总卡**(`GET extension/real-publish-checklist-summary` + 链 Settings / 扩展引导);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `keywords_report_export_oss_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `keywords_citation_monitoring_card`) |
| `/app/competitors` | 竞品监测;**「M3 建议模块」说明卡**(checklist `competitors_m3_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `competitors_report_export_oss_card`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `competitors_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `competitors_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `competitors_citation_monitoring_card`) |
| `/app/reports` | 历史报告(列表项含 `brandId`;行内 brandName 链 `/app/brands/[id]`;URL `?brandId=` 预填);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `reports_fill_submit_draft_summary`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context` + 链业务手册 / 下载 PDF);**「platform publish 状态」汇总卡**(`GET reports/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `reports_citation_monitoring_card`;L1 URL 规则扫描 MVP + D+ 节点 badge +「查看内容库」链);**「扩展真发 checklist」汇总卡**(`GET extension/real-publish-checklist-summary` + 链 Settings / 扩展引导);**「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis` + 链 Settings / 扩展引导 / docs#extension-connection-steps);**内嵌报告 `export?inline=1` 含 platform publish 状态卡 + 扩展真发 checklist 卡 + 扩展连接诊断卡 + PDF/OSS 报告导出内嵌卡**(checklist `report_inline_report_export_oss_card`) |
| `/app/scans/[id]` | 监测详情(品牌链 + 顶栏/底部「查看报告」+ **「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `scan_detail_fill_submit_draft_summary`)+ **「platform publish 状态」汇总卡**(`GET scans/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情;checklist `scan_detail_platform_publish_status_card`)+ **「扩展真发 checklist」汇总卡** + **「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis`;checklist `scan_detail_extension_connection_diagnosis`)+ **「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `scan_detail_cron_productization_card`)+ **「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `scan_detail_pay_checklist_card`)+ **「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `scan_detail_report_export_oss_card`)+ **「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `scan_detail_citation_monitoring_card`)) |
| `/app/m3` | M3 建议模块 hub(**checklist 全量分组**:navigation / page_cards / engine / prd_gaps + 汇总 badge;路由卡;**`?brandId=`「最近监测」+ 监测详情/内嵌报告/优化建议链**;**「platform publish 状态」汇总卡**(`GET m3/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `m3_hub_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `m3_hub_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `m3_hub_citation_monitoring_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `m3_hub_report_export_oss_card`)+ **「扩展连接诊断」汇总卡**(checklist `m3_hub_extension_connection_diagnosis`)+ **「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `m3_hub_fill_submit_draft_summary`)+ `?brandId=` 最近监测链) |
| `/app/m3/suggestions` | M3 优化建议独立路由(与 `/app/suggestions` 同源;m3Route badge + **「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `suggestions_fill_submit_draft_summary`)+ **M3 模块卡**(checklist `suggestions_m3_card`)+ **「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `suggestions_report_export_oss_card`)+ **「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `suggestions_cron_productization_card`)+ **「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `suggestions_pay_checklist_card`)+ **「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `suggestions_citation_monitoring_card`)+ **「关键词缺口(M3-02)」卡**(`GET keyword-gaps` + 一键 POST add-to-matrix + 链 Prompt 矩阵)+ **「引用诱导策略库(M3-05)」卡**(`GET citation-strategies` + POST apply-to-draft + 链生成中心)+ **「行业最佳实践(M3-06)」卡**(`GET industry-practices` + POST apply-to-draft + 链生成中心)+ **「扩展真发 checklist」汇总卡**(checklist `suggestions_extension_real_publish_summary`)+ **「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis`;checklist `suggestions_extension_connection_diagnosis`);AppShell「优化建议」链出) |
| `/app/m3` | M3 模块 hub(checklist 全量分组 + **「platform publish 状态」汇总卡** + **「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `m3_hub_report_export_oss_card`)+ **「扩展连接诊断」汇总卡**(checklist `m3_hub_extension_connection_diagnosis`)+ `?brandId=` 最近监测链) |
| `/app/suggestions` | 优化建议(规则引擎;**「M3 建议模块」说明卡**(checklist `suggestions_m3_card`)+ **「关键词缺口(M3-02)」卡**(`GET keyword-gaps` + 一键 POST add-to-matrix + 链 Prompt 矩阵)+ **「引用诱导策略库(M3-05)」卡**(`GET citation-strategies` + POST apply-to-draft + 链生成中心)+ **「行业最佳实践(M3-06)」卡**(`GET industry-practices` + POST apply-to-draft + 链生成中心)+ **「扩展真发 checklist」汇总卡**;来源卡 brandName 链 `/app/brands/[id]`;URL `?brandId=` 预填;**底部 CTA(generate/reports/keywords/M3 模块)保留 brandId**;无监测数据时空状态「查看品牌详情」链) |
| `/app/generate` | 内容生成中心;**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `generate_fill_submit_draft_summary`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `generate_report_export_oss_card`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `generate_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `generate_pay_checklist_card`);**「platform publish 状态」汇总卡**(`GET generate/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `generate_citation_monitoring_card`) |
| `/app/generate/[id]` | 单篇生成详情 |
| `/app/publish` | 发布中心:`GET publish/list` 分区展示草稿与 **scheduled**(列表项含 **brandId/brandName** + **platformPublishReadiness** / **platformPublishPublishedUrl**;草稿/预约行 **platform publish badge**;已预约行 brandName 链 `/app/brands/[id]`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `publish_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `publish_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `publish_citation_monitoring_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `publish_page_report_export_oss_card`);**「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis`;checklist `publish_page_extension_connection_diagnosis`);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `publish_page_fill_submit_draft_summary`);**`?brandId=` 时「最近监测」+ 底部 CTA 监测详情/内嵌报告链**;`POST schedule` / `cancel`;筛选区「当前品牌」链品牌详情 |
| `/app/published` | 已发布列表(`publish/list` 过滤 `published`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `published_citation_monitoring_card`;L1 URL 规则扫描 MVP + D+ 节点 badge);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `published_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `published_pay_checklist_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `published_report_export_oss_card`);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `published_fill_submit_draft_summary`);**`?brandId=` 时「最近监测」+ 底部 CTA 监测详情/内嵌报告链** |
| `/app/publications` | 内容库列表;**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `publications_citation_monitoring_card`;L1 URL 规则扫描 MVP + D+1/3/7/14/30 节点 badge);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `publications_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `publications_pay_checklist_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `publications_report_export_oss_card`);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `publications_fill_submit_draft_summary`);**`?brandId=` 时「最近监测」+ 底部 CTA 监测详情/内嵌报告链** |
| `/app/publications/new` | 新建发文草稿;**「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis`;checklist `new_publication_extension_connection_diagnosis` + 链 Settings / 扩展引导 / docs#extension-connection-steps);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `new_publication_fill_submit_draft_summary`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `new_publication_report_export_oss_card`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `new_publication_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `new_publication_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `new_publication_citation_monitoring_card`) |
| `/app/publications/[id]` | 单篇详情 / 撤稿;**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `publication_detail_citation_monitoring_card`);**「真 AI 回答抓取」卡**(`POST …/capture-ai-answer` + `POST …/chain-capture-to-citation-scan` + `GET …/ai-answer-capture-context`;六引擎 callEngine → `metrics_json.aiAnswerCapture` · 链式 L2/L3 → `metrics_json.aiAnswerCaptureChain`;checklist `publication_detail_ai_answer_capture_card` / **m5_capture_auto_chain_l2_scan** / **m5_capture_auto_chain_l3_scan**);**「citation_hits 明细」卡**(`GET publications/:id/citation-hits-context`;checklist `publication_detail_citation_hits_detail_card`;**「导出 CSV」** → `GET …/citation-hits/export?format=csv`;命中行「查看证据」→ **引用证据抽屉** `GET …/citation-hits/:hitId/evidence-context` · 优先展示真抓取片段);**「30 天引用趋势」卡**(`GET publications/:id/citation-trend-context`;checklist `publication_detail_citation_trend_card`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `publication_detail_report_export_oss_card`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `publication_detail_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `publication_detail_pay_checklist_card`);**「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis`;checklist `publication_detail_extension_connection_diagnosis`);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `publication_detail_fill_submit_draft_summary`) |
| `/app/publish/extension` | 浏览器扩展引导;**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `publish_extension_fill_submit_draft_summary`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `publish_extension_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `publish_extension_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `publish_extension_citation_monitoring_card`);**稳定 DOM 选择器注册表**(`GET extension/stable-dom-selectors` + 链 docs#extension-stable-dom-selectors);**发布后 URL 稳定捕获**(`GET extension/stable-url-capture` + 链 docs#extension-stable-url-capture);**四平台 DOM 真调验收卡(深化)**(`GET extension/dom-tuning-acceptance` · per-platform acceptanceDepthReady + 链 stable selectors/URL capture/docs#extension-dom-tuning-acceptance) |
| `/app/sourcing` | 代发信源市场;**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `sourcing_fill_submit_draft_summary`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `sourcing_report_export_oss_card`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `sourcing_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `sourcing_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `sourcing_citation_monitoring_card`) |
| `/app/sourcing/orders` | 我的代发订单(列表卡片展示 `publishedUrl` 外链,供应商 deliver/complete 后可见;卡片「查看详情」链 `/app/sourcing/orders/[id]`);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `sourcing_orders_report_export_oss_card`);**「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `sourcing_orders_cron_productization_card`);**「国内支付就绪」汇总卡**(`GET pay-checklist-status`;checklist `sourcing_orders_pay_checklist_card`);**「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `sourcing_orders_citation_monitoring_card`) |
| `/app/sourcing/orders/[id]` | 单条代发订单详情(品牌名链 + **「M3 建议模块」说明卡**(checklist `sourcing_order_detail_m3_card`)+ **「返回订单管理」+ 底部 CTA 保留 brandId** + **底部「下一步」优化建议/M3 模块链** + **「最近监测」+ 底部 CTA 监测详情/内嵌报告链**;GET :id 含 latestScanId/latestReportId) |
| `/app/settings` | 账号 / 订阅 / 配额;国内微信/支付宝订阅与 Stripe 用户列并存时展示说明(以 `subscriptions` 为准);**「全链路演示 · 总入口」卡**(`GET demo/full-chain-hub-steps`:Admin 六域 + M5 七子卡双 hub 子卡 + **公网部署四件套汇总子卡** + step deploy_tenant_readiness_summary + checklist **demo_script_full_chain_hub_deploy_four_piece_merge** + 链 docs#full-chain-hub-steps / deploy-readiness-ops-steps / aliyun-d1-checklist / Admin/M5 子 hub docs);**「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `settings_fill_submit_draft_summary`);**「全链路演示 · M3/支付/PDF-OSS 运维步骤」卡**(`GET demo/tenant-ops-steps`);**「全链路演示 · M3 Admin 运维步骤」卡**(`GET demo/m3-admin-ops-steps` + 链 `/admin` M3 建议模块运维卡 / PRD 缺口路线图);**「全链路演示 · extension Admin 运维步骤」卡**(`GET demo/extension-admin-ops-steps` + 链 `/admin` 扩展六卡 / PRD 缺口路线图);**「全链路演示 · PDF/OSS Admin 运维步骤」卡**(`GET demo/pdf-oss-ops-steps` + 链 `/admin` PDF/OSS 运维卡 / 阿里云 OSS 清单);**「全链路演示 · 国内支付/订阅 Admin 运维步骤」卡**(`GET demo/cn-pay-ops-steps` + 链 `/admin` 国内支付运维卡 / `/admin/billing/subscriptions`);**「全链路演示 · 定时 Cron Admin 运维步骤」卡**(`GET demo/cron-admin-ops-steps` + 链 `/admin` Cron 产品化运维卡 / Cron 运维说明);**「全链路演示 · 定时 Cron 运维步骤」卡**(`GET demo/cron-ops-steps` + schedule/cron-productization 子 API);**「全链路演示 · M5 embedding Admin 运维步骤」卡**(`GET demo/m5-embedding-ops-steps` + 链 `/admin` M5 L3 embedding 运维卡 / M5 引用监测步骤 / PRD 缺口路线图);**「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context` + checklist `settings_report_export_oss_card`);**「扩展真发 checklist」汇总卡**(`GET extension/real-publish-checklist-summary` + 链扩展引导;checklist `settings_extension_real_publish_summary`);**`?brandId=` 时「返回工作台」+ 底部「下一步」CTA 保留 brandId** |

**品牌库 · 竞品编辑(`/app/brands`)**

1. **新建品牌**:填写名称;「竞品名称」为多行文本框(每行一个,可选)。留空时 `POST /api/v1/app/brands` 默认写入「友商A」,便于 `/app/competitors` 与全链路 demo step 6 非空。
2. **编辑竞品**:品牌卡片「编辑竞品」→ 对话框展示当前列表(每行一名称);保存时 `PATCH /api/v1/app/brands/[id]` 全量替换 `competitors` 数组。
3. **监测刷新**:有竞品后可在 `/app/competitors` 触发刷新(页内会携带当前筛选 `brandId`),或 `POST /api/v1/app/competitors/refresh`(可选 body `{ "brandId": "<uuid>" }`;**202**)+ Cron/`POST /api/v1/internal/process-async-jobs`(须 `INTERNAL_JOB_SECRET`≥16,与 Next 进程一致)。
4. **监测链**:`GET /api/v1/app/brands` 列表项含 `latestScanId`/`latestReportId`;有监测时卡片 footer「监测详情」链 `/app/scans/[id]` +「内嵌报告」链 `export?inline=1`;**「M3 建议模块」说明卡**(`GET /api/v1/app/m3/module-status` + checklist `brands_m3_card`);`?brandId=` 时底部「下一步」CTA 优化建议→`/app/m3/suggestions` + M3 模块链 + 监测详情/内嵌报告链。

### 1.2 核心 API(`/api/v1/app/*` 及关联)

| 能力 | 方法 | 路径 |
|------|------|------|
| 工作台汇总 | GET | `/api/v1/app/dashboard-summary` |
| 刷新受理 | POST | `/api/v1/app/dashboard-summary/refresh` |
| 品牌列表/创建 | GET/POST | `/api/v1/app/brands` |
| 品牌详情 | GET/PATCH/DELETE | `/api/v1/app/brands/[id]` |
| 关键词矩阵 | GET | `/api/v1/app/keywords` |
| 定时重测 Cron 状态 | GET | `/api/v1/app/monitor/schedule-status`(可选 `?brandId=`;INTERNAL_JOB_SECRET/间隔/到期关键词 checklist,不暴露密钥) |
| 定时 Cron 产品化 | GET | `/api/v1/app/monitor/cron-productization-context`(可选 `?brandId=`;复用 schedule-status + 定时发文/run-all-cron + 多页挂载 checklist;Settings/Reports/Dashboard/Keywords/BrandDetail/Pricing/ScanDetail/Generate/Sourcing/SourcingOrders/Publications/NewPublication/PublicationDetail/Publish/PublishExtension/Published/M3 hub/Suggestions/Competitors 汇总卡) |
| PDF/OSS 报告导出 | GET | `/api/v1/app/reports/export-oss-context`(pdf-lib/OSS env/预签名/多页 P0 checklist;Settings/Reports/Dashboard/BrandDetail/Keywords/ScanDetail/Competitors/Suggestions/Generate/M3 hub/Sourcing/SourcingOrders/Publications/PublicationDetail/NewPublication/Publish/Published/Pricing 汇总卡 + inline `report_inline_report_export_oss_card`) |
| 草稿/导入/保存 | GET/POST | `/api/v1/app/keywords/draft`、`import`、`save`、`merge` |
| 竞品 | GET | `/api/v1/app/competitors`(可选 `?brandId=` 按品牌筛选) |
| 竞品刷新(入队) | POST | `/api/v1/app/competitors/refresh` |
| 报告列表 | GET | `/api/v1/app/reports`(可选 `?brandId=` 按品牌筛选;列表项含 `brandId`) |
| 单条报告导出 | GET | `/api/v1/app/reports/[id]/export`(`?format=json` 含 `brandId`;无 OSS:附件;有 OSS:JSON `downloadUrl`);`?inline=1` 内嵌 HTML + `@media print`,供浏览器「另存为 PDF」 |
| 报告列表 CSV | GET | `/api/v1/app/reports/export`(可选 `?brandId=`,与列表一致) |
| 报告重算 | POST | `/api/v1/app/reports/regenerate` |
| 建议 | GET | `/api/v1/app/suggestions`(可选 `?brandId=`;`source.brandId` 来自 scan) |
| M3-02 关键词缺口 | GET | `/api/v1/app/suggestions/keyword-gaps`(可选 `?brandId=`;perKeyword 低分 + 竞品/口碑推荐拓展;对比 matrix draft) |
| M3-02 入矩阵 | POST | `/api/v1/app/suggestions/keyword-gaps/add-to-matrix`(可选 `?brandId=`;body `{ all: true }` 或 `{ keywords: [...] }` → merge keyword_matrix_drafts) |
| M3-05 策略库 | GET | `/api/v1/app/suggestions/citation-strategies`(可选 `?brandId=`;20+ 静态模式 + 效果数据 + 与最近 generation applied 对比) |
| M3-05 应用草稿 | POST | `/api/v1/app/suggestions/citation-strategies/apply-to-draft`(可选 `?brandId=`;body `{ strategyId }` → append 最近 done generation output) |
| M5 引用监测 L1 MVP | GET | `/api/v1/app/publications/citation-monitoring-status`(可选 `?brandId=`;六引擎 L1 URL 规则 + D+ 节点 + published/live_url/L1 eligible + **citationHitCount/citationScanCount/sampleHits** + checklist;Publications/Published/BrandDetail 汇总卡;只读) |
| M5 L1 命中写入 | POST | `/api/v1/app/publications/:id/record-citation-l1-scan`(已发布 + live_url → L1 规则扫描写入 **citation_scans/citation_hits**;checklist **m5_citation_hits_table**) |
| M5 D+ 调度 Cron | GET/POST | `/api/v1/cron/citation-scheduler`(Bearer CRON_SECRET/INTERNAL_JOB_SECRET · 到期发文 **L1 + auto capture + auto chain L2/L3** → `metrics_json.aiAnswerCapture`/`aiAnswerCaptureChain` `source=citation_scheduler_cron`;checklist **m5_citation_scheduler_auto_capture_cron** / **m5_citation_scheduler_auto_chain_cron**) |
| M5 真 AI 回答抓取 | POST | `/api/v1/app/publications/:id/capture-ai-answer`(已发布 · 六引擎 **callEngine** → `metrics_json.aiAnswerCapture`;checklist **m5_capture_ai_answer_api** / **m5_ai_answer_capture_persisted**) |
| M5 抓取自动链 L2/L3 | POST | `/api/v1/app/publications/:id/chain-capture-to-citation-scan`(须先 capture · 读 aiAnswerCapture → 自动 **record-citation-l2/l3-scan** → `metrics_json.aiAnswerCaptureChain`;checklist **m5_chain_capture_to_citation_scan_api** / **m5_capture_auto_chain_l2_scan** / **m5_capture_auto_chain_l3_scan**) |
| M5 真 AI 回答抓取上下文 | GET | `/api/v1/app/publications/:id/ai-answer-capture-context`(只读 · PublicationDetail「真 AI 回答抓取」卡 · chainReadiness / cronAutoCapture / cronAutoChain / chainL2HitCount / chainL3HitCount;checklist **publication_detail_ai_answer_capture_card** / **m5_citation_scheduler_auto_*_cron**) |
| M5 L3 语义引写入 | POST | `/api/v1/app/publications/:id/record-citation-l3-scan`(已发布 + **paraphrase aiAnswerMvp** → token bag cosine ≥ 0.85 + 规则化 LLM 复核写入 **semantic_match**;checklist **m5_l3_semantic_token_cosine**) |
| M5 L2 段引写入 | POST | `/api/v1/app/publications/:id/record-citation-l2-scan`(已发布 + **aiAnswerMvp** → normalize 标题/段落 fuzzy 匹配写入 **title_cited/paragraph_quoted**;checklist **m5_l2_segment_quote_normalize**) |
| M5 单篇命中明细 | GET | `/api/v1/app/publications/:id/citation-hits-context`(单篇 citation_hits 行 · readiness · checklist **publication_detail_citation_hits_detail_card** / **publication_detail_citation_evidence_drawer**) |
| M5 单篇命中 CSV | GET | `/api/v1/app/publications/:id/citation-hits/export?format=csv`(最多 5000 行 · `writeAuditLog` `app.publications.citation_hits.export_csv`;checklist **m5_publication_citation_hits_export_api** / **publication_citation_hits_export_csv**) |
| M5 引用证据抽屉 | GET | `/api/v1/app/publications/:id/citation-hits/:hitId/evidence-context`(Prompt + aiAnswerMvp + evidenceExcerpt 高亮 · checklist **publication_citation_evidence_api**) |
| M5 单篇 30 天趋势 | GET | `/api/v1/app/publications/:id/citation-trend-context`(30 天日级 citation_hits 聚合 · 引擎摘要 · checklist **publication_detail_citation_trend_card**) |
| M5 品牌 30 天趋势 | GET | `/api/v1/app/brands/:id/citation-trend-context`(品牌下已发布篇 30 天日级 citation_hits 聚合 · 引擎摘要 · checklist **brand_detail_citation_trend_card**) |
| M5 跨品牌对比 | GET | `/api/v1/app/brands/citation-comparison-context`(可选 `?brandId=` 高亮;30 天 citation_hits 跨品牌排行 · checklist **dashboard_citation_comparison_card**) |
| M3-06 行业实践 | GET | `/api/v1/app/suggestions/industry-practices`(可选 `?brandId=`;首发 6 张卡片 + 采纳率 + 与最近 generation applied 对比) |
| M3-06 应用草稿 | POST | `/api/v1/app/suggestions/industry-practices/apply-to-draft`(可选 `?brandId=`;body `{ cardId }` → append 最近 done generation output) |
| 生成任务 | POST | `/api/v1/app/generate/run` |
| 生成列表 | GET | `/api/v1/app/generate/list` |
| 发文 CRUD | GET/POST | `/api/v1/app/publications`、`/list` |
| 立即发布 | POST | `/api/v1/app/publications/[id]/publish` |
| 定时/取消 | POST | `/api/v1/app/publish/schedule`、`cancel` |
| 发布列表 | GET | `/api/v1/app/publish/list` |
| 撤稿申请 | POST | `/api/v1/app/publications/[id]/withdraw-request` |
| 信源目录 | GET | `/api/v1/app/sourcing/list` |
| 代发下单 | POST | `/api/v1/app/sourcing/orders/create` |
| 代发订单列表 | GET | `/api/v1/app/sourcing/orders`(含 `publishedUrl` / `publicUrl`,履约 `published` 时 UI 待验收) |
| 通知 | GET | `/api/v1/app/notifications` |
| 最近异步任务 | GET | `/api/v1/app/jobs/recent` |
| 计费 | GET/POST | `/api/v1/app/billing/*` |
| 国内支付 checklist | GET | `/api/v1/app/billing/pay-checklist-status`(微信/支付宝可下单与回调履约 checklist + 生产占位说明;只读) |
| 微信支付占位 | POST | `/api/v1/app/billing/wechat-pay/create`(无 `WECHAT_PAY_*` → **503**;env 齐全 → **501** 待接商户号) |
| 支付宝占位 | POST | `/api/v1/app/billing/alipay/create`(无 `ALIPAY_*` → **503**;env 齐全 → **501**) |

**租户侧关联(非 `/app` 前缀)**:

| 能力 | 方法 | 路径 |
|------|------|------|
| 监测扫描 | POST | `/api/v1/scans` |
| 当前用户 | GET | `/api/v1/me` |
| 开发登录 | POST | `/api/v1/auth/dev-session` |
| 登出 | POST | `/api/v1/auth/logout` |

### 1.3 租户演示片段

```bash
BASE=http://127.0.0.1:3000
JAR=/tmp/wm-geo-tenant.jar

# 登录
curl -sS -c "$JAR" -b "$JAR" -X POST "$BASE/api/v1/auth/dev-session" | jq .

# 品牌
curl -sS -b "$JAR" "$BASE/api/v1/app/brands" | jq '.items|length'

# 扫描(需先有 brandId)
curl -sS -b "$JAR" -X POST "$BASE/api/v1/scans" \
  -H 'Content-Type: application/json' \
  -d '{"brandId":"<uuid>","keywords":["测试词"],"engines":["deepseek"]}' | jq .

# 异步机(生成/发布/竞品刷新依赖)
curl -sS -X POST "$BASE/api/v1/internal/process-async-jobs" \
  -H "Authorization: Bearer $INTERNAL_JOB_SECRET" | jq .
```

### 1.4 国内支付占位(批次 EA)

| 入口 | 说明 |
|------|------|
| `/pricing` | 付费档「微信支付」「支付宝」按钮;**品牌下拉**(默认最近品牌),POST create 传 `brandId`;**登录态「fillDraft/submitDraft 真调 checklist」汇总卡**(`GET extension/fill-submit-draft-checklist-summary`;checklist `pricing_fill_submit_draft_summary`);**登录态「国内支付就绪」卡**(`GET pay-checklist-status` + aggregate badge + 支付接入路线图/账户设置链);**登录态「扩展真发 checklist」汇总卡**(`GET extension/real-publish-checklist-summary` + 链 Settings / 扩展引导;checklist `pricing_extension_real_publish_summary`);**登录态「扩展连接诊断」汇总卡**(`GET extension/connection-diagnosis` + 链 Settings / 扩展引导 / docs#extension-connection-steps;checklist `pricing_extension_connection_diagnosis`);**登录态「platform publish 状态」汇总卡**(`GET billing/platform-publish-status-context` + 链 Settings / 扩展引导 / 发文详情;checklist `pricing_platform_publish_status_card`);**登录态「定时 Cron 产品化」汇总卡**(`GET monitor/cron-productization-context?brandId=`;checklist `pricing_cron_productization_card`);**登录态「M5 引用监测」汇总卡**(`GET publications/citation-monitoring-status?brandId=`;checklist `pricing_citation_monitoring_card`);**登录态「PDF/OSS 报告导出」汇总卡**(`GET reports/export-oss-context?brandId=`;checklist `pricing_report_export_oss_card`);**`?brandId=` 登录态「M3 建议模块」卡**(`pricing_m3_card`)+ 底部优化建议/M3 模块链 |
| `/app/settings` | 订阅区 `ChinaPayPlanActions`(`?brandId=` 预填归属品牌);「最近订单」行内 `brandName` 链 `/app/brands/[brandId]`;**「扩展真发 checklist」汇总卡**(链扩展引导);`?brandId=` 时「当前品牌」链品牌详情 |
| `/docs/payment-roadmap` | 503/501 时链至 [`支付接入路线图.md`](./支付接入路线图.md) |

```bash
# 须先 dev-session(见 §1.3)
curl -sS -b "$JAR" -X POST "$BASE/api/v1/app/billing/wechat-pay/create" \
  -H 'Content-Type: application/json' -d '{"planId":"solo","brandId":"<uuid>"}' | jq .
# 本地无 WECHAT_PAY_* → 503 wechat_pay_not_configured

curl -sS -b "$JAR" -X POST "$BASE/api/v1/app/billing/alipay/create" \
  -H 'Content-Type: application/json' -d '{"planId":"solo","brandId":"<uuid>"}' | jq .
# 本地无 ALIPAY_* → 503 alipay_not_configured

curl -sS -b "$JAR" "$BASE/api/v1/app/billing/orders" | jq '.items[0].brandId,.items[0].brandName'
```

Stripe 海外档仍走 `billing/create-checkout-session` / Customer Portal。

**Settings 订阅并存(批次 HX)**:当 `GET /api/v1/app/billing/subscription` 的 `provider` 为 `wechat` / `alipay`,且 `GET /api/v1/me` 的 `integrations.stripe.billingStatus` 仍为 `active` 时,设置页「当前订阅」展示蓝色提示:**以 `subscriptions` 表为准**(支付渠道与 `planSlug` 已合并国内单;Stripe 用户列可能仍显示生效)。

```bash
# 验收:dev-session 后打开设置页订阅区
open http://127.0.0.1:3000/app/settings
```

微信支付异步回调(批次 IE):`POST /api/v1/webhooks/wechat-pay` 在 `WECHAT_PAY_PLATFORM_CERT`(或 `WECHAT_PAY_PLATFORM_CERT_PATH`)**非占位**时执行 V3 验签(`lib/billing/wechat-pay-notify.ts` · `verifyWechatPayNotifySignature`);`WECHAT_PAY_DEV_NOTIFY=1` 或 development + 占位/缺省证书可跳过。`trade_state=SUCCESS` 幂等写 `orders` 与用户套餐(`fulfillCnPayOrder` 内核)。

支付宝异步回调(批次 IB):`POST /api/v1/webhooks/alipay` 在 `ALIPAY_ALIPAY_PUBLIC_KEY` **非占位**时执行 RSA2 验签(`lib/billing/alipay-notify.ts` · `crypto.verify`);`ALIPAY_DEV_NOTIFY=1` 或 development + 占位公钥可跳过。`TRADE_SUCCESS` / `TRADE_FINISHED` 幂等写 `orders` 与用户套餐(与微信 notify 同 `fulfillCnPayOrder` 内核)。

```bash
# E2E/本地(ALIPAY_DEV_NOTIFY=1,明文 form 回调)
curl -sS -X POST "$BASE/api/v1/webhooks/alipay" \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data "out_trade_no=<out_trade_no>&trade_no=alipay_e2e_1&trade_status=TRADE_SUCCESS&total_amount=199.00"
```

### 1.5 浏览器扩展与 open-draft(批次 EB / EE / HY)

| 项 | 说明 |
|----|------|
| 引导页 | `/app/publish/extension`(**AUTO_SUBMIT** 说明与 `extension/options.html` 对齐;**四平台 DOM 真调验收卡** — `GET /api/v1/app/extension/dom-tuning-acceptance` + `/docs/demo-script#extension-dom-tuning-acceptance`) |
| 自动发布开关 | `chrome://extensions` → **wm-geo 发布助手** → **扩展选项**(`chrome-extension://<ID>/options.html`);勾选后写入 `WM_GEO_EXTENSION_AUTO_SUBMIT=1`,与 `NEXT_PUBLIC_WM_GEO_EXTENSION_AUTO_SUBMIT=1` 等效 |
| Settings AUTO_SUBMIT 说明(VQ–VS) | `GET /api/v1/app/extension/auto-submit-status`(JWT);Settings「扩展 AUTO_SUBMIT(真发开关)」卡:readiness badge + env/checklist + 扩展选项三步说明 |
| submitDraft 门禁(VW–VY) | `GET /api/v1/app/extension/submit-draft-gate`(JWT);`/app/publish/extension`「submitDraft 门禁(AUTO_SUBMIT)」卡;`content.js` 读取 `chrome.storage.local` 与 open-draft `autoSubmit` 或 gate |
| open-draft | 发布中心 / 发布详情 `ExtensionOpenDraftButton` → `wm-geo:open-draft`(推荐携带 title + bodyPlain);仅 `publicationId` 时须在**已登录控制台同源页**由扩展 `content.js` `fetch` `/api/v1/app/publications/:id`(无 CORS、跨域平台页不可用),转发 active tab 前补全 |
| 填表 + submitDraft | 四平台 MVP 半自动填表;**开启 AUTO_SUBMIT** 后 `submitDraft` 尝试点击发布/群发(默认关闭,仅填表;未开启返回 `auto_submit_disabled`) |
| 渠道 OAuth start(UJ) | `POST /api/v1/channels/:channel/oauth/start`(JWT);Settings「集成诊断」→「Chrome 扩展连接」→「连接 {平台}」;`WM_GEO_CHANNEL_OAUTH_DEV_BYPASS=1` 时返回 mock authorizeUrl → `GET …/oauth/callback` 重定向 returnTo |
| 渠道 OAuth token(UM) | callback dev bypass 写 `channel_oauth_tokens` mock token;`GET me/integrations.extension.oauth.connections` 摘要(不含 access_token);Settings「已连接渠道」badge |
| 渠道 OAuth 加密/refresh(UP–UR) | `WM_GEO_CHANNEL_OAUTH_TOKEN_SECRET`(≥16)时 access/refresh token 存库 **enc:v1:** AES-256-GCM;`POST /api/v1/channels/:channel/oauth/refresh` dev_mock 轮换 token;Settings「Token 加密」badge +「刷新 token」按钮 |
| 渠道 OAuth 生产 exchange(US–UU) | `WM_GEO_CHANNEL_*_OAUTH_CLIENT_ID/SECRET` + `WM_GEO_CHANNEL_OAUTH_EXCHANGE_SKELETON=1` 时 `GET …/oauth/exchange-status` checklist;callback `code=platform_skeleton` 存 **platform** token;Settings「Exchange 就绪」badge |
| 渠道 OAuth HTTP exchange(YG–YI) | 配置 `…_TOKEN_URL`(或平台默认端点);callback 真实授权 code 经 `exchange-channel-oauth-token-http` POST 换 token;E2E 默认 `WM_GEO_CHANNEL_ZHIHU_OAUTH_TOKEN_URL` → internal mock;Settings Exchange note 含 HTTP exchange 渠道数 |
| 渠道 OAuth HTTP refresh(YJ–YL) | platform token + `…_TOKEN_URL` 齐全时 `POST …/oauth/refresh` 经 `refresh-channel-oauth-token-http` 换 access_token;E2E mock 支持 `grant_type=refresh_token`;Settings Refresh note 含 HTTP refresh 渠道数 |
| open-draft OAuth 自动 refresh(YM–YO) | `GET …/open-draft-context` 检测 token 过期/即将过期时自动 `POST …/oauth/refresh` 后重读;DTO 含 `autoRefreshed`/`refreshHttp` + checklist **oauth_token_auto_refresh**;Publication 详情 **OAuth refresh badge** |
| submit-draft OAuth 自动 refresh(YP–YR) | `GET …/submit-draft-context` 检测 token 过期/即将过期时自动 `POST …/oauth/refresh` 后重读;DTO 含 `autoRefreshed`/`refreshHttp` + checklist **submit_draft_oauth_auto_refresh**;Publication 详情 **submitDraft OAuth refresh badge** |
| open-draft OAuth token(VK–VM) | `GET /api/v1/app/publications/:id/open-draft-context` 按 publication.channel 映射 platform 并会话内下发 access_token;`ExtensionOpenDraftButton` postMessage 携带 `oauthAccessToken`;详情页 OAuth badge |
| submitDraft OAuth token(VN–VP) | `GET /api/v1/app/publications/:id/submit-draft-context`;open-draft 写入 chrome.storage;`submitDraft` 读取 token 传入 adapter(`oauthAttached` 骨架);详情页「submitDraft OAuth 就绪」badge |
| 剪贴板 fallback | open-draft 后出现 **「复制正文到剪贴板」**(`navigator.clipboard`);无正文时提示先保存 `metrics_json.bodyPlain` |

演示:在目标平台创作页打开控制台,从 `/app/publish` 选草稿点「用扩展打开草稿」;未装扩展时可仅用复制 fallback。自动发布须在扩展选项或 env 中开启。

### 1.6 demo 脚本 step 6:报告 PDF(批次 DY)

`scripts/demo-full-business-path.sh` 在扫描出 `REPORT_ID` 后执行:

```bash
curl -sS -b "$JAR" -o /tmp/wm-geo-report.pdf \
  "$BASE/api/v1/app/reports/${REPORT_ID}/export?format=pdf"
head -c 5 /tmp/wm-geo-report.pdf   # 期望 %PDF-
```

与 `e2e/report-export-flow.spec.ts` 及报告页「下载 PDF」一致;可选 `WM_GEO_PDF_FONT_URL` 改善中文渲染。

---

## 2. Vendor(`/vendor` 门户)

登录:`/vendor/login` → 开发会话 `POST /api/v1/auth/vendor-dev-session`。

### 2.1 页面路径

| 路径 | 用途 |
|------|------|
| `/vendor/dashboard` | 接单/进行中/待结算概览(「待结算」KPI → `/vendor/settlements`) |
| `/vendor/tasks` | 任务列表 |
| `/vendor/tasks/[id]` | 任务详情、deliver 回填 `published_url`(可点击外链,与 Admin 代发台一致) |
| `/vendor/settlements` | 对账列表与导出 |
| `/vendor/settlements/[id]` | 对账详情 |
| `/vendor/profile` | 资料与单价 |

### 2.2 核心 API

| 能力 | 方法 | 路径 |
|------|------|------|
| 概览 | GET | `/api/v1/vendor/summary` |
| 任务列表 | GET | `/api/v1/vendor/tasks/list`(items 含 `brandId`/`brandName`) |
| 任务详情 | GET | `/api/v1/vendor/tasks/[id]`(task + sourcing 快照含 `brandId`/`brandName`) |
| 接单 | POST | `/api/v1/vendor/tasks/[id]/accept` |
| 交付 | POST | `/api/v1/vendor/tasks/[id]/deliver` |
| 完成 | POST | `/api/v1/vendor/tasks/[id]/complete` |
| 结算列表 | GET | `/api/v1/vendor/settlements/list`(items 含 `brandId`/`brandName`/`brandCount`,对账周期内已发布订单聚合) |
| 结算详情 | GET | `/api/v1/vendor/settlements/[id]`(item 含 `brandId`/`brandName`/`brandCount`) |
| 结算导出 | GET | `/api/v1/vendor/settlements/export` |
| 资料 | GET/PATCH | `/api/v1/vendor/profile` |
| 开发登录 | POST | `/api/v1/auth/vendor-dev-session` |

### 2.3 Vendor 演示片段

```bash
VJAR=/tmp/wm-geo-vendor.jar
curl -sS -c "$VJAR" -b "$VJAR" -X POST "$BASE/api/v1/auth/vendor-dev-session" | jq .
curl -sS -b "$VJAR" "$BASE/api/v1/vendor/tasks/list" | jq '.items|length'
curl -sS -b "$VJAR" "$BASE/api/v1/vendor/tasks/list" | jq '.items[0].brandName'
curl -sS -b "$VJAR" "$BASE/api/v1/vendor/settlements/list" | jq '.items[0].brandName'
# 履约(orderId 来自租户下单 + 运营指派)
curl -sS -b "$VJAR" -X POST "$BASE/api/v1/vendor/tasks/<orderId>/accept"
```

全链路中 accept → deliver → complete 见 **`demo-full-business-path.sh`** 第 11 步。

---

## 3. Admin(`/admin` 运营后台)

**仅 PC**;本地可 `ADMIN_DEV_BYPASS=1` 或租户 dev 用户 `is_admin`。

### 3.1 页面路径

| 路径 | 用途 |
|------|------|
| `/admin` | 总览(KPI「国内支付订单」卡片 → `/admin/billing/orders`;**「PDF/OSS 报告导出运维」卡** — `GET /api/v1/admin/reports/export-oss-status` PDF/OSS env + reports/scans 全库计数 + checklist **admin_report_export_oss_ops_summary** + 链业务跑通手册 / 阿里云 OSS 清单 / 租户历史报告 / Settings;**「M3 建议模块运维」卡** — `GET /api/v1/admin/m3/module-status` 租户 checklist + brands/generations/scans 全库计数 + PRD P1 缺口 + checklist **admin_m3_module_ops_summary** + 链业务跑通手册 / PRD 缺口路线图 / 租户 M3 hub / 优化建议;**「国内支付运维」卡** — `GET /api/v1/admin/billing/cn-pay-production-status` 双通道 env + orders/subscriptions 全库计数 + checklist **admin_cn_pay_production_ops_summary** + 链支付路线图 / 计费概览 / 国内支付订单 / 租户 Settings / 定价页;**「定时重测 Cron 运维」卡** — `GET /api/v1/admin/monitor/schedule-status` 全平台 checklist + readiness badge + 链 `/docs/business-runbook`;**「platform publish 运维」卡** — `GET /api/v1/admin/platform-publish-status` 全平台 OAuth/live_url/platform API 写回 checklist + readiness badge + 链 `/docs/demo-script` / 租户 Settings / 扩展引导;**「扩展连接运维」卡** — `GET /api/v1/admin/extension-connection-status` 全平台 OAuth/exchange/加密/live_url checklist + readiness badge + 链 `/docs/demo-script` / 租户 Settings / 扩展安装引导 / 扩展引导;**「扩展 DOM 真调运维」卡** — `GET /api/v1/admin/extension/dom-tuning-status` 四平台 dom-tuning-acceptance + DOM 骨架 + live_url/OAuth 全库计数 + checklist **admin_extension_dom_tuning_ops_summary** + 链 docs#extension-dom-tuning-acceptance / PRD 缺口路线图 / Settings / 扩展引导;**「fillDraft/submitDraft checklist 运维」卡** — `GET /api/v1/admin/extension/fill-submit-draft-status` 租户 fill/submit/DOM 真调/十八页汇总卡计数 + checklist **admin_extension_fill_submit_draft_ops_summary** + 链 docs#extension-real-publish-steps / Settings / 扩展引导;**「扩展真发 checklist 运维」卡** — `GET /api/v1/admin/extension-real-publish-status` 全平台 DOM/AUTO_SUBMIT/OAuth/live_url checklist + readiness badge + 链 `/docs/demo-script` / 租户 Settings / 扩展引导) |
| `/admin/users` | 用户与配额 |
| `/admin/orders` | 订阅订单 |
| `/admin/billing` | 计费总览 |
| `/admin/billing/subscriptions` | 订阅列表 |
| `/admin/billing/invoices` | 发票 |
| `/admin/billing/orders` | 国内支付订单(`orders` 游标分页;可按 `provider=wechat\|alipay` / `brandId` 筛选;**URL `?brandId=` 预填自动应用**;**品牌名列链 `/admin/brands/[id]`**;筛选区「当前品牌」链;空状态「查看品牌详情」链) |
| `/admin/source-orders` | 代发订单台(列表含 brandId/品牌名;可选 `?brandId=` 筛选 + **URL 预填自动应用**;**品牌名列链 `/admin/brands/[id]`**;筛选区「当前品牌」链;空状态「查看品牌详情」链) |
| `/admin/brands` | 用户品牌库(只读分页 + `?q=` / `?userEmail=` / `?userId=` 筛选 + **`?brandId=` 精确筛选 + URL 预填自动应用** + 筛选区「当前品牌」链 + 空状态「查看品牌详情」链 + CSV 导出) |
| `/admin/brands/[id]` | 品牌详情(counts + 邮箱掩码 + **运营管理快捷入口链 source-orders/billing/orders/audit/disputes/brands?brandId=** + **代发计数卡链代发订单台** + **「← 用户品牌库」链 `/admin/brands?brandId=`**) |
| `/admin/tasks/pool` | 任务池 |
| `/admin/tasks/mine` | 我的工作台 |
| `/admin/tasks/[itemId]` | 任务执行 |
| `/admin/sources` | 信源池 |
| `/admin/vendors` | 供应商 |
| `/admin/operators` | 运营员工 |
| `/admin/audit` | 内容审核(列表含 brandId/brandName;**`?brandId=` 筛选 + URL 预填**) |
| `/admin/withdrawals` | 撤稿队列 |
| `/admin/disputes` | 申诉(列表含 brandId/brandName,join 代发订单;**`?brandId=` 筛选 + URL 预填**) |
| `/admin/audit-logs` | 操作审计 |

### 3.2 核心 API

| 能力 | 方法 | 路径 |
|------|------|------|
| 总览 | GET | `/api/v1/admin/summary`(`cn_pay_orders`:paid/pending 计数) |
| 计费 MRR | GET | `/api/v1/admin/billing/summary` |
| 国内支付配置校验 | GET | `/api/v1/admin/billing/config-status`(微信/支付宝 env checklist + 生产占位说明;只读) |
| PDF/OSS 报告导出运维摘要 | GET | `/api/v1/admin/reports/export-oss-status`(env + reports/scans 全库计数 + checklist **admin_report_export_oss_ops_summary** / **demo_script_admin_pdf_oss_ops**;链 `/docs/demo-script#pdf-oss-ops-steps`;只读) |
| PDF/OSS Admin 运维 demo 步骤 | GET | `/api/v1/app/demo/pdf-oss-ops-steps`(聚合 export-oss-context + export-oss-status;Settings 演示卡 + demo step 7e) |
| M3 建议模块运维摘要 | GET | `/api/v1/admin/m3/module-status`(租户 checklist + brands/generations/scans 全库计数 + PRD P1 缺口 + checklist **admin_m3_module_ops_summary** / **demo_script_admin_m3_ops**;链 `/docs/demo-script#m3-admin-ops-steps`;只读) |
| extension Admin 运维 demo 步骤 | GET | `/api/v1/app/demo/extension-admin-ops-steps`(聚合 real-publish-checklist-summary + Admin 六卡运维子 API;Settings 演示卡 + demo step 7h) |
| 国内支付生产运维摘要 | GET | `/api/v1/admin/billing/cn-pay-production-status`(env + orders/subscriptions 全库计数 + `cnPaySubscriptionsTotal` + checklist **admin_cn_pay_production_ops_summary** / **admin_billing_subscriptions_list** / **demo_script_admin_cn_pay_ops**;链 `/admin/billing/subscriptions` · `/docs/demo-script#cn-pay-ops-steps`;只读) |
| 国内支付 Admin 运维 demo 步骤 | GET | `/api/v1/app/demo/cn-pay-ops-steps`(聚合 pay-checklist-status + cn-pay-production-status;Settings 演示卡 + demo step 7d) |
| 定时重测 Cron 运维 | GET | `/api/v1/admin/monitor/schedule-status`(全平台 INTERNAL_JOB_SECRET/间隔/活跃关键词与品牌/待入队/下次计划/pending monitored_scan checklist;只读) |
| 定时 Cron 产品化运维摘要 | GET | `/api/v1/admin/monitor/cron-productization-status`(三条 Cron 脚本 + 22 页租户汇总卡 + scheduled 发文/异步任务全库计数 + checklist **admin_cron_productization_ops_summary** / **demo_script_admin_cron_ops**;链 `/docs/demo-script#cron-admin-ops-steps`;只读) |
| platform publish 运维 | GET | `/api/v1/admin/platform-publish-status`(全平台 OAuth 租户数/live_url 写回/platform API 写回 + env skeleton checklist;只读) |
| 扩展连接运维 | GET | `/api/v1/admin/extension-connection-status`(全平台 OAuth/exchange/加密/live_url + P0 连接 checklist 聚合;只读) |
| M5 跨品牌引用对比运维摘要 | GET | `/api/v1/admin/m5/citation-comparison-status`(全库 **brandCount/brandsWithHitsInWindow/totalInWindow/topRows** + checklist **admin_m5_citation_comparison_ops_summary** + demo 链;只读) |
| M5 汇总运维入口 | GET | `/api/v1/admin/m5/citation-ops-hub-status`(六子卡聚合计数 + 证据抽屉/趋势 checklist + **admin_m5_citation_ops_hub_summary** + demo 链;只读) |
| M5 证据/趋势运维摘要 | GET | `/api/v1/admin/m5/citation-evidence-trend-ops-status`(全库 **totalCitationHitCount/hitsWithEvidenceExcerptCount/hitsInWindow30Count/publicationsWithHitsInWindowCount/brandsWithTrendDataCount/capturePublicationCount** + checklist **admin_m5_citation_evidence_trend_ops_summary** + demo 链;只读) |
| M5 L2/L3 段引/语义引运维摘要 | GET | `/api/v1/admin/m5/citation-l2-l3-ops-status`(全库 **citationL2HitCount/citationL3HitCount/titleCitedHitCount/paragraphQuotedHitCount/publicationsWithL2HitsCount/publicationsWithL3HitsCount** + checklist **admin_m5_citation_l2_l3_ops_summary** + demo 链;只读) |
| M5 L3 embedding API 运维摘要 | GET | `/api/v1/admin/m5/embedding-ops-status`(全库 **citationL3HitCount/embeddingL3ScanCount/publicationsWithL3HitsCount/embeddingApiConfigured** + checklist **admin_m5_embedding_ops_summary** + demo 链;只读) |
| M5 embedding Admin 运维 demo 步骤 | GET | `/api/v1/app/demo/m5-embedding-ops-steps`(聚合 m5/embedding-status + admin/m5/embedding-ops-status;Settings 演示卡 + demo step 11e) |
| M5 citation_hits CSV 导出运维摘要 | GET | `/api/v1/admin/m5/citation-hits-csv-export-status`(全库 **totalCitationHitCount/publicationsWithHitsCount/citationL2HitCount/citationL3HitCount/csvExportAuditCount** + checklist **admin_m5_citation_hits_csv_export_ops_summary** + demo 链;只读) |
| M5 AI 回答抓取/链式 scan 运维摘要 | GET | `/api/v1/admin/m5/ai-answer-capture-status`(全库 **capturePublicationCount/chainPublicationCount/manualCaptureCount/cronCaptureCount/totalL2HitCount/totalL3HitCount** + checklist **admin_m5_ai_answer_capture_ops_summary** + demo 链;只读) |
| M5 引用监测运维摘要 | GET | `/api/v1/admin/m5/citation-monitoring-status`(六引擎 L1 URL 规则 + D+ 节点 + published/live_url/L1 eligible + **citationHitCount/citationScanCount** + **cronCaptureCount/cronChainCount** 全库计数 + checklist **admin_m5_citation_scheduler_auto_*** / **admin_m5_citation_monitoring_ops_summary** + demo 链;只读) |
| 扩展 DOM 真调运维摘要 | GET | `/api/v1/admin/extension/dom-tuning-status`(四平台 dom-tuning-acceptance **acceptanceDepth** + stable selectors/URL capture 对齐 + DOM 骨架 + live_url/OAuth 全库计数 + checklist **extension_dom_tuning_acceptance_depth** / **admin_extension_dom_tuning_ops_summary**;只读) |
| fillDraft/submitDraft checklist 运维摘要 | GET | `/api/v1/admin/extension/fill-submit-draft-status`(租户 fill/submit checklist 对齐 + **十八页汇总卡**计数 + DOM 真调/AUTO_SUBMIT + checklist **admin_extension_fill_submit_draft_ops_summary** + demo 链;只读) |
| 扩展 live_url 写回运维 | GET | `/api/v1/admin/extension/live-url-backfill-status`(live_url/已发布+live_url/extension 审计/platform API 写回计数 + stable-url-capture pattern + checklist **admin_extension_live_url_backfill_ops_summary**;只读) |
| 扩展真发 checklist 运维 | GET | `/api/v1/admin/extension-real-publish-status`(全平台 DOM 骨架/AUTO_SUBMIT/OAuth/live_url + P0 checklist 聚合;只读) |
| 国内支付订单 | GET | `/api/v1/admin/billing/orders`(`cursor`/`status`/`provider`/`q`;邮箱掩码) |
| 国内支付订单 CSV | GET | `/api/v1/admin/billing/orders/export?format=csv`(可选 `provider=wechat\|alipay` 与列表一致;finance/auditor;最多 5000 行;审计 `admin.billing.orders.export_csv`) |
| 代发订单 | GET/PATCH | `/api/v1/admin/source-orders`、`[id]`(GET 可选 `?brandId=` UUID 筛选) |
| 撤稿批准/驳回 | POST | `/api/v1/admin/publications/[id]/withdraw-approve`、`withdraw-reject` |
| 生成审核 | POST | `/api/v1/admin/generations/[id]/approve`、`reject` |
| 用户 | GET | `/api/v1/admin/users` |
| 任务池/我的 | GET | `/api/v1/admin/tasks/pool`、`mine` |
| 审计日志 | GET | `/api/v1/admin/audit-logs` |
| 申诉队列 | GET | `/api/v1/admin/disputes`(join 代发订单 `brand_id` → `brandId`/`brandName`;可选 **`?brandId=`** 按品牌筛选,无效 UUID **400**) |

### 3.3 Admin 演示片段

```bash
# 指派供应商(orderId 来自租户 create)
curl -sS -b "$JAR" -X PATCH "$BASE/api/v1/admin/source-orders/<orderId>" \
  -H 'Content-Type: application/json' \
  -d '{"assignedVendorSubject":"00000000-0000-0000-0000-00000000e002"}' | jq .

# 撤稿批准
curl -sS -b "$JAR" -X POST "$BASE/api/v1/admin/publications/<pubId>/withdraw-approve" \
  -H 'Content-Type: application/json' \
  -d '{"targetStatus":"withdrawn"}' | jq .
```

---

## 4. 公开 / 营销(无需登录)

| 路径 | API |
|------|-----|
| `/diagnose` | `POST /api/v1/diagnose/anon` |
| `/contact` | `POST /api/v1/public/contact`(`ContactInquiryForm` 已接线) |
| `/r/[shareToken]` | `GET /api/v1/public-reports/[shareToken]` |
| `/pricing` | `GET /api/v1/public/plans` |
| 健康检查 | `GET /api/v1/health` |

### 4.1 联系表单写库

- **表**:`contact_inquiries`(迁移 `20260519210000_contact_inquiries`)
- **接口**:`POST /api/v1/public/contact` — 校验通过后写入;无 `DATABASE_URL` 时 **503**;按 IP 限流(429 时 E2E 会 skip)
- **审计**:`WM_GEO_PUBLIC_CONTACT_AUDIT=1` 时异步 `audit_logs`(不含蜜罐字段)
- **页面**:`/contact` 使用 `components/marketing/ContactInquiryForm.tsx`

```bash
# 最小合法提交(需求描述 ≥10 字)
curl -sS -X POST "$BASE/api/v1/public/contact" \
  -H 'Content-Type: application/json' \
  -d '{"name":"测","email":"you@example.com","message":"1234567890"}' | jq .
# 期望:{"ok":true}
```

---

## 5. 定时任务(Cron)

均需环境变量 **`INTERNAL_JOB_SECRET`**(Bearer,≥16 字符)。脚本位于 `scripts/`。

| 脚本 | 命中 API | 作用 |
|------|----------|------|
| `cron-process-async-jobs.sh` | `POST /api/v1/internal/process-async-jobs` | 处理 pending 异步任务(`generate_run`、`publication_publish`、`report_regenerate`、`monitored_scan` 等) |
| `cron-process-scheduled-publications.sh` | `POST /api/v1/internal/process-scheduled-publications` | 到点 `scheduled` 发文入队并发布 |
| `cron-process-scheduled-scans.sh` | `POST /api/v1/internal/process-scheduled-scans` | 关键词 `scheduled_at` 到期入队监测扫描 |

租户侧只读摘要:`GET /api/v1/app/monitor/schedule-status`(Keywords / **Dashboard / BrandDetail**「定时重测」卡);深化汇总:`GET /api/v1/app/monitor/cron-productization-context`(**Settings / Reports / Dashboard / Keywords / BrandDetail / Pricing / ScanDetail / Generate / Sourcing / SourcingOrders / Publications / NewPublication / Publish / Published / M3 hub / Suggestions / Competitors**「定时 Cron 产品化」卡);运维细节见 `scripts/README-cron.md` 与 `/docs/business-runbook` §5。

**crontab 示例**(勿把密钥写在 crontab 明文,用 env 文件):

```cron
*/5 * * * * cd /path/to/wm-geo && . ./.env.local && ./scripts/cron-process-async-jobs.sh
*/10 * * * * cd /path/to/wm-geo && . ./.env.local && ./scripts/cron-process-scheduled-publications.sh
0 * * * * cd /path/to/wm-geo && . ./.env.local && ./scripts/cron-process-scheduled-scans.sh
```

---

## 6. 验收清单(手工)

- [ ] `./scripts/demo-full-business-path.sh` 全程无 `exit 1`(含 step 6 PDF `%PDF-`)
- [ ] `/pricing` 或 `/app/settings` 国内支付按钮返回 503/501 且文案可读
- [ ] `/app/publish` open-draft 后可「复制正文到剪贴板」
- [ ] `/app` 仪表盘可打开,快捷入口可跳转各模块
- [ ] `/vendor/dashboard` 快捷入口可跳转任务台、对账、任务说明(profile)
- [ ] `/admin` 首页快捷入口可跳转审核、撤稿、代发订单、计费、运营
- [ ] `/r/<shareToken>` 公开报告可读
- [ ] Vendor 任务列表可见已指派订单并完成三态
- [ ] Admin 撤稿批准后 publication 状态为 `withdrawn`
- [ ] `node scripts/backfill-brand-id.mjs` dry-run 无异常(有历史 null 行时)
- [ ] `npm run lint` 与 `npm run build` 通过
- [ ] `npx playwright test`(`next start` 已起)全绿;或至少 `e2e/demo-script-smoke.spec.ts` 通过
- [ ] `POST /api/v1/public/contact` 返回 `{"ok":true}` 且库表 `contact_inquiries` 有新行

---

## 7. 相关文档

- 全链路脚本源码:`scripts/demo-full-business-path.sh`
- **上线配置(env / Cron / HSTS·CSP)**:[`上线配置清单.md`](./上线配置清单.md) · [`.env.production.example`](../.env.production.example)
- 产品可交付说明:[`可交付版本说明.md`](./可交付版本说明.md)
- 研发交付边界:[`当前交付边界.md`](./当前交付边界.md)
- 仓库 README:[`README.md`](../README.md)
- 会话纪要:`docs/会话开发纪要-Cursor-2026-05.md`
- 页面 IA:`docs/PRD-页面功能与设计需求.md`
- 阿里云交付勾选项:`docs/aliyun-d1-checklist.md`
- 环境变量全集:`.env.example`