2026-04-01 00:58:42 +08:00
|
|
|
|
# GEO 双后台与后端技术架构方案 V1
|
|
|
|
|
|
|
2026-04-20 13:52:35 +08:00
|
|
|
|
> 工作记录说明:本文仍保留作为历史架构记录。其中涉及浏览器插件执行链路、`/api/callback/plugin/*`、`plugin_sessions`、`installation_token` 的相关章节,自 2026-04-20 起视为旧版设计;当前实现请以 desktop client 方案和最新代码为准。
|
|
|
|
|
|
|
2026-04-01 00:58:42 +08:00
|
|
|
|
## 1. 文档信息
|
|
|
|
|
|
|
|
|
|
|
|
| 项目 | 内容 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| 文档名称 | GEO 双后台与后端技术架构方案 V1 |
|
|
|
|
|
|
| 文档版本 | V1.0 |
|
|
|
|
|
|
| 文档状态 | 待评审 |
|
|
|
|
|
|
| 创建日期 | 2026-03-25 |
|
|
|
|
|
|
| 适用范围 | `admin-web`、`ops-admin-web` 与 Go 后端整体架构设计 |
|
|
|
|
|
|
| 关联文档 | `docs/geo-platform-prd-v1.md` |
|
|
|
|
|
|
| 关联文档 | `docs/geo-platform-ops-admin-prd-v1.md` |
|
|
|
|
|
|
| 关联文档 | `docs/geo-platform-tech-architecture-v1-50k.md` |
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 目标与结论
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 建设目标
|
|
|
|
|
|
|
|
|
|
|
|
本方案用于明确 GEO 平台在 V1 阶段的双后台形态与后端落地方式,满足以下目标:
|
|
|
|
|
|
|
|
|
|
|
|
- 面向租户提供独立的业务后台 `admin-web`
|
|
|
|
|
|
- 面向平台内部提供独立的管理后台 `ops-admin-web`
|
|
|
|
|
|
- 后端统一采用 Go 实现,控制复杂度,同时保留后续拆分能力
|
|
|
|
|
|
- 支撑内容生成、知识学习、任务运维、额度管理、平台配置和审计能力
|
|
|
|
|
|
- 在 V1 阶段做到“结构清晰、实现收敛、可持续演进”
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 核心结论
|
|
|
|
|
|
|
|
|
|
|
|
V1 推荐采用以下架构策略:
|
|
|
|
|
|
|
|
|
|
|
|
- 前端采用 `pnpm workspace + Vue 3 + TypeScript + ant-design-vue + Vite 8(截至 2026-03 官方稳定主线)`
|
|
|
|
|
|
|
|
|
|
|
|
- 前端拆分为两个独立应用:`apps/admin-web` 和 `apps/ops-admin-web`
|
|
|
|
|
|
|
|
|
|
|
|
- 公共能力通过 `packages/*` 复用,而不是让两个应用互相引用业务代码
|
|
|
|
|
|
|
|
|
|
|
|
- 后端采用 `Go + Gin + PostgreSQL + Redis + RabbitMQ + Qdrant + 对象存储`
|
|
|
|
|
|
|
|
|
|
|
|
- 对象存储支持双实现:公有云部署推荐 `阿里云 OSS + CDN`,私有化部署推荐 `MinIO + Nginx / CDN`
|
|
|
|
|
|
|
|
|
|
|
|
- 工程脚手架可使用 [`sponge`](https://github.com/go-dev-frame/sponge),但仅用于项目初始化、基础设施接线与简单样板生成;不直接生成业务 `handler/service/dao` 主体代码,领域边界仍以本文的 `transport -> app -> domain -> repository` 分层为准
|
|
|
|
|
|
|
|
|
|
|
|
- 后端拆分为 `gateway + tenant-api + platform-api + scheduler + 多个 Worker`,其中 `gateway` 必须保持超薄
|
|
|
|
|
|
|
|
|
|
|
|
- API 按路由前缀隔离:`/api/tenant/*` 与 `/api/platform/*`
|
|
|
|
|
|
|
|
|
|
|
|
- 权限按两层建模:`tenant_role` 与 `platform_role`
|
|
|
|
|
|
|
|
|
|
|
|
- 重任务统一异步化,任务进度通过 `SSE` 或短轮询回写
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 架构边界
|
|
|
|
|
|
|
|
|
|
|
|
| 维度 | `admin-web` | `ops-admin-web` |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| 服务对象 | 租户用户 | 平台内部人员 |
|
|
|
|
|
|
| 数据范围 | 当前租户 | 全平台或指定租户 |
|
|
|
|
|
|
| 核心目标 | 生成、发布、查看内容与数据 | 管租户、管配置、管任务、管风险 |
|
|
|
|
|
|
| 权限模型 | `tenant_role` | `platform_role` |
|
|
|
|
|
|
| API 前缀 | `/api/tenant/*` | `/api/platform/*` |
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 仓库结构方案
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 推荐目录
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
D:\project\geo
|
|
|
|
|
|
├─ apps
|
|
|
|
|
|
│ ├─ admin-web
|
|
|
|
|
|
│ ├─ ops-admin-web
|
|
|
|
|
|
│ └─ browser-extension
|
|
|
|
|
|
├─ packages
|
|
|
|
|
|
│ ├─ ui
|
|
|
|
|
|
│ ├─ shared-types
|
|
|
|
|
|
│ ├─ http-client
|
|
|
|
|
|
│ ├─ utils
|
|
|
|
|
|
│ ├─ eslint-config
|
|
|
|
|
|
│ └─ tsconfig
|
|
|
|
|
|
├─ server
|
|
|
|
|
|
│ ├─ cmd
|
|
|
|
|
|
│ │ ├─ gateway
|
|
|
|
|
|
│ │ ├─ tenant-api
|
|
|
|
|
|
│ │ ├─ platform-api
|
|
|
|
|
|
│ │ ├─ scheduler
|
|
|
|
|
|
│ │ ├─ worker-generate
|
|
|
|
|
|
│ │ ├─ worker-knowledge
|
|
|
|
|
|
│ │ ├─ worker-analytics
|
|
|
|
|
|
│ │ └─ worker-publish-callback
|
|
|
|
|
|
│ ├─ internal
|
|
|
|
|
|
│ ├─ migrations
|
|
|
|
|
|
│ ├─ sql
|
|
|
|
|
|
│ └─ pkg
|
|
|
|
|
|
├─ deploy
|
|
|
|
|
|
│ ├─ docker-compose
|
|
|
|
|
|
│ └─ k8s
|
|
|
|
|
|
└─ docs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 前端共享包建议
|
|
|
|
|
|
|
|
|
|
|
|
- `packages/ui`
|
|
|
|
|
|
- 通用布局、表格筛选栏、状态标签、详情抽屉、权限按钮
|
|
|
|
|
|
- `packages/shared-types`
|
|
|
|
|
|
- 前后端共用 DTO、分页结构、状态枚举、角色枚举
|
|
|
|
|
|
- `packages/http-client`
|
|
|
|
|
|
- Axios 实例、鉴权拦截器、错误处理、统一响应解包
|
|
|
|
|
|
- `packages/utils`
|
|
|
|
|
|
- 时间、金额、脱敏、下载、表格导出等工具
|
|
|
|
|
|
- `packages/eslint-config`
|
|
|
|
|
|
- 统一 ESLint 规则
|
|
|
|
|
|
- `packages/tsconfig`
|
|
|
|
|
|
- 统一 TS 配置基线
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 是否需要第三个前端应用
|
|
|
|
|
|
|
|
|
|
|
|
当前双后台方案覆盖了租户侧和平台侧的控制面,但租户侧 V1 的媒体绑定与手动发布还依赖独立执行面。
|
|
|
|
|
|
|
|
|
|
|
|
因此 V1 建议同步建设:
|
|
|
|
|
|
|
|
|
|
|
|
- `apps/browser-extension`
|
|
|
|
|
|
|
|
|
|
|
|
该应用不属于当前“双后台”主体,但属于 V1 必选执行端,负责真实登录检测、绑定回传、图片上传、手动发布和状态校验。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 前端完整方案
|
|
|
|
|
|
|
|
|
|
|
|
## 4.1 `apps/admin-web` 定位
|
|
|
|
|
|
|
|
|
|
|
|
租户端后台,主要服务于租户管理员与编辑,负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 工作台
|
|
|
|
|
|
- 文章生成与管理
|
|
|
|
|
|
- 品牌与知识库管理
|
|
|
|
|
|
- 媒体账号绑定与手动发布
|
|
|
|
|
|
- 数据追踪与套餐额度查看
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1.1 路由建议
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/login
|
|
|
|
|
|
/workspace
|
|
|
|
|
|
/articles
|
|
|
|
|
|
/articles/:id
|
|
|
|
|
|
/brands
|
|
|
|
|
|
/knowledge
|
|
|
|
|
|
/media
|
|
|
|
|
|
/tracking
|
|
|
|
|
|
/account
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1.2 页面特点
|
|
|
|
|
|
|
|
|
|
|
|
- 业务操作多
|
|
|
|
|
|
- 任务状态多
|
|
|
|
|
|
- 详情页和表单较多
|
|
|
|
|
|
- 需要关注生成与发布的过程反馈
|
|
|
|
|
|
|
|
|
|
|
|
## 4.2 `apps/ops-admin-web` 定位
|
|
|
|
|
|
|
|
|
|
|
|
平台管理员端,主要服务于超级管理员、平台运营、客服支持、财务运营、审核风控与技术运维,负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 平台工作台
|
|
|
|
|
|
- 租户中心
|
|
|
|
|
|
- 套餐与额度
|
|
|
|
|
|
- 平台用户与角色
|
|
|
|
|
|
- 模型中心
|
|
|
|
|
|
- 内容配置
|
|
|
|
|
|
- 任务运维
|
|
|
|
|
|
- 监控告警
|
|
|
|
|
|
- 审计中心
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2.1 路由建议
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/login
|
|
|
|
|
|
/platform/dashboard
|
|
|
|
|
|
/platform/tenants
|
|
|
|
|
|
/platform/tenants/:id
|
|
|
|
|
|
/platform/plans
|
|
|
|
|
|
/platform/platform-users
|
|
|
|
|
|
/platform/models
|
|
|
|
|
|
/platform/content
|
|
|
|
|
|
/platform/tasks
|
|
|
|
|
|
/platform/monitoring
|
|
|
|
|
|
/platform/audit
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2.2 页面特点
|
|
|
|
|
|
|
|
|
|
|
|
- 列表、筛选、统计卡片较多
|
|
|
|
|
|
- 高风险操作较多
|
|
|
|
|
|
- 权限粒度更细
|
|
|
|
|
|
- 更偏运维、审计、治理和配置管理
|
|
|
|
|
|
|
|
|
|
|
|
## 4.3 前端技术栈建议
|
|
|
|
|
|
|
|
|
|
|
|
- `vue`
|
|
|
|
|
|
- `typescript`
|
|
|
|
|
|
- `vite`
|
|
|
|
|
|
- `pnpm`
|
|
|
|
|
|
- `ant-design-vue`
|
|
|
|
|
|
- `vue-router`
|
|
|
|
|
|
- `pinia`
|
|
|
|
|
|
- `@tanstack/vue-query`
|
|
|
|
|
|
- `axios`
|
|
|
|
|
|
- `zod`
|
|
|
|
|
|
- `@vueuse/core`
|
|
|
|
|
|
- `dayjs`
|
|
|
|
|
|
- `vitest`
|
|
|
|
|
|
|
|
|
|
|
|
## 4.4 前端工程规范
|
|
|
|
|
|
|
|
|
|
|
|
- 每个应用独立 `src`,共享能力全部进入 `packages`
|
|
|
|
|
|
- 菜单、按钮、路由权限全部由权限配置表驱动
|
|
|
|
|
|
- 页面模式统一为:`筛选区 + 表格区 + 详情抽屉 / 详情页`
|
|
|
|
|
|
- 长任务状态统一使用 `状态标签 + 默认轮询`,仅在存在运行中任务的活跃页面临时升级为 `SSE`
|
|
|
|
|
|
- 高风险按钮统一带确认弹窗和原因输入框
|
|
|
|
|
|
|
|
|
|
|
|
## 4.5 前端部署建议
|
|
|
|
|
|
|
|
|
|
|
|
- `admin-web` 和 `ops-admin-web` 独立构建、独立发布
|
|
|
|
|
|
- 推荐独立域名或子路径:
|
|
|
|
|
|
- `admin.xxx.com`
|
|
|
|
|
|
- `ops.xxx.com`
|
|
|
|
|
|
- 两套前端都走 CDN,后端统一走 API 域名
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 后端完整方案
|
|
|
|
|
|
|
|
|
|
|
|
## 5.1 V1 后端总体策略
|
|
|
|
|
|
|
|
|
|
|
|
V1 推荐:
|
|
|
|
|
|
|
|
|
|
|
|
- `1 个统一网关出口`
|
|
|
|
|
|
- `2 个 Go API 服务`
|
|
|
|
|
|
- `1 个 Scheduler`
|
|
|
|
|
|
- `4 类异步 Worker`
|
|
|
|
|
|
- `1 个浏览器插件执行端`
|
|
|
|
|
|
- `1 套统一基础设施`
|
|
|
|
|
|
|
|
|
|
|
|
其中:
|
|
|
|
|
|
|
|
|
|
|
|
- `tenant-api` 负责租户侧核心业务
|
|
|
|
|
|
- `platform-api` 负责平台治理与内部管理
|
|
|
|
|
|
- `gateway` 负责统一接入、路由转发、公共鉴权、租户级限流与 `request_id` 注入
|
|
|
|
|
|
|
|
|
|
|
|
V1 保留 `gateway`,但必须满足以下硬约束:
|
|
|
|
|
|
|
|
|
|
|
|
- 只做 `route + auth + rate limit + request_id/trace_id 注入 + 错误响应封装`
|
|
|
|
|
|
- 不承载任何 `tenant/*` 或 `platform/*` 业务逻辑
|
|
|
|
|
|
- 不直接写 PostgreSQL 业务表,不发 MQ 业务消息,不做任务编排
|
|
|
|
|
|
- 若未来部署环境极简,可由 `Ingress / Nginx` 直接分流到 `tenant-api` 与 `platform-api`;本文默认仍保留超薄 `gateway`
|
|
|
|
|
|
|
|
|
|
|
|
这样可以避免:
|
|
|
|
|
|
|
|
|
|
|
|
- 过早微服务化
|
|
|
|
|
|
- 大量跨服务联调
|
|
|
|
|
|
- 权限和数据边界复杂化
|
|
|
|
|
|
- 运维成本提前爆炸
|
|
|
|
|
|
|
|
|
|
|
|
同时,V1 不建议把 `worker-generate / worker-knowledge / worker-analytics / worker-publish-callback` 合并成单一 Worker 进程,因为:
|
|
|
|
|
|
|
|
|
|
|
|
- 交互式生成链路的时延目标高于知识学习和统计聚合
|
|
|
|
|
|
- LLM、Embedding、统计聚合的资源模型不同
|
|
|
|
|
|
- 回调补偿链路需要与用户生成链路故障隔离
|
|
|
|
|
|
- 运维简化更适合通过共享容器基座、统一 Helm 模板和统一日志规范实现,而不是牺牲任务隔离
|
|
|
|
|
|
|
|
|
|
|
|
## 5.2 Go 后端目录结构
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
server
|
|
|
|
|
|
├─ cmd
|
|
|
|
|
|
│ ├─ gateway
|
|
|
|
|
|
│ ├─ tenant-api
|
|
|
|
|
|
│ ├─ platform-api
|
|
|
|
|
|
│ ├─ scheduler
|
|
|
|
|
|
│ ├─ worker-generate
|
|
|
|
|
|
│ ├─ worker-knowledge
|
|
|
|
|
|
│ ├─ worker-analytics
|
|
|
|
|
|
│ └─ worker-publish-callback
|
|
|
|
|
|
├─ internal
|
|
|
|
|
|
│ ├─ bootstrap
|
|
|
|
|
|
│ ├─ shared
|
|
|
|
|
|
│ │ ├─ auth
|
|
|
|
|
|
│ │ ├─ config
|
|
|
|
|
|
│ │ ├─ middleware
|
|
|
|
|
|
│ │ ├─ observability
|
|
|
|
|
|
│ │ ├─ plugin
|
|
|
|
|
|
│ │ ├─ retrieval
|
|
|
|
|
|
│ │ ├─ scheduler
|
|
|
|
|
|
│ │ ├─ sse
|
|
|
|
|
|
│ │ ├─ repository
|
|
|
|
|
|
│ │ │ ├─ postgres
|
|
|
|
|
|
│ │ │ ├─ redis
|
|
|
|
|
|
│ │ │ ├─ rabbitmq
|
|
|
|
|
|
│ │ │ ├─ qdrant
|
|
|
|
|
|
│ │ │ └─ objectstorage
|
|
|
|
|
|
│ │ └─ dto
|
|
|
|
|
|
│ ├─ tenant
|
|
|
|
|
|
│ │ ├─ transport
|
|
|
|
|
|
│ │ ├─ app
|
|
|
|
|
|
│ │ ├─ domain
|
|
|
|
|
|
│ │ └─ repository
|
|
|
|
|
|
│ ├─ platform
|
|
|
|
|
|
│ │ ├─ transport
|
|
|
|
|
|
│ │ ├─ app
|
|
|
|
|
|
│ │ ├─ domain
|
|
|
|
|
|
│ │ └─ repository
|
|
|
|
|
|
│ ├─ jobs
|
|
|
|
|
|
│ └─ gateway
|
|
|
|
|
|
├─ migrations
|
|
|
|
|
|
├─ sql
|
|
|
|
|
|
└─ pkg
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 5.3 API 路由分层建议
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3.1 公共接口
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/health/*`
|
|
|
|
|
|
- `/api/auth/*`
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3.2 租户端接口
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/tenant/workspace/*`
|
|
|
|
|
|
- `/api/tenant/articles/*`
|
|
|
|
|
|
- `/api/tenant/brands/*`
|
|
|
|
|
|
- `/api/tenant/knowledge/*`
|
|
|
|
|
|
- `/api/tenant/media/*`
|
|
|
|
|
|
- `/api/tenant/tracking/*`
|
|
|
|
|
|
- `/api/tenant/account/*`
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3.3 平台管理员端接口
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/platform/dashboard/*`
|
|
|
|
|
|
- `/api/platform/tenants/*`
|
|
|
|
|
|
- `/api/platform/plans/*`
|
|
|
|
|
|
- `/api/platform/platform-users/*`
|
|
|
|
|
|
- `/api/platform/models/*`
|
|
|
|
|
|
- `/api/platform/content/*`
|
|
|
|
|
|
- `/api/platform/integrations/*`
|
|
|
|
|
|
- `/api/platform/tasks/*`
|
|
|
|
|
|
- `/api/platform/monitoring/*`
|
|
|
|
|
|
- `/api/platform/audit/*`
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3.4 回调与内部接口
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/callback/plugin/*`
|
|
|
|
|
|
- `/api/internal/metrics/*`
|
|
|
|
|
|
- `/api/internal/task-events/*`
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3.5 网关转发关系
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/auth/*` -> `gateway` 或共享认证模块
|
|
|
|
|
|
- `/api/tenant/*` -> `tenant-api`
|
|
|
|
|
|
- `/api/platform/*` -> `platform-api`
|
|
|
|
|
|
- `/api/callback/*` -> `tenant-api`
|
|
|
|
|
|
|
|
|
|
|
|
## 5.4 后端二进制职责
|
|
|
|
|
|
|
|
|
|
|
|
| 二进制 | 作用 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `cmd/gateway` | 统一 API 出口、无状态路由分发、基础鉴权、租户级限流、`request_id/trace_id` 注入与统一错误响应封装 |
|
|
|
|
|
|
| `cmd/tenant-api` | 提供租户端业务接口、任务状态接口、按需 SSE、插件会话与插件回调接口 |
|
|
|
|
|
|
| `cmd/platform-api` | 提供平台管理员端接口、租户治理、模型配置、审计与监控查询 |
|
|
|
|
|
|
| `cmd/scheduler` | 扫描定时生成、数据监控等到期任务,生成调度批次并入队 |
|
|
|
|
|
|
| `cmd/worker-generate` | 处理模板生成、Prompt 生成、批量生成与文章优化任务,并负责 RAG 检索、LLM 超时/限流/并发池控制 |
|
|
|
|
|
|
| `cmd/worker-knowledge` | 处理知识学习、解析、批量 Embedding、Qdrant 写入与 chunk 元数据维护 |
|
|
|
|
|
|
| `cmd/worker-analytics` | 处理问题采集、分析快照、统计聚合、缓存刷新;默认走低优先级模型通道 |
|
|
|
|
|
|
| `cmd/worker-publish-callback` | 处理发布回调、状态回写、失败补偿 |
|
|
|
|
|
|
|
|
|
|
|
|
## 5.5 后端模块职责
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.1 `shared/auth`
|
|
|
|
|
|
|
|
|
|
|
|
- 登录
|
|
|
|
|
|
- Token 颁发与校验
|
|
|
|
|
|
- 用户身份识别
|
|
|
|
|
|
- 平台角色 / 租户角色装载
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.2 `shared/retrieval`
|
|
|
|
|
|
|
|
|
|
|
|
- 统一封装 query rewrite、filter 构造、Qdrant 检索、rerank 与上下文拼装
|
|
|
|
|
|
- 为 `worker-generate` 暴露品牌知识 RAG 检索入口
|
|
|
|
|
|
- V1 将 `retrieval_logs` 和 badcase 采样先写文件日志或对象存储,后续再升级为数据库评测体系
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.3 `tenant`
|
|
|
|
|
|
|
|
|
|
|
|
- 租户基础资料
|
|
|
|
|
|
- 租户状态
|
|
|
|
|
|
- 租户成员与租户角色
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.4 `platform`
|
|
|
|
|
|
|
|
|
|
|
|
- 平台管理员用户
|
|
|
|
|
|
- 平台角色
|
|
|
|
|
|
- 平台配置与平台级查询
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.5 `tenant/article` / `tenant/brand` / `tenant/knowledge`
|
|
|
|
|
|
|
|
|
|
|
|
- 租户业务核心能力
|
|
|
|
|
|
- 生成内容、品牌资料、知识库管理
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.6 `platform/quota` / `platform/plan`
|
|
|
|
|
|
|
|
|
|
|
|
- 套餐配置
|
|
|
|
|
|
- 配额消耗
|
|
|
|
|
|
- 配额补量
|
|
|
|
|
|
- 到期与重置规则
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.7 `platform/model`
|
|
|
|
|
|
|
|
|
|
|
|
- LLM 配置
|
|
|
|
|
|
- Embedding 配置
|
|
|
|
|
|
- 限流策略
|
|
|
|
|
|
- 默认模型策略
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.8 `tenant/task` + `platform/task`
|
|
|
|
|
|
|
|
|
|
|
|
- 任务入队
|
|
|
|
|
|
- 状态查询
|
|
|
|
|
|
- 重试与终止
|
|
|
|
|
|
- 死信处理
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.9 `platform/monitoring`
|
|
|
|
|
|
|
|
|
|
|
|
- 服务健康
|
|
|
|
|
|
- 队列状态
|
|
|
|
|
|
- Worker 状态
|
|
|
|
|
|
- 告警汇总
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.10 `platform/audit`
|
|
|
|
|
|
|
|
|
|
|
|
- 操作日志
|
|
|
|
|
|
- 配置变更日志
|
|
|
|
|
|
- 额度变更日志
|
|
|
|
|
|
- 风险操作日志
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5.11 `shared/observability`
|
|
|
|
|
|
|
|
|
|
|
|
- 统一结构化日志规范与日志字段
|
|
|
|
|
|
- 统一 `request_id`、`trace_id`、`task_batch_id` 透传
|
|
|
|
|
|
- Prometheus 指标、健康检查、慢查询与队列深度观测
|
|
|
|
|
|
- 为 API、MQ、Worker 共用的错误码与告警标签提供基础设施
|
|
|
|
|
|
|
|
|
|
|
|
## 5.6 服务边界建议
|
|
|
|
|
|
|
|
|
|
|
|
### 5.6.1 `tenant-api` 负责
|
|
|
|
|
|
|
|
|
|
|
|
- 租户工作台
|
|
|
|
|
|
- 品牌、文章、知识库
|
|
|
|
|
|
- 媒体绑定与发布记录
|
|
|
|
|
|
- 生成任务提交与状态查询
|
|
|
|
|
|
- 租户侧额度消耗校验
|
|
|
|
|
|
- 发布回调接收
|
|
|
|
|
|
|
|
|
|
|
|
### 5.6.2 `platform-api` 负责
|
|
|
|
|
|
|
|
|
|
|
|
- 平台工作台
|
|
|
|
|
|
- 租户管理
|
|
|
|
|
|
- 套餐与额度策略
|
|
|
|
|
|
- 平台用户与平台角色
|
|
|
|
|
|
- 模型配置与模板规则
|
|
|
|
|
|
- 任务运维查询与重试控制
|
|
|
|
|
|
- 监控告警与审计中心
|
|
|
|
|
|
|
|
|
|
|
|
### 5.6.3 两服务协作原则
|
|
|
|
|
|
|
|
|
|
|
|
- `platform-api` 不直接承载租户高频业务流量
|
|
|
|
|
|
- `tenant-api` 不同步依赖 `platform-api` 完成核心链路
|
|
|
|
|
|
- 平台侧对租户业务的控制,优先通过数据库规则、缓存配置或内部命令完成
|
|
|
|
|
|
- 需要重试或控制任务时,由 `platform-api` 写控制记录并重新入队或调用内部接口
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 认证与权限架构
|
|
|
|
|
|
|
|
|
|
|
|
## 6.1 统一身份模型
|
|
|
|
|
|
|
|
|
|
|
|
建议统一 `users` 主表,但角色绑定拆分:
|
|
|
|
|
|
|
|
|
|
|
|
- `platform_user_roles`
|
|
|
|
|
|
- `tenant_memberships`
|
|
|
|
|
|
|
|
|
|
|
|
这样一个账号可以:
|
|
|
|
|
|
|
|
|
|
|
|
- 既是平台内部用户
|
|
|
|
|
|
- 也可能是某个租户的成员
|
|
|
|
|
|
|
|
|
|
|
|
但两种权限链路必须分开校验。
|
|
|
|
|
|
|
|
|
|
|
|
## 6.2 权限模型
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2.1 平台角色 `platform_role`
|
|
|
|
|
|
|
|
|
|
|
|
- `super_admin`
|
|
|
|
|
|
- `ops`
|
|
|
|
|
|
- `sre`
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2.2 租户角色 `tenant_role`
|
|
|
|
|
|
|
|
|
|
|
|
- `tenant_admin`
|
|
|
|
|
|
- `editor`
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2.3 租户角色能力边界
|
|
|
|
|
|
|
|
|
|
|
|
| 角色 | 主要能力 | 明确限制 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `tenant_admin` | 租户设置、成员管理、模板/Prompt/品牌/知识/媒体、发布、配额查看、风险操作确认 | 无平台级治理权限 |
|
|
|
|
|
|
| `editor` | 创建与编辑文章、模板、Prompt、品牌、知识、媒体发布、查看追踪数据 | 不能管理成员、套餐策略、平台级配置 |
|
|
|
|
|
|
|
|
|
|
|
|
V1 权限模型按当前产品裁剪口径收敛为 `tenant_admin + editor` 两种租户角色;`viewer` 暂不单列,若后续出现严格只读协作者场景,可再由 `editor` 细分。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2.4 Prompt 分享身份 `kol_profile`
|
|
|
|
|
|
|
|
|
|
|
|
- `kol` 不是权限角色,而是用户在 Prompt 分享场景下的作者/达人身份
|
|
|
|
|
|
- `kol` 用户可生成分享码,供普通用户导入新的“文章模板类型”
|
|
|
|
|
|
- 分享内容本质上是“模板卡片 + 变量槽位定义 + 使用说明 + 受保护 Prompt 资产引用”的快照,而不是裸 Prompt 文本
|
|
|
|
|
|
- 导入后会在工作台或模板页形成新的模板卡片,作为平台预设模板之外的扩展文章类型
|
|
|
|
|
|
- 公司名、地址、品牌名、联系方式等租户专属字段仍由导入方在变量槽位中自行填写或绑定
|
|
|
|
|
|
- KOL 的原始 Prompt 正文对普通用户不可见,不可导出,不可在前端编辑,用于保护 Prompt 版权
|
|
|
|
|
|
- `kol_profile` 通过 `prompt_share_profiles` 与 `prompt_share_codes` 建模,不参与 RBAC 鉴权
|
|
|
|
|
|
|
|
|
|
|
|
## 6.3 鉴权中间件顺序
|
|
|
|
|
|
|
|
|
|
|
|
1. Token 校验
|
|
|
|
|
|
2. 用户身份解析
|
|
|
|
|
|
3. 路由前缀识别
|
|
|
|
|
|
4. 平台角色或租户角色装载
|
|
|
|
|
|
5. 资源范围校验
|
|
|
|
|
|
6. 风险操作校验
|
|
|
|
|
|
7. 审计上下文注入
|
|
|
|
|
|
|
|
|
|
|
|
## 6.4 风险操作要求
|
|
|
|
|
|
|
|
|
|
|
|
以下操作建议统一纳入风险操作:
|
|
|
|
|
|
|
|
|
|
|
|
- 冻结 / 解冻租户
|
|
|
|
|
|
- 调整套餐额度
|
|
|
|
|
|
- 修改模型默认策略
|
|
|
|
|
|
- 修改敏感词规则
|
|
|
|
|
|
- 批量重试任务
|
|
|
|
|
|
- 修改平台适配器配置
|
|
|
|
|
|
|
|
|
|
|
|
这些操作至少具备:
|
|
|
|
|
|
|
|
|
|
|
|
- 二次确认
|
|
|
|
|
|
- 操作原因
|
|
|
|
|
|
- 审计日志
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 数据与中间件方案
|
|
|
|
|
|
|
|
|
|
|
|
## 7.1 PostgreSQL
|
|
|
|
|
|
|
|
|
|
|
|
负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 用户、租户、成员、角色关系
|
|
|
|
|
|
- 品牌、文章、发布记录
|
|
|
|
|
|
- 套餐、额度、账期
|
|
|
|
|
|
- 模型配置、模板配置
|
|
|
|
|
|
- 任务记录
|
|
|
|
|
|
- 告警记录
|
|
|
|
|
|
- 审计日志
|
|
|
|
|
|
- 配额预扣与调度租约
|
|
|
|
|
|
- 知识 chunk 元数据
|
|
|
|
|
|
|
|
|
|
|
|
## 7.2 Redis
|
|
|
|
|
|
|
|
|
|
|
|
负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 登录黑名单
|
|
|
|
|
|
- 高频查询缓存
|
|
|
|
|
|
- 仪表盘热点数据
|
|
|
|
|
|
- 任务短期状态缓存
|
|
|
|
|
|
- 限流计数
|
|
|
|
|
|
- SSE 跨 Pod 广播
|
|
|
|
|
|
|
|
|
|
|
|
## 7.3 RabbitMQ
|
|
|
|
|
|
|
|
|
|
|
|
负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 文章生成任务
|
|
|
|
|
|
- 知识学习任务
|
|
|
|
|
|
- 分析聚合任务
|
|
|
|
|
|
- 发布回调任务
|
|
|
|
|
|
- 死信队列
|
|
|
|
|
|
|
|
|
|
|
|
## 7.4 Qdrant
|
|
|
|
|
|
|
|
|
|
|
|
负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 知识库向量存储
|
|
|
|
|
|
- RAG 检索
|
|
|
|
|
|
|
|
|
|
|
|
## 7.5 对象存储
|
|
|
|
|
|
|
|
|
|
|
|
负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 原始文档
|
|
|
|
|
|
- 图片素材
|
|
|
|
|
|
- 导入导出文件
|
|
|
|
|
|
- 原始抓取结果
|
|
|
|
|
|
- 原始模型回答与插件回调归档
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 双后台与后端交互图
|
|
|
|
|
|
|
|
|
|
|
|
以下为主架构的宏观交互图,细化后的闭环版本以 §13.5.1 为准。
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart LR
|
|
|
|
|
|
subgraph FE["前端应用"]
|
|
|
|
|
|
AW["admin-web<br/>租户端"]
|
|
|
|
|
|
OW["ops-admin-web<br/>平台管理员端"]
|
|
|
|
|
|
EXT["browser-extension<br/>V1 发布执行端"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AW --> CDN["CDN / Nginx"]
|
|
|
|
|
|
OW --> CDN
|
|
|
|
|
|
|
|
|
|
|
|
CDN --> ING["Ingress / API Gateway"]
|
|
|
|
|
|
EXT --> ING
|
|
|
|
|
|
|
|
|
|
|
|
ING --> GW["gateway"]
|
|
|
|
|
|
GW --> TA["tenant-api"]
|
|
|
|
|
|
GW --> PA["platform-api"]
|
|
|
|
|
|
SCH["scheduler"] --> PG["PostgreSQL"]
|
|
|
|
|
|
SCH --> MQ["RabbitMQ"]
|
|
|
|
|
|
|
|
|
|
|
|
TA --> PG["PostgreSQL"]
|
|
|
|
|
|
TA --> REDIS["Redis"]
|
|
|
|
|
|
TA --> MQ["RabbitMQ"]
|
|
|
|
|
|
TA --> OBJ["Object Storage"]
|
|
|
|
|
|
TA --> QD["Qdrant"]
|
|
|
|
|
|
|
|
|
|
|
|
PA --> PG
|
|
|
|
|
|
PA --> REDIS
|
|
|
|
|
|
PA --> MQ
|
|
|
|
|
|
|
|
|
|
|
|
MQ --> WG["worker-generate"]
|
|
|
|
|
|
MQ --> WK["worker-knowledge"]
|
|
|
|
|
|
MQ --> WA["worker-analytics"]
|
|
|
|
|
|
MQ --> WP["worker-publish-callback"]
|
|
|
|
|
|
|
|
|
|
|
|
WG --> PG
|
|
|
|
|
|
WG --> REDIS
|
|
|
|
|
|
WG --> QD
|
|
|
|
|
|
|
|
|
|
|
|
WK --> PG
|
|
|
|
|
|
WK --> QD
|
|
|
|
|
|
WK --> OBJ
|
|
|
|
|
|
|
|
|
|
|
|
WA --> PG
|
|
|
|
|
|
WA --> REDIS
|
|
|
|
|
|
WA --> OBJ
|
|
|
|
|
|
|
|
|
|
|
|
WP --> PG
|
|
|
|
|
|
WP --> REDIS
|
|
|
|
|
|
PA --> TA
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 后端结构图
|
|
|
|
|
|
|
|
|
|
|
|
以下为主架构的模块示意图;二进制职责、共享模块和运行约束以 §13.5 与 §13.13 为准。
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart TB
|
|
|
|
|
|
subgraph CMD["cmd"]
|
|
|
|
|
|
GWBIN["gateway"]
|
|
|
|
|
|
TENBIN["tenant-api"]
|
|
|
|
|
|
PLTBIN["platform-api"]
|
|
|
|
|
|
SCHBIN["scheduler"]
|
|
|
|
|
|
GENBIN["worker-generate"]
|
|
|
|
|
|
KBBIN["worker-knowledge"]
|
|
|
|
|
|
ANABIN["worker-analytics"]
|
|
|
|
|
|
PUBBIN["worker-publish-callback"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
subgraph SHARED["internal/shared"]
|
|
|
|
|
|
SAUTH["auth"]
|
|
|
|
|
|
SMIDDLE["middleware"]
|
|
|
|
|
|
SPLUGIN["plugin"]
|
|
|
|
|
|
SRET["retrieval"]
|
|
|
|
|
|
SSCHED["scheduler"]
|
|
|
|
|
|
SREPO["shared repositories"]
|
|
|
|
|
|
SSSE["sse"]
|
|
|
|
|
|
SOBS["observability"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
subgraph TENANT["internal/tenant"]
|
|
|
|
|
|
TTRANS["transport"]
|
|
|
|
|
|
TAPP["app"]
|
|
|
|
|
|
TDOMAIN["domain"]
|
|
|
|
|
|
TREPO["repository"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
subgraph PLATFORM["internal/platform"]
|
|
|
|
|
|
PTRANS["transport"]
|
|
|
|
|
|
PAPP["app"]
|
|
|
|
|
|
PDOMAIN["domain"]
|
|
|
|
|
|
PREPO["repository"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
subgraph JOBS["internal/jobs"]
|
|
|
|
|
|
JGEN["generate job"]
|
|
|
|
|
|
JKB["knowledge job"]
|
|
|
|
|
|
JANA["analytics job"]
|
|
|
|
|
|
JPUB["publish callback job"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
subgraph INFRA["infra"]
|
|
|
|
|
|
PGREPO["postgres"]
|
|
|
|
|
|
REDISREPO["redis"]
|
|
|
|
|
|
MQREPO["rabbitmq"]
|
|
|
|
|
|
QDREPO["qdrant"]
|
|
|
|
|
|
OBJREPO["objectstorage"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
GWBIN --> SAUTH
|
|
|
|
|
|
GWBIN --> SMIDDLE
|
|
|
|
|
|
|
|
|
|
|
|
TENBIN --> TTRANS
|
|
|
|
|
|
TENBIN --> SAUTH
|
|
|
|
|
|
TENBIN --> SPLUGIN
|
|
|
|
|
|
TENBIN --> SSSE
|
|
|
|
|
|
TENBIN --> SOBS
|
|
|
|
|
|
|
|
|
|
|
|
PLTBIN --> PTRANS
|
|
|
|
|
|
PLTBIN --> SAUTH
|
|
|
|
|
|
PLTBIN --> SOBS
|
|
|
|
|
|
|
|
|
|
|
|
SCHBIN --> SSCHED
|
|
|
|
|
|
SCHBIN --> SOBS
|
|
|
|
|
|
|
|
|
|
|
|
TTRANS --> TAPP
|
|
|
|
|
|
TAPP --> TDOMAIN
|
|
|
|
|
|
TAPP --> TREPO
|
|
|
|
|
|
|
|
|
|
|
|
PTRANS --> PAPP
|
|
|
|
|
|
PAPP --> PDOMAIN
|
|
|
|
|
|
PAPP --> PREPO
|
|
|
|
|
|
|
|
|
|
|
|
GENBIN --> JGEN
|
|
|
|
|
|
KBBIN --> JKB
|
|
|
|
|
|
ANABIN --> JANA
|
|
|
|
|
|
PUBBIN --> JPUB
|
|
|
|
|
|
|
|
|
|
|
|
JGEN --> SRET
|
|
|
|
|
|
JGEN --> TREPO
|
|
|
|
|
|
JKB --> TREPO
|
|
|
|
|
|
JANA --> PREPO
|
|
|
|
|
|
JPUB --> TREPO
|
|
|
|
|
|
JPUB --> PREPO
|
|
|
|
|
|
|
|
|
|
|
|
TREPO --> SREPO
|
|
|
|
|
|
PREPO --> SREPO
|
|
|
|
|
|
|
|
|
|
|
|
SRET --> SREPO
|
|
|
|
|
|
SREPO --> PGREPO
|
|
|
|
|
|
SREPO --> REDISREPO
|
|
|
|
|
|
SREPO --> MQREPO
|
|
|
|
|
|
SREPO --> QDREPO
|
|
|
|
|
|
SREPO --> OBJREPO
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 核心链路设计
|
|
|
|
|
|
|
|
|
|
|
|
## 10.1 租户端生成链路
|
|
|
|
|
|
|
|
|
|
|
|
1. `admin-web` 提交生成请求
|
|
|
|
|
|
2. API 校验租户身份、额度、参数
|
|
|
|
|
|
3. `tenant-api` 在同一 PostgreSQL 事务内完成“额度预扣 / 保留 + `generation_tasks` / `task_records` 创建 + 文章占位记录初始化”
|
|
|
|
|
|
4. 事务提交后写入 RabbitMQ
|
|
|
|
|
|
5. `worker-generate` 消费任务,先经 `shared/retrieval` 执行 `query rewrite -> filter -> Qdrant 检索 -> rerank -> 上下文拼装`
|
|
|
|
|
|
6. `worker-generate` 在超时、限流、并发池保护下调用模型
|
|
|
|
|
|
7. 成功时在同一 PostgreSQL 事务内写入 `article_versions`、更新 `articles`、确认额度消耗;失败时写失败状态并按条退还额度
|
|
|
|
|
|
8. 结果写入 Redis,前端通过 SSE 或轮询感知任务进度
|
|
|
|
|
|
|
|
|
|
|
|
## 10.2 平台端额度调整链路
|
|
|
|
|
|
|
|
|
|
|
|
1. `ops-admin-web` 发起额度变更
|
|
|
|
|
|
2. API 校验 `platform_role`
|
|
|
|
|
|
3. 写入额度变更记录
|
|
|
|
|
|
4. 更新租户额度表与缓存
|
|
|
|
|
|
5. 写入审计日志
|
|
|
|
|
|
6. 租户端下一次请求按新额度生效
|
|
|
|
|
|
|
|
|
|
|
|
## 10.3 平台端任务排查链路
|
|
|
|
|
|
|
|
|
|
|
|
1. `ops-admin-web` 查询失败任务列表
|
|
|
|
|
|
2. API 聚合 PostgreSQL 任务信息、错误信息与重试信息
|
|
|
|
|
|
3. 平台人员发起重试
|
|
|
|
|
|
4. API 写入重试记录并重新入队
|
|
|
|
|
|
5. Worker 执行后回写结果
|
|
|
|
|
|
6. 审计中心记录操作人和结果
|
|
|
|
|
|
|
|
|
|
|
|
## 10.4 监控与告警链路
|
|
|
|
|
|
|
|
|
|
|
|
1. Go API 与 Worker 暴露指标
|
|
|
|
|
|
2. 监控系统采集服务、队列、缓存、数据库指标
|
|
|
|
|
|
3. 告警服务生成异常记录
|
|
|
|
|
|
4. `ops-admin-web` 查询并展示告警状态
|
|
|
|
|
|
|
|
|
|
|
|
## 11. 部署建议
|
|
|
|
|
|
|
|
|
|
|
|
## 11.1 本地开发
|
|
|
|
|
|
|
|
|
|
|
|
- 前端:`pnpm` 工作区本地联调
|
|
|
|
|
|
- 基础设施:`docker compose` 仅启动 PostgreSQL、Redis、RabbitMQ、Qdrant、MinIO
|
|
|
|
|
|
- 后端服务建议本地 `go run`,按需启动:
|
|
|
|
|
|
- `go run ./server/cmd/gateway`
|
|
|
|
|
|
- `go run ./server/cmd/tenant-api`
|
|
|
|
|
|
- `go run ./server/cmd/platform-api`
|
|
|
|
|
|
- `go run ./server/cmd/scheduler`
|
|
|
|
|
|
- `go run ./server/cmd/worker-generate`
|
|
|
|
|
|
- `go run ./server/cmd/worker-knowledge`
|
|
|
|
|
|
- `go run ./server/cmd/worker-analytics`
|
|
|
|
|
|
- `go run ./server/cmd/worker-publish-callback`
|
|
|
|
|
|
- 建议提供 `make dev-init` 或等价任务脚本,统一完成:
|
|
|
|
|
|
- 执行 migration
|
|
|
|
|
|
- 创建 RabbitMQ 队列 / exchange / routing key
|
|
|
|
|
|
- 初始化 MinIO bucket
|
|
|
|
|
|
- 写入最小种子数据与本地模型通道配置
|
|
|
|
|
|
|
|
|
|
|
|
## 11.2 测试与预发
|
|
|
|
|
|
|
|
|
|
|
|
- 前端独立构建产物
|
|
|
|
|
|
- API 与 Worker 独立容器
|
|
|
|
|
|
- 使用共享测试基础设施或云托管实例
|
|
|
|
|
|
|
|
|
|
|
|
## 11.3 线上生产
|
|
|
|
|
|
|
|
|
|
|
|
- `admin-web` 与 `ops-admin-web` 独立发布到 CDN
|
|
|
|
|
|
- API 与 Worker 部署到 Kubernetes
|
|
|
|
|
|
- PostgreSQL、Redis、RabbitMQ、Qdrant 使用高可用或托管方案
|
|
|
|
|
|
|
|
|
|
|
|
## 12. 演进路线
|
|
|
|
|
|
|
|
|
|
|
|
### 12.1 V1
|
|
|
|
|
|
|
|
|
|
|
|
- 两个前端应用
|
|
|
|
|
|
- 一个浏览器插件执行端
|
|
|
|
|
|
- 一个统一网关出口
|
|
|
|
|
|
- 两个 Go API 服务
|
|
|
|
|
|
- 一个 Scheduler
|
|
|
|
|
|
- 四类 Worker
|
|
|
|
|
|
- 平台端与租户端路由隔离
|
|
|
|
|
|
|
|
|
|
|
|
### 12.2 V1.5
|
|
|
|
|
|
|
|
|
|
|
|
- 抽离统一审计模块
|
|
|
|
|
|
- 抽离模型网关模块
|
|
|
|
|
|
- 增加平台接入配置中心
|
|
|
|
|
|
|
|
|
|
|
|
### 12.3 V2
|
|
|
|
|
|
|
|
|
|
|
|
- 按压力拆分平台 API 与租户 API
|
|
|
|
|
|
- 单独拆出 `ops-bff` 或 `platform-api`
|
|
|
|
|
|
- 单独拆出 `analytics-service`
|
|
|
|
|
|
|
|
|
|
|
|
## 13. V1 闭环补齐方案
|
|
|
|
|
|
|
|
|
|
|
|
### 13.1 适用说明
|
|
|
|
|
|
|
|
|
|
|
|
本节结合以下材料对前文进行补齐修订,并作为 V1 详细落地的统一口径:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/refer/*`
|
|
|
|
|
|
- `docs/geo-platform-prd-v1.md`
|
|
|
|
|
|
- `docs/geo-platform-ops-admin-prd-v1.md`
|
|
|
|
|
|
- `docs/media-binding-and-publish-v1.md`
|
|
|
|
|
|
- `docs/question-driven-monitoring-design-v1.md`
|
|
|
|
|
|
- `docs/Claude_architecture_review.md`
|
|
|
|
|
|
|
|
|
|
|
|
若本节与前文较早的抽象表述存在冲突,以本节为准。
|
|
|
|
|
|
|
|
|
|
|
|
### 13.2 修订结论
|
|
|
|
|
|
|
|
|
|
|
|
为保证 `docs/refer` 中 8 个页面在 V1 阶段形成“页面 -> 路由 -> API -> 对象 -> 任务 -> 存储 -> 状态回传”的完整闭环,V1 对总体架构做如下修订:
|
|
|
|
|
|
|
|
|
|
|
|
- `apps/browser-extension` 从“后续可选”提升为 `V1 必选执行端`
|
|
|
|
|
|
- 后端实际形态明确为:`gateway + tenant-api + platform-api + scheduler + 4 类 Worker + browser-extension`
|
|
|
|
|
|
- `tenant-api` 按业务拆分为 `workspace / template / prompt-rule / schedule / article / optimization / brand / knowledge / media / tracking / account`
|
|
|
|
|
|
- `worker-generate` 同时承载 `模板生成 / Prompt 生成 / 批量生成 / 文章优化`
|
|
|
|
|
|
- 工作台模板卡片支持“平台预设 + 租户自建 + KOL 分享码导入”三种来源,导入后统一物化为租户模板
|
|
|
|
|
|
- `数据追踪` 采用“问题驱动监控”模型,最小采集单元为 `question_version x model x run_time`
|
|
|
|
|
|
- 工作台、数据追踪、任务状态统一提供聚合接口,避免前端首屏发起过多散请求
|
|
|
|
|
|
- 所有长任务统一接入 `task_records + SSE + 轮询兜底`
|
|
|
|
|
|
|
|
|
|
|
|
### 13.3 功能闭环矩阵
|
|
|
|
|
|
|
|
|
|
|
|
| 功能页 | 核心路由 | 核心 API 组 | 核心对象 | 异步/执行组件 |
|
|
|
|
|
|
| --- | --- | --- | --- | --- |
|
|
|
|
|
|
| 工作台 | `/workspace` | `/api/tenant/workspace/*` | `articles` `article_templates` `brands` `platform_accounts` `tenant_plan_subscriptions` | `worker-generate` `worker-publish-callback` |
|
|
|
|
|
|
| 模板创作 | `/articles/template` | `/api/tenant/templates/*` `/api/tenant/prompt-shares/*` `/api/tenant/articles/*` | `article_templates` `prompt_share_codes` `articles` `generation_tasks` | `worker-generate` |
|
|
|
|
|
|
| 自定义生成 | `/articles/custom/*` | `/api/tenant/prompt-rules/*` `/api/tenant/schedules/*` `/api/tenant/articles/*` | `prompt_rules` `schedule_tasks` `generation_tasks` | `scheduler` `worker-generate` |
|
|
|
|
|
|
| 文章优化 | `/articles/optimize` | `/api/tenant/optimizations/*` `/api/tenant/articles/*` | `optimization_tasks` `article_versions` | `worker-generate` |
|
|
|
|
|
|
| 媒体管理 | `/media` | `/api/tenant/media/*` `/api/callback/plugin/*` | `media_platforms` `platform_accounts` `plugin_sessions` `publish_records` | `browser-extension` `worker-publish-callback` |
|
|
|
|
|
|
| 品牌词库 | `/brands` `/brands/:id` | `/api/tenant/brands/*` | `brands` `brand_keywords` `brand_questions` `brand_question_versions` `competitors` | `worker-analytics` |
|
|
|
|
|
|
| 知识库 | `/knowledge` | `/api/tenant/knowledge/*` | `knowledge_groups` `knowledge_items` `knowledge_parse_tasks` | `worker-knowledge` |
|
|
|
|
|
|
| 数据追踪 | `/tracking/overview` `/tracking/detail` | `/api/tenant/tracking/*` | `question_monitor_runs` `question_monitor_parse_results` `keyword_model_daily_metrics` `keyword_model_top_questions_daily` `keyword_model_citation_rank_daily` | `scheduler` `worker-analytics` |
|
|
|
|
|
|
|
|
|
|
|
|
### 13.4 细化前端路由
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.4.1 `admin-web`
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/login
|
|
|
|
|
|
/workspace
|
|
|
|
|
|
/articles/template
|
|
|
|
|
|
/articles/template/create
|
|
|
|
|
|
/articles/custom
|
|
|
|
|
|
/articles/custom/instant
|
|
|
|
|
|
/articles/custom/scheduled
|
|
|
|
|
|
/articles/custom/prompts
|
|
|
|
|
|
/articles/optimize
|
|
|
|
|
|
/articles/:id
|
|
|
|
|
|
/articles/:id/publish-records
|
|
|
|
|
|
/brands
|
|
|
|
|
|
/brands/:id
|
|
|
|
|
|
/knowledge
|
|
|
|
|
|
/media
|
|
|
|
|
|
/tracking/overview
|
|
|
|
|
|
/tracking/detail
|
|
|
|
|
|
/account
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.4.2 `ops-admin-web`
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/login
|
|
|
|
|
|
/platform/dashboard
|
|
|
|
|
|
/platform/tenants
|
|
|
|
|
|
/platform/tenants/:id
|
|
|
|
|
|
/platform/plans
|
|
|
|
|
|
/platform/platform-users
|
|
|
|
|
|
/platform/platform-roles
|
|
|
|
|
|
/platform/models/llm
|
|
|
|
|
|
/platform/models/embedding
|
|
|
|
|
|
/platform/models/channels
|
|
|
|
|
|
/platform/models/limits
|
|
|
|
|
|
/platform/content/templates
|
|
|
|
|
|
/platform/content/prompts
|
|
|
|
|
|
/platform/content/tags
|
|
|
|
|
|
/platform/content/sensitive-rules
|
|
|
|
|
|
/platform/integrations/media-platforms
|
|
|
|
|
|
/platform/integrations/adapters
|
|
|
|
|
|
/platform/integrations/publish-policies
|
|
|
|
|
|
/platform/tasks/generation
|
|
|
|
|
|
/platform/tasks/knowledge
|
|
|
|
|
|
/platform/tasks/publish
|
|
|
|
|
|
/platform/tasks/analytics
|
|
|
|
|
|
/platform/tasks/dead-letter
|
|
|
|
|
|
/platform/monitoring/services
|
|
|
|
|
|
/platform/monitoring/queues
|
|
|
|
|
|
/platform/monitoring/workers
|
|
|
|
|
|
/platform/monitoring/storage
|
|
|
|
|
|
/platform/monitoring/alerts
|
|
|
|
|
|
/platform/audit/operations
|
|
|
|
|
|
/platform/audit/config-changes
|
|
|
|
|
|
/platform/audit/quota-changes
|
|
|
|
|
|
/platform/audit/risk-actions
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 13.5 服务、二进制与模块补齐
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.5.1 修订后的整体交互图
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart LR
|
|
|
|
|
|
AW["admin-web"] --> CDN["CDN / Nginx"]
|
|
|
|
|
|
OW["ops-admin-web"] --> CDN
|
|
|
|
|
|
EXT["browser-extension"] <---> AW
|
|
|
|
|
|
|
|
|
|
|
|
CDN --> GW["gateway"]
|
|
|
|
|
|
GW --> TA["tenant-api"]
|
|
|
|
|
|
GW --> PA["platform-api"]
|
|
|
|
|
|
|
|
|
|
|
|
SCH["scheduler"] --> PG["PostgreSQL"]
|
|
|
|
|
|
SCH --> MQ["RabbitMQ"]
|
|
|
|
|
|
|
|
|
|
|
|
TA --> PG
|
|
|
|
|
|
TA --> REDIS["Redis"]
|
|
|
|
|
|
TA --> MQ
|
|
|
|
|
|
TA --> OBJ["Object Storage"]
|
|
|
|
|
|
TA --> QD["Qdrant"]
|
|
|
|
|
|
|
|
|
|
|
|
PA --> PG
|
|
|
|
|
|
PA --> REDIS
|
|
|
|
|
|
PA --> MQ
|
|
|
|
|
|
|
|
|
|
|
|
EXT --> CB["/api/callback/plugin/*"]
|
|
|
|
|
|
CB --> TA
|
|
|
|
|
|
|
|
|
|
|
|
MQ --> WG["worker-generate"]
|
|
|
|
|
|
MQ --> WK["worker-knowledge"]
|
|
|
|
|
|
MQ --> WA["worker-analytics"]
|
|
|
|
|
|
MQ --> WP["worker-publish-callback"]
|
|
|
|
|
|
|
|
|
|
|
|
WG --> QD
|
|
|
|
|
|
WA --> OBJ
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.5.2 二进制职责补齐
|
|
|
|
|
|
|
|
|
|
|
|
| 二进制/执行端 | 职责 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `cmd/gateway` | 统一入口、公共鉴权、限流、`request_id/trace_id` 注入与统一错误响应封装;保持无状态,支持水平扩容 |
|
|
|
|
|
|
| `cmd/tenant-api` | 承载租户侧全部业务接口、SSE、插件会话管理、回调落库 |
|
|
|
|
|
|
| `cmd/platform-api` | 承载平台治理、套餐额度、平台用户、模型中心、平台接入、监控审计 |
|
|
|
|
|
|
| `cmd/scheduler` | 扫描 `schedule_tasks` 和数据监控计划,按到期窗口生成调度批次并入队 |
|
|
|
|
|
|
| `cmd/worker-generate` | 执行模板生成、Prompt 生成、批量生成、文章优化;通过 `shared/retrieval` 做 RAG 检索,并使用独立 LLM 并发池控制交互任务 |
|
|
|
|
|
|
| `cmd/worker-knowledge` | 执行文档解析、URL 抓取、文本切片、批量 Embedding、Qdrant 写入、chunk 元数据维护 |
|
|
|
|
|
|
| `cmd/worker-analytics` | 执行问题驱动监控、回答解析、日级聚合、排行榜刷新、缓存刷新;采集任务默认走低优先级模型通道 |
|
|
|
|
|
|
| `cmd/worker-publish-callback` | 处理发布回调补偿、账号状态检测结果、失败重放与死信回写 |
|
|
|
|
|
|
| `apps/browser-extension` | 真实登录检测、账号绑定、图片上传、手动发布、状态检查、本地 adapter 执行 |
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.5.3 租户侧模块补齐
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 职责 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `tenant/workspace` | 工作台聚合指标、最近生成、额度摘要、模板卡片下发;卡片来源支持平台预设、租户自建与 KOL 分享导入 |
|
|
|
|
|
|
| `tenant/template` | 模板定义、模板 schema、模板版本、模板生成入口、KOL 分享模板的变量定制与落库;不向导入方暴露受保护 Prompt 正文 |
|
|
|
|
|
|
| `tenant/prompt-rule` | Prompt 规则 CRUD、启停、默认语气/字数配置、作者身份信息、分享码导出与导入;支持变量槽位定义与版权保护 |
|
|
|
|
|
|
| `tenant/schedule` | 定时生成计划 CRUD、启停、下一次执行时间维护 |
|
|
|
|
|
|
| `tenant/article` | 文章主记录、详情、预览、复制、删除、发布前读取 |
|
|
|
|
|
|
| `tenant/optimization` | 优化任务、优化方向、版本保存、未完成任务入口 |
|
|
|
|
|
|
| `tenant/brand` | 品牌、关键词、问题集、问题版本、竞品库 |
|
|
|
|
|
|
| `tenant/knowledge` | 分组、知识条目、来源类型、学习任务状态 |
|
|
|
|
|
|
| `tenant/media` | 平台清单、平台账号、插件会话、发送记录、状态检测 |
|
|
|
|
|
|
| `tenant/tracking` | 数据概览、趋势图、高频问题、引用排行、品牌关键词模型筛选 |
|
|
|
|
|
|
| `tenant/account` | 套餐、额度、重置时间、升级入口占位 |
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.5.4 平台侧模块补齐
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 职责 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `platform/tenant` | 租户开通、冻结解冻、套餐关联、额度治理 |
|
|
|
|
|
|
| `platform/plan` + `platform/quota` | 套餐档位、额度策略、补量、账期重置 |
|
|
|
|
|
|
| `platform/model` | LLM、Embedding、渠道密钥、限流、默认策略 |
|
|
|
|
|
|
| `platform/content` | 平台级模板、Prompt 规则、分类标签、敏感词规则 |
|
|
|
|
|
|
| `platform/integration` | 媒体平台清单、平台分类、adapter 注册、发布策略 |
|
|
|
|
|
|
| `platform/task` | 任务运维、批量重试、死信处理、执行历史 |
|
|
|
|
|
|
| `platform/monitoring` | 服务、队列、Worker、存储、告警 |
|
|
|
|
|
|
| `platform/audit` | 操作日志、配置变更、额度变更、风险操作 |
|
|
|
|
|
|
|
|
|
|
|
|
### 13.6 核心 API 补齐
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.6.1 租户侧 API
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/tenant/workspace/overview`
|
|
|
|
|
|
- `/api/tenant/workspace/recent-articles`
|
|
|
|
|
|
- `/api/tenant/workspace/quota-summary`
|
|
|
|
|
|
- `/api/tenant/workspace/template-cards`
|
|
|
|
|
|
- `/api/tenant/templates`
|
|
|
|
|
|
- `/api/tenant/templates/{id}`
|
|
|
|
|
|
- `/api/tenant/templates/{id}/schema`
|
|
|
|
|
|
- `/api/tenant/templates/{id}/generate`
|
|
|
|
|
|
- `/api/tenant/prompt-rules`
|
|
|
|
|
|
- `/api/tenant/prompt-rules/{id}`
|
|
|
|
|
|
- `/api/tenant/prompt-rules/{id}/share-code`
|
|
|
|
|
|
- `/api/tenant/prompt-shares/resolve/{shareCode}`
|
|
|
|
|
|
- `/api/tenant/prompt-shares/import`
|
|
|
|
|
|
- `/api/tenant/prompt-share-profiles/me`
|
|
|
|
|
|
- `/api/tenant/schedules`
|
|
|
|
|
|
- `/api/tenant/schedules/{id}`
|
|
|
|
|
|
- `/api/tenant/schedules/{id}/enable`
|
|
|
|
|
|
- `/api/tenant/schedules/{id}/disable`
|
|
|
|
|
|
- `/api/tenant/articles`
|
|
|
|
|
|
- `/api/tenant/articles/{id}`
|
|
|
|
|
|
- `/api/tenant/articles/{id}/versions`
|
|
|
|
|
|
- `/api/tenant/articles/{id}/publish-records`
|
|
|
|
|
|
- `/api/tenant/optimizations`
|
|
|
|
|
|
- `/api/tenant/optimizations/{id}`
|
|
|
|
|
|
- `/api/tenant/brands`
|
|
|
|
|
|
- `/api/tenant/brands/{id}`
|
|
|
|
|
|
- `/api/tenant/brands/{id}/keywords`
|
|
|
|
|
|
- `/api/tenant/brands/{id}/questions`
|
|
|
|
|
|
- `/api/tenant/brands/{id}/competitors`
|
|
|
|
|
|
- `/api/tenant/knowledge/groups`
|
|
|
|
|
|
- `/api/tenant/knowledge/items`
|
|
|
|
|
|
- `/api/tenant/knowledge/parse-tasks`
|
|
|
|
|
|
- `/api/tenant/media/platforms`
|
|
|
|
|
|
- `/api/tenant/media/platform-accounts`
|
|
|
|
|
|
- `/api/tenant/media/platform-accounts/{id}/check`
|
|
|
|
|
|
- `/api/tenant/media/plugin-sessions`
|
|
|
|
|
|
- `/api/tenant/media/publish-records`
|
|
|
|
|
|
- `/api/tenant/tracking/summary`
|
|
|
|
|
|
- `/api/tenant/tracking/trend`
|
|
|
|
|
|
- `/api/tenant/tracking/top-questions`
|
|
|
|
|
|
- `/api/tenant/tracking/citation-rank`
|
|
|
|
|
|
- `/api/tenant/account/plan`
|
|
|
|
|
|
- `/api/tenant/account/quota`
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.6.2 平台侧 API
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/platform/dashboard/*`
|
|
|
|
|
|
- `/api/platform/tenants/*`
|
|
|
|
|
|
- `/api/platform/plans/*`
|
|
|
|
|
|
- `/api/platform/platform-users/*`
|
|
|
|
|
|
- `/api/platform/models/*`
|
|
|
|
|
|
- `/api/platform/content/*`
|
|
|
|
|
|
- `/api/platform/integrations/*`
|
|
|
|
|
|
- `/api/platform/tasks/*`
|
|
|
|
|
|
- `/api/platform/monitoring/*`
|
|
|
|
|
|
- `/api/platform/audit/*`
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.6.3 插件回调与内部接口
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/callback/plugin/bind`
|
|
|
|
|
|
- `/api/callback/plugin/publish`
|
|
|
|
|
|
- `/api/callback/plugin/check`
|
|
|
|
|
|
- `/api/internal/task-events`
|
|
|
|
|
|
- `/api/internal/scheduler/dispatch`
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.6.4 统一错误响应与错误码
|
|
|
|
|
|
|
|
|
|
|
|
所有 API 建议统一返回:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"code": 40301,
|
|
|
|
|
|
"message": "quota_insufficient",
|
|
|
|
|
|
"detail": "生成额度不足,请升级套餐或等待额度重置",
|
|
|
|
|
|
"request_id": "req_xxx"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
错误码段建议如下:
|
|
|
|
|
|
|
|
|
|
|
|
| 错误码段 | 含义 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `400xx` | 参数校验与请求格式错误 |
|
|
|
|
|
|
| `401xx` | 认证失败、Token 失效 |
|
|
|
|
|
|
| `403xx` | 权限不足、额度不足、功能未开通 |
|
|
|
|
|
|
| `404xx` | 资源不存在 |
|
|
|
|
|
|
| `409xx` | 状态冲突、幂等冲突、重复提交 |
|
|
|
|
|
|
| `429xx` | 频率限制、队列拥塞 |
|
|
|
|
|
|
| `500xx` | 内部错误 |
|
|
|
|
|
|
| `503xx` | 下游依赖不可用,如 `LLM / Embedding / Qdrant / ObjectStorage` |
|
|
|
|
|
|
|
|
|
|
|
|
`gateway` 与各 API 服务必须共用同一套错误码枚举和响应封装,避免前后端联调时出现多种格式。
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.6.5 KOL 分享码解析边界
|
|
|
|
|
|
|
|
|
|
|
|
- `/api/tenant/prompt-shares/resolve/{shareCode}` 只返回模板卡片信息、变量槽位、使用说明、作者展示信息,不返回底层 Prompt 正文
|
|
|
|
|
|
- `/api/tenant/prompt-shares/import` 在服务端完成模板物化,前端只提交变量定制结果,不接触受保护 Prompt 资产
|
|
|
|
|
|
- `/api/tenant/templates/{id}` 对 `origin_type=kol_share` 的模板仅返回可定制字段与运行配置,不返回 `prompt_template`
|
|
|
|
|
|
- 真正参与生成的受保护 Prompt 仅由 `tenant-api` / `worker-generate` 在服务端读取,前端与浏览器插件都不可见
|
|
|
|
|
|
|
|
|
|
|
|
### 13.7 异步任务、调度与幂等设计
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.7.1 队列与任务类型
|
|
|
|
|
|
|
|
|
|
|
|
| 队列 | 任务类型 | 说明 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `q.generate.interactive` | `article.generate.template` `article.generate.prompt` `article.optimize` | 交互式任务,高优先级,服务工作台、模板创作、自定义生成即时任务与文章优化 |
|
|
|
|
|
|
| `q.generate.batch` | `article.generate.batch_item` `article.generate.schedule_item` | 批量与定时任务,低优先级,避免堵塞交互任务 |
|
|
|
|
|
|
| `q.knowledge` | `knowledge.parse.file` `knowledge.parse.url` `knowledge.parse.text` | 不同来源共用解析入口,按来源类型走不同解析器 |
|
|
|
|
|
|
| `q.analytics.collect` | `analytics.collect.question` | 采集任务,低于用户直触发生成任务优先级,默认使用独立模型通道或更小并发池 |
|
|
|
|
|
|
| `q.analytics.aggregate` | `analytics.aggregate.daily` `analytics.refresh.cache` | 聚合与缓存刷新任务,不占用 LLM 通道 |
|
|
|
|
|
|
| `q.publish-callback` | `publish.persist` `platform-account.check.persist` | 插件执行结果、账号检测结果入队补偿 |
|
|
|
|
|
|
| `q.dead-letter` | `dead_letter.*` | 统一兜底失败任务 |
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.7.2 调度器设计
|
|
|
|
|
|
|
|
|
|
|
|
- `scheduler` 每分钟扫描一次 `schedule_tasks`,条件为 `status=enabled and next_run_at <= now()`
|
|
|
|
|
|
- 使用数据库行级锁或租约字段 `dispatch_lease_until + lease_owner` 防止多实例重复派发
|
|
|
|
|
|
- 每次派发生成一个 `task_batch_id`,并为批量任务拆分出多个 `generation_tasks`
|
|
|
|
|
|
- 数据追踪监控计划同样由 `scheduler` 生成 `analytics.collect.question` 任务
|
|
|
|
|
|
- 计划任务创建时默认写入 `dispatch_jitter_minutes`,将大批同时到期任务平滑散布到 `5~10 分钟` 窗口内
|
|
|
|
|
|
- `scheduler` 重启后按 `task_batch_id + request_hash` 幂等追回漏派发任务,避免重复投递
|
|
|
|
|
|
- V1 不依赖 RabbitMQ Delay Queue,统一采用“数据库到期扫描 + 普通消息队列”方式,降低实现复杂度
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.7.3 事务、幂等与补偿
|
|
|
|
|
|
|
|
|
|
|
|
- 任务提交路径必须在单个 PostgreSQL 事务内完成“额度预扣 / 保留 + 任务创建 + 任务记录写入”
|
|
|
|
|
|
- Worker 成功路径必须在单个 PostgreSQL 事务内完成“结果写入 + 主记录状态更新 + 额度确认”
|
|
|
|
|
|
- Worker 失败路径必须在单个 PostgreSQL 事务内完成“失败状态更新 + 额度退还 / 释放”
|
|
|
|
|
|
- 批量生成采用“提交时按批次预扣 + 单条失败退款 + 定期对账”模式,批次维度以 `task_batch_id` 管理
|
|
|
|
|
|
- 生成任务按 `tenant_id + source_type + request_hash + schedule_slot` 做幂等
|
|
|
|
|
|
- 插件回调按 `plugin_session_id + callback_stage` 做幂等
|
|
|
|
|
|
- `publish_records` 保留请求与响应摘要,支持补偿重放
|
|
|
|
|
|
- Worker 默认重试 3 次,超过阈值进入死信;平台端允许人工批量重试
|
|
|
|
|
|
|
|
|
|
|
|
### 13.8 浏览器插件执行面闭环
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.8.1 插件会话模型
|
|
|
|
|
|
|
|
|
|
|
|
为避免“页面一关结果丢失”,V1 引入 `plugin_sessions`:
|
|
|
|
|
|
|
|
|
|
|
|
1. 前端先调用 `/api/tenant/media/plugin-sessions` 创建一次性会话
|
|
|
|
|
|
2. 后端返回 `plugin_session_id + session_token + expire_at`
|
|
|
|
|
|
3. 前端将会话信息交给 `browser-extension`
|
|
|
|
|
|
4. 插件执行绑定、检测或发布动作
|
|
|
|
|
|
5. 插件将结果:
|
|
|
|
|
|
- 回传给前端用于即时交互
|
|
|
|
|
|
- 同时回调 `/api/callback/plugin/*` 用于可靠落库
|
|
|
|
|
|
6. `tenant-api` 校验 `session_token` 后写入 `platform_accounts` 或 `publish_records`
|
|
|
|
|
|
7. 系统通过 SSE 广播结果,列表页和详情页实时刷新
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.8.2 绑定/发布状态流转
|
|
|
|
|
|
|
|
|
|
|
|
- 平台账号状态:`pending -> active -> invalid/expired`
|
|
|
|
|
|
- 发布状态:`unpublished -> publishing -> success/failed/pending_review`
|
|
|
|
|
|
- 回调接口不直接信任浏览器 Cookie,只信任后端签发的短期 `session_token`
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.8.3 安全约束
|
|
|
|
|
|
|
|
|
|
|
|
- 服务端不保存第三方平台 Cookie 与登录态
|
|
|
|
|
|
- 插件仅允许注入受信后台域名
|
|
|
|
|
|
- 所有 `postMessage` / `runtime.sendMessage` 必须校验来源域名与会话 token
|
|
|
|
|
|
- 所有绑定、重检、发布、失败补偿动作写入审计日志
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.8.4 插件检测与降级
|
|
|
|
|
|
|
|
|
|
|
|
- `packages/shared-types` 维护 `MIN_BROWSER_EXTENSION_VERSION` 常量,作为前后端与插件共享的最低兼容版本
|
|
|
|
|
|
- 媒体页加载时,`admin-web` 先通过 `plugin.ping` / `postMessage` 握手检测插件是否安装、版本是否满足要求、能力清单是否齐备
|
|
|
|
|
|
- 未安装、被禁用或版本过低时,页面将“去绑定 / 重新检测 / 发布”按钮置灰,并展示安装或升级引导
|
|
|
|
|
|
- 插件回调会把 `client_version` 回传到 `plugin_sessions` 审计字段,便于排查兼容问题
|
|
|
|
|
|
- 降级场景下不走伪成功逻辑,统一保持前端只读提示,避免产生无法落库的假状态
|
|
|
|
|
|
|
|
|
|
|
|
### 13.9 数据追踪闭环
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.9.1 采集模型
|
|
|
|
|
|
|
|
|
|
|
|
数据追踪采用 `问题驱动监控`,最小采集单元为:
|
|
|
|
|
|
|
|
|
|
|
|
`1 question_version x 1 model x 1 run_time = 1 条原始监控记录`
|
|
|
|
|
|
|
|
|
|
|
|
含义如下:
|
|
|
|
|
|
|
|
|
|
|
|
- `品牌` 是租户下的监控主体
|
|
|
|
|
|
- `关键词` 是问题集合容器与聚合维度
|
|
|
|
|
|
- `问题版本` 保证历史口径稳定
|
|
|
|
|
|
- `模型` 是对比维度
|
|
|
|
|
|
- 页面只查日级聚合表,不直接扫描原始回答
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.9.2 数据链路
|
|
|
|
|
|
|
|
|
|
|
|
1. 用户在品牌词库维护 `brand_keywords` 与 `brand_questions`
|
|
|
|
|
|
2. `scheduler` 按每日频率为启用的问题版本和目标模型派发监控任务
|
|
|
|
|
|
3. `worker-analytics` 调用模型得到原始回答,原文写入对象存储
|
|
|
|
|
|
4. 解析回答是否提及品牌、是否首位提及、是否首选推荐、是否正向提及、是否引用文章
|
|
|
|
|
|
5. 结果写入 `question_monitor_runs` 与 `question_monitor_parse_results`
|
|
|
|
|
|
6. 日级聚合刷新 `question_model_daily_metrics`、`keyword_model_daily_metrics`、`keyword_model_top_questions_daily`、`keyword_model_citation_rank_daily`
|
|
|
|
|
|
7. Redis 缓存 30 天摘要、趋势图、高频问题、引用排行
|
|
|
|
|
|
8. `/api/tenant/tracking/*` 统一从聚合表和缓存读取
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.9.3 V1 控制策略
|
|
|
|
|
|
|
|
|
|
|
|
- 每个问题每天默认执行 `1 次`
|
|
|
|
|
|
- 重要品牌或更高套餐可配置为 `2 次`
|
|
|
|
|
|
- 同品牌、同模型、同日、相同 `question_hash` 可做采集去重
|
|
|
|
|
|
- 原始回答落对象存储,PostgreSQL 仅保存结构化解析与聚合结果
|
|
|
|
|
|
- 原始运行记录保留 `30 ~ 90 天`,解析结果保留 `90 天`,日级汇总保留 `180 天+`
|
|
|
|
|
|
- `brand_question_versions` 仅在“启用 / 发布新监控口径”时生成新版本;编辑态默认做 `10 分钟` debounce,避免碎片化
|
|
|
|
|
|
|
|
|
|
|
|
### 13.10 SSE 与轮询策略
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.10.1 SSE 适用场景
|
|
|
|
|
|
|
|
|
|
|
|
以下场景在“存在运行中任务”期间可临时升级为 SSE:
|
|
|
|
|
|
|
|
|
|
|
|
- 文章生成进度
|
|
|
|
|
|
- 文章优化进度
|
|
|
|
|
|
- 知识学习状态
|
|
|
|
|
|
- 平台账号检测状态
|
|
|
|
|
|
- 发布状态变更
|
|
|
|
|
|
- 配额刷新提醒
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.10.2 事件类型
|
|
|
|
|
|
|
|
|
|
|
|
- `task.updated`
|
|
|
|
|
|
- `article.generated`
|
|
|
|
|
|
- `article.optimized`
|
|
|
|
|
|
- `knowledge.updated`
|
|
|
|
|
|
- `platform_account.updated`
|
|
|
|
|
|
- `publish.updated`
|
|
|
|
|
|
- `quota.updated`
|
|
|
|
|
|
|
|
|
|
|
|
统一负载字段建议:
|
|
|
|
|
|
|
|
|
|
|
|
- `event_id`
|
|
|
|
|
|
- `tenant_id`
|
|
|
|
|
|
- `event_type`
|
|
|
|
|
|
- `resource_type`
|
|
|
|
|
|
- `resource_id`
|
|
|
|
|
|
- `task_id`
|
|
|
|
|
|
- `status`
|
|
|
|
|
|
- `message`
|
|
|
|
|
|
- `occurred_at`
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.10.3 连接策略
|
|
|
|
|
|
|
|
|
|
|
|
- 工作台、列表页、数据页默认使用 `10s` 轮询
|
|
|
|
|
|
- 仅当页面存在 `queued/running/publishing/checking` 状态的资源时,前端才建立 SSE 连接
|
|
|
|
|
|
- 单用户单租户默认只保留 `1` 条 SSE 连接;页面空闲 `60s` 且无运行中任务时主动关闭
|
|
|
|
|
|
- `tenant-api` 通过 Redis Pub/Sub 做跨 Pod 事件广播,不依赖 Sticky Session;任一 Pod 写事件后,所有订阅 Pod 都能向本地连接转发
|
|
|
|
|
|
- SSE heartbeat 调整为 `30s`
|
|
|
|
|
|
- 客户端断线后按 `3s / 5s / 10s` 退避重连
|
|
|
|
|
|
- 若浏览器或网络环境不支持 SSE,则保持 `10s` 轮询
|
|
|
|
|
|
- 页面不直接监听 RabbitMQ,统一由 `tenant-api` 聚合并对前端推送
|
|
|
|
|
|
|
|
|
|
|
|
### 13.11 核心数据模型与最小 Schema
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.1 身份、租户与额度
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `tenants` | `id` `name` `status` `created_at` `frozen_at` | `uk_tenant_name` |
|
|
|
|
|
|
| `users` | `id` `email` `phone` `status` `created_at` | `uk_users_email` |
|
|
|
|
|
|
| `tenant_memberships` | `id` `tenant_id` `user_id` `tenant_role` | `uk_tenant_user` |
|
|
|
|
|
|
| `platform_user_roles` | `id` `user_id` `platform_role` | `uk_platform_user_role` |
|
|
|
|
|
|
| `plans` | `id` `plan_code` `name` `quota_policy_json` `status` | `uk_plan_code` |
|
|
|
|
|
|
| `tenant_plan_subscriptions` | `id` `tenant_id` `plan_id` `start_at` `end_at` `status` | `idx_tenant_plan_active` |
|
|
|
|
|
|
| `tenant_quota_ledgers` | `id` `tenant_id` `quota_type` `delta` `balance_after` `reason` | `idx_tenant_quota_tenant_type_created` |
|
|
|
|
|
|
| `quota_reservations` | `id` `tenant_id` `quota_type` `resource_type` `resource_id` `reserved_amount` `consumed_amount` `refunded_amount` `status` `expire_at` | `idx_quota_reservation_tenant_status` |
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.2 模板、Prompt、文章与优化
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `article_templates` | `id` `scope` `tenant_id` `origin_type` `share_code_id` `template_key` `template_name` `schema_json` `prompt_template` `prompt_visibility` `protected_prompt_asset_key` `card_config_json` `status` `version_no` | `uk_template_scope_key_version` |
|
|
|
|
|
|
| `prompt_rules` | `id` `tenant_id` `name` `prompt_content` `scene` `default_tone` `default_word_count` `status` | `idx_prompt_rule_tenant_status` |
|
|
|
|
|
|
| `prompt_share_profiles` | `id` `user_id` `display_name` `bio` `avatar_url` `share_enabled` `status` | `uk_prompt_share_profile_user` |
|
|
|
|
|
|
| `prompt_share_codes` | `id` `tenant_id` `source_template_id` `owner_user_id` `share_code` `snapshot_json` `protected_prompt_asset_key` `status` `expire_at` | `uk_prompt_share_code` |
|
|
|
|
|
|
| `schedule_tasks` | `id` `tenant_id` `prompt_rule_id` `target_platform_id` `cron_expr` `next_run_at` `dispatch_jitter_minutes` `lease_owner` `dispatch_lease_until` `last_dispatch_at` `status` | `idx_schedule_due` |
|
|
|
|
|
|
| `articles` | `id` `tenant_id` `source_type` `template_id` `prompt_rule_id` `current_version_id` `generate_status` `publish_status` | `idx_article_tenant_created` |
|
|
|
|
|
|
| `article_versions` | `id` `article_id` `version_no` `title` `html_content` `markdown_content` `word_count` `source_label` | `uk_article_version_no` |
|
|
|
|
|
|
| `generation_tasks` | `id` `tenant_id` `article_id` `task_batch_id` `quota_reservation_id` `task_type` `request_hash` `status` `error_message` | `idx_generation_task_status_created` |
|
|
|
|
|
|
| `optimization_tasks` | `id` `tenant_id` `article_id` `source_version_id` `target_version_id` `optimization_type` `status` | `idx_optimization_task_status` |
|
|
|
|
|
|
|
|
|
|
|
|
其中:`article_templates.scope=platform` 时 `tenant_id` 为空;`scope=tenant` 时 `tenant_id` 必填。
|
|
|
|
|
|
|
|
|
|
|
|
导入 KOL 分享码后,系统会把快照物化为当前租户自己的 `article_templates` 记录,并标记 `origin_type=kol_share`。
|
|
|
|
|
|
|
|
|
|
|
|
`article_templates.prompt_visibility=sealed` 时,模板的 Prompt 正文只允许服务端读取,前端接口不得返回。
|
|
|
|
|
|
|
|
|
|
|
|
`prompt_share_codes.snapshot_json` 只保存模板卡片信息、变量占位和使用说明;真正的 Prompt 正文通过 `protected_prompt_asset_key` 以受保护资产方式保存,不复制导出方租户的品牌、地址、媒体账号等私有数据。
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.3 品牌与问题集
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `brands` | `id` `tenant_id` `name` `description` `status` | `uk_brand_tenant_name` |
|
|
|
|
|
|
| `brand_keywords` | `id` `tenant_id` `brand_id` `name` `status` | `uk_brand_keyword_name` |
|
|
|
|
|
|
| `brand_questions` | `id` `tenant_id` `brand_id` `keyword_id` `current_version_id` `status` | `idx_brand_questions_keyword` |
|
|
|
|
|
|
| `brand_question_versions` | `id` `question_id` `question_text` `question_hash` `version_no` `is_active` | `uk_question_version_no` `idx_question_hash` |
|
|
|
|
|
|
| `competitors` | `id` `tenant_id` `brand_id` `name` `website` `description` `product_lines_json` | `idx_competitor_brand` |
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.4 知识库
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `knowledge_groups` | `id` `tenant_id` `name` `parent_id` `sort_order` | `uk_knowledge_group_name` |
|
|
|
|
|
|
| `knowledge_items` | `id` `tenant_id` `group_id` `source_type` `name` `storage_key` `status` `size_bytes` | `idx_knowledge_item_group_status` |
|
|
|
|
|
|
| `knowledge_parse_tasks` | `id` `tenant_id` `knowledge_item_id` `source_type` `status` `error_message` | `idx_parse_task_status` |
|
|
|
|
|
|
| `knowledge_chunks_meta` | `id` `tenant_id` `knowledge_item_id` `chunk_index` `token_count` `qdrant_point_id` `item_version` `status` | `idx_chunk_item_version` |
|
|
|
|
|
|
|
|
|
|
|
|
V1 的 `retrieval_logs` 与 `rag_eval_cases` 先不落数据库表,统一写文件日志或对象存储采样归档,待评测体系成熟后再升级。
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.5 媒体平台与插件执行
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `media_platforms` | `id` `platform_code` `name` `category` `adapter_key` `status` | `uk_media_platform_code` |
|
|
|
|
|
|
| `platform_accounts` | `id` `tenant_id` `user_id` `platform_id` `platform_uid` `nickname` `avatar_url` `status` `last_check_at` | `uk_platform_account_identity` |
|
|
|
|
|
|
| `plugin_sessions` | `id` `tenant_id` `user_id` `action_type` `platform_id` `session_token` `client_version` `expire_at` `status` | `uk_plugin_session_token` `idx_plugin_session_expire` |
|
|
|
|
|
|
| `publish_records` | `id` `tenant_id` `article_id` `platform_account_id` `platform_id` `status` `external_article_id` `error_message` `request_payload_json` `response_payload_json` | `idx_publish_record_article_created` |
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.6 数据追踪
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `question_monitor_runs` | `id` `tenant_id` `brand_id` `keyword_id` `question_id` `question_version_id` `model_id` `run_date` `run_at` `task_batch_id` `status` `raw_answer_storage_key` | `idx_monitor_runs_query` |
|
|
|
|
|
|
| `question_monitor_parse_results` | `id` `run_id` `mentioned_brand` `top1_mentioned` `first_recommended` `positive_mentioned` `citation_article_count` `citation_platform_count` `parser_version` | `uk_parse_result_run` |
|
|
|
|
|
|
| `question_model_daily_metrics` | `tenant_id` `brand_id` `keyword_id` `question_id` `question_version_id` `model_id` `date` `ask_count` `mention_count` `top1_mention_count` `first_recommend_count` `positive_mention_count` `citation_count` | `uk_question_model_daily` |
|
|
|
|
|
|
| `keyword_model_daily_metrics` | `tenant_id` `brand_id` `keyword_id` `model_id` `date` `ask_count` `mention_rate` `positive_mention_rate` | `uk_keyword_model_daily` |
|
|
|
|
|
|
| `keyword_model_top_questions_daily` | `tenant_id` `brand_id` `keyword_id` `model_id` `date` `question_id` `score` | `idx_top_questions_daily` |
|
|
|
|
|
|
| `keyword_model_citation_rank_daily` | `tenant_id` `brand_id` `keyword_id` `model_id` `date` `cited_article_id` `citation_count` | `idx_citation_rank_daily` |
|
|
|
|
|
|
|
|
|
|
|
|
保留策略建议与专项监控方案对齐:原始运行记录 `30 ~ 90 天`、解析结果 `90 天`、日级汇总 `180 天或更久`。
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.11.7 平台任务与审计
|
|
|
|
|
|
|
|
|
|
|
|
| 表 | 关键字段 | 关键约束/索引 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `task_records` | `id` `tenant_id` `task_type` `resource_type` `resource_id` `status` `retry_count` `task_batch_id` | `idx_task_record_status_type` |
|
|
|
|
|
|
| `audit_logs` | `id` `operator_id` `tenant_id` `module` `action` `before_json` `after_json` `result` `created_at` | `idx_audit_module_created` |
|
|
|
|
|
|
| `config_change_logs` | `id` `operator_id` `scope_type` `scope_id` `change_type` `diff_json` | `idx_config_change_scope` |
|
|
|
|
|
|
| `quota_change_logs` | `id` `operator_id` `tenant_id` `quota_type` `delta` `reason` | `idx_quota_change_tenant` |
|
|
|
|
|
|
| `risk_action_logs` | `id` `operator_id` `tenant_id` `risk_type` `reason` `result` | `idx_risk_action_tenant_created` |
|
|
|
|
|
|
|
|
|
|
|
|
### 13.12 闭环验收标准
|
|
|
|
|
|
|
|
|
|
|
|
以下标准满足时,可认为主技术架构已从“宏观方案”补齐为“可开发闭环方案”:
|
|
|
|
|
|
|
|
|
|
|
|
- `工作台` 有独立聚合 API,不依赖前端拼装多个分散接口
|
|
|
|
|
|
- `模板创作` 有模板定义、schema、批量生成和任务状态落点
|
|
|
|
|
|
- `自定义生成` 有 Prompt 规则、定时任务、Scheduler 和幂等派发设计
|
|
|
|
|
|
- `文章优化` 有优化任务、版本表、保存结果与回看路径
|
|
|
|
|
|
- `媒体管理` 有插件执行端、插件会话、绑定回调、发布回调和状态同步
|
|
|
|
|
|
- `品牌词库` 有关键词、问题、问题版本、竞品库与追踪关联
|
|
|
|
|
|
- `知识库` 有分组、多来源解析策略、学习任务和对象存储落点
|
|
|
|
|
|
- `数据追踪` 有明确采集单元、聚合表、缓存策略和查询口径
|
|
|
|
|
|
- 所有长任务都有 `task_records`、SSE 事件和轮询兜底
|
|
|
|
|
|
- 所有高风险操作、配置变更、额度变更、发布失败补偿都有审计记录
|
|
|
|
|
|
|
|
|
|
|
|
### 13.13 面向 5 万并发与简单运维的运行策略
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.1 Gateway 水平扩展与负载均衡
|
|
|
|
|
|
|
|
|
|
|
|
- `gateway` 必须保持无状态,允许多实例水平扩展
|
|
|
|
|
|
- 线上入口通过 `Ingress / Nginx` 做 L7 负载均衡,前端无需感知后端实例
|
|
|
|
|
|
- Kubernetes 建议为 `gateway` 配置 HPA,核心观测指标为:`CPU`、`RPS`、`active_connections`
|
|
|
|
|
|
- `gateway` 到 `tenant-api` / `platform-api` 之间通过集群内部 Service 直连,V1 不引入额外服务网格
|
|
|
|
|
|
- `gateway` 只允许承担统一入口职责,不允许沉淀业务编排、任务控制、数据聚合与数据库业务写入
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.2 Scheduler 故障恢复策略
|
|
|
|
|
|
|
|
|
|
|
|
- V1 默认采用 `单活 scheduler + 健康检查 + 自动重启`
|
|
|
|
|
|
- `scheduler` 重启后必须重新扫描 `next_run_at <= now()` 的计划任务,并按幂等键自动追回漏派发任务
|
|
|
|
|
|
- 若计划任务已超出允许追赶窗口,则记录为 `skipped/expired` 并写入审计日志
|
|
|
|
|
|
- 派发状态需保留 `lease_owner`、`dispatch_lease_until`、`last_dispatch_at`,便于故障排查和追赶
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.3 PostgreSQL 分区、索引与归档
|
|
|
|
|
|
|
|
|
|
|
|
- `audit_logs`、`config_change_logs`、`quota_change_logs`、`risk_action_logs` 按月分区
|
|
|
|
|
|
- `question_monitor_runs`、`question_monitor_parse_results`、`question_model_*`、`keyword_model_*` 按日期分区
|
|
|
|
|
|
- `articles` 至少提供 `(tenant_id, created_at desc)`、`(tenant_id, generate_status, publish_status, created_at desc)` 复合索引
|
|
|
|
|
|
- 原始回答正文保留在对象存储 `30~90 天`,解析结果保留 `90 天`,聚合表保留 `180 天+`
|
|
|
|
|
|
- V1 先使用单 PostgreSQL 主实例;若读压升高,优先增加只读副本而不是立即拆库
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.4 限流、队列保护与熔断
|
|
|
|
|
|
|
|
|
|
|
|
- `gateway` 层增加基于 Redis 的租户级令牌桶限流,维度为 `tenant_id + route_group`
|
|
|
|
|
|
- `tenant-api` 在任务提交前校验:套餐额度、租户当日提交量、当前排队深度、模型通道状态
|
|
|
|
|
|
- `worker-generate` 对下游 LLM 调用统一使用 `context.WithTimeout(30s)`,并以 `semaphore` 控制单 consumer 组最大并发,V1 默认建议 `50`
|
|
|
|
|
|
- 交互式生成、批量生成、监控采集使用独立令牌桶;`worker-analytics` 默认只占用小比例低优先级通道,不能反压用户实时生成
|
|
|
|
|
|
- `worker-generate` 与 `worker-analytics` 的上游调用按 `3s / 10s / 30s` 做有限退避重试;熔断打开后只允许少量探测请求恢复
|
|
|
|
|
|
- `worker-knowledge` 的 Embedding 请求按 chunk 批量提交,建议单次 `16 ~ 32` 个 chunk,失败时自动拆批重试
|
|
|
|
|
|
- RabbitMQ 为生成队列配置最大长度和溢出策略,超过阈值时拒绝低优先级批量任务
|
|
|
|
|
|
- 平台端的强制重试、强制补量、限流豁免必须写审计日志
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.5 Redis 缓存与对象存储分发策略
|
|
|
|
|
|
|
|
|
|
|
|
- 工作台聚合、趋势图、高频问题、引用排行等热点查询使用 `TTL + 抖动 + 异步刷新`
|
|
|
|
|
|
- 对不存在的数据维度使用空值缓存,避免缓存穿透
|
|
|
|
|
|
- 高热点品牌数据在凌晨批量预热,避免白天冷启动击穿数据库
|
|
|
|
|
|
- 公有云部署推荐 `OSS + CDN`;私有化部署推荐 `MinIO + Nginx / CDN`
|
|
|
|
|
|
- 图片、封面、知识库原文件通过带签名的对象存储 URL 输出,走 CDN 分发
|
|
|
|
|
|
- 已删除知识文档的对象文件按 `T+7` 清理,原始模型回答按监控策略保留 `30 ~ 90 天`
|
|
|
|
|
|
- 发布请求/响应原始 payload 建议按审计需求保留 `30 ~ 90 天`,并由 GC 任务定期扫描孤儿文件
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.6 配置管理与动态加载
|
|
|
|
|
|
|
|
|
|
|
|
- V1 配置层级采用:`base YAML -> 环境变量覆盖 -> 动态配置覆盖`
|
|
|
|
|
|
- 动态配置仅用于可热更新项:限流阈值、功能开关、模型通道权重、adapter 开关、轮询/SSE 策略
|
|
|
|
|
|
- 结构性配置如数据库 DSN、MQ 地址、端口等仍通过重启生效,避免隐藏复杂度
|
|
|
|
|
|
- 所有动态配置变更进入 `config_change_logs`
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.7 Sponge 使用原则
|
|
|
|
|
|
|
|
|
|
|
|
- `sponge` 仅作为脚手架初始化工具使用,不采用其默认的业务 `handler/service/dao` 全量代码生成
|
|
|
|
|
|
- 如需复用少量样板代码,生成代码也必须按本文分层映射:`handler -> transport`、`service/logic -> app`、`dao -> repository`、`domain` 由业务手工维护
|
|
|
|
|
|
- `tenant` 与 `platform` 的双域拆分优先于代码生成习惯,架构设计始终先于框架约束
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.8 Migration 与 Schema 变更策略
|
|
|
|
|
|
|
|
|
|
|
|
- V1 推荐统一使用 `golang-migrate` 管理 Schema 版本,目录固定为 `server/migrations/`
|
|
|
|
|
|
- 命名规则建议:`YYYYMMDDHHMMSS_description.up.sql` 与对应 `down.sql`
|
|
|
|
|
|
- 线上 DDL 采用 expand / migrate / contract 三阶段,避免单次发布中直接删列、改类型或重建大索引
|
|
|
|
|
|
- 分区表、索引和长耗时 DDL 必须走预发演练;高风险变更在低峰窗口执行并保留回滚脚本
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.9 租户隔离与关键事务边界
|
|
|
|
|
|
|
|
|
|
|
|
- Repository 层必须提供 `TenantScope(ctx)` 或等价封装,租户侧查询默认自动注入 `tenant_id`
|
|
|
|
|
|
- 平台侧跨租户查询只允许出现在 `platform/*` 域;禁止在租户域直接手写绕过租户条件的 SQL
|
|
|
|
|
|
- CI 应增加静态检查或代码评审规则,重点扫描缺少 `tenant_id` 过滤的查询
|
|
|
|
|
|
- 关键事务边界至少包括:任务提交预扣额度、Worker 成功确认额度、Worker 失败退还额度、插件回调幂等落库
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.10 错误码、日志与链路追踪
|
|
|
|
|
|
|
|
|
|
|
|
- 所有进程统一使用结构化 JSON 日志,建议使用 `zap`
|
|
|
|
|
|
- `gateway` 为入口请求生成 `request_id`;若上游已带可信 `request_id` 则复用,并同时补充内部 `trace_id`
|
|
|
|
|
|
- API -> MQ -> Worker 全链路透传 `request_id`、`trace_id`、`tenant_id`、`task_batch_id`
|
|
|
|
|
|
- RabbitMQ 消息头必须包含上述追踪字段,Worker 落日志时原样打印
|
|
|
|
|
|
- V1 最低要求是“统一错误码 + 结构化日志 + `request_id` 贯通”;V1.5 再引入 OpenTelemetry / Jaeger
|
|
|
|
|
|
- 所有告警规则统一绑定 `service`、`queue`、`tenant_scope`、`error_code` 标签,便于聚合排查
|
|
|
|
|
|
|
|
|
|
|
|
#### 13.13.11 本地开发、归档与运维模板
|
|
|
|
|
|
|
|
|
|
|
|
- 本地开发默认模式为“中间件容器化,Go 服务本地运行”,避免 `docker compose up` 同时拉起全部业务进程
|
|
|
|
|
|
- 提供统一的 `make dev-init`、`make dev-api`、`make dev-workers` 或等价任务入口,降低新人启动门槛
|
|
|
|
|
|
- 4 类 Worker 保持独立二进制,但共享同一套容器基座、健康检查协议、日志格式和 Helm 模板
|
|
|
|
|
|
- 审计表与监控表分区需配套归档脚本或定时作业,按月导出历史分区并清理超期数据
|
|
|
|
|
|
- 对象存储 GC、分区归档、死信队列巡检建议统一纳入 `scheduler` 的低频运维作业或独立运维 CronJob
|
|
|
|
|
|
|
|
|
|
|
|
## 14. 最终建议
|
|
|
|
|
|
|
|
|
|
|
|
如果当前目标是尽快落地并保持后续可扩展,最推荐的方案是:
|
|
|
|
|
|
|
|
|
|
|
|
- 前端采用双应用:`apps/admin-web` 与 `apps/ops-admin-web`
|
|
|
|
|
|
- V1 同步建设执行端:`apps/browser-extension`
|
|
|
|
|
|
- 共享能力全部沉淀到 `packages/*`
|
|
|
|
|
|
- 后端采用 `gateway + tenant-api + platform-api + scheduler + 多 Worker` 结构
|
|
|
|
|
|
- 统一使用 `PostgreSQL + Redis + RabbitMQ + Qdrant + 对象存储`
|
|
|
|
|
|
- 权限严格按 `platform_role` 与 `tenant_role` 分层
|
|
|
|
|
|
- 高风险操作统一纳入审计
|
|
|
|
|
|
|
|
|
|
|
|
这个方案的优点是:
|
|
|
|
|
|
|
|
|
|
|
|
- 前端边界清晰
|
|
|
|
|
|
- 后端复杂度可控
|
|
|
|
|
|
- 权限模型不混乱
|
|
|
|
|
|
- 既适合 V1,也方便未来演进到更细的服务拆分
|