Files
edu-industry/admin-tools/demo/PRODUCTION_ARCHITECTURE.md
lofyerandfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> b9fbd4c6af refactor: simplify product copy
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-08-25 11:37:59 +08:00

278 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 产教招聘数据中台生产架构建议
## 1. 目标架构
```text
商业招聘平台 / 公共就业平台 / 校内系统
│
▼
Connector Runtime 集群
┌──────────────┬──────────────┬──────────────┐
│ BOSS Adapter │ 智联 Adapter │ 公共源 Adapter│
└──────────────┴──────────────┴──────────────┘
│
任务、分片、租约、心跳、重试、限速
▼
原始数据层
页面 / JSON / 文件 / 元数据 / SHA-256
│
▼
解析、清洗与标准化流水线
去重 → 企业归一 → 岗位归一 → 技能抽取
│
▼
Schema Registry + Quality Engine
│
▼
版本化标准层与数据产品交付层
Manifest / Schema / Quality / Lineage / Hash
```
## 2. 推荐服务边界
| 服务 | 核心职责 | 推荐存储 |
|---|---|---|
| Source Registry | 数据源、连接器、责任人、目标契约、运行策略 | PostgreSQL |
| Scheduler | 调度计划、任务、分片、租约、心跳、暂停和恢复 | PostgreSQL + Redis |
| Connector Runtime | 源端访问、原始响应生成、增量水位 | Kubernetes Jobs/Workers |
| Raw Store | 原始页面、响应、文件、请求元数据和哈希 | S3/OSS 兼容对象存储 |
| Parser Service | 按来源解析原始快照,输出来源 Schema | 流式计算或批处理 |
| Normalization Service | 企业、岗位、技能、地区和薪资统一 | PostgreSQL + 检索引擎 |
| Schema Registry | JSON Schema、兼容性、版本和发布 | PostgreSQL + Git |
| Quality Engine | 结构、完整性、唯一性、时效和业务规则 | 分布式 SQL/计算引擎 |
| Data Product Service | 标准层版本、Manifest、租户范围和发布回滚 | Lakehouse + PostgreSQL |
| Data Query Service | 标准、源端、原始快照和隔离记录的分页检索、字段权限与证据追溯 | Lakehouse/OLAP + 检索引擎 |
| Audit Service | 统一 trace_id、事件签名、证据和留存 | WORM/Object Lock |
| Operations Service | 告警、问题、工单、SLA、指派、处置时间线和通知待办 | PostgreSQL + 事件总线 |
| Release Approval Service | 候选版本、发布质量检查、职责分离审批、稳定别名发布与回滚 | PostgreSQL + 策略引擎 |
| Tenant Delivery Service | 逐租户发送状态、幂等重试、回执验签、记录数/SHA校验和单租户回滚 | PostgreSQL + 消息队列 |
## 3. 连接器 SPI
每个商业或公共平台实现同一接口:
```text
describe() 返回来源、能力、代码版本和目标 Schema
plan(scope, watermark) 根据地域、岗位族和水位生成分片
probe(shard) 小样本连接和结构预检
collect(shard, lease) 执行一个具备租约的采集分片
checkpoint(result) 提交幂等水位和运行摘要
snapshot(response) 生成原始对象、元数据和 SHA-256
parse(snapshot) 解析为来源 Schema
health() 返回入口可达性、延迟和错误分类
```
参考实现位于 [`../crawler/`](../crawler/),逐来源接入方式和启用条件见 [`../../docs/crawler-source-implementation.md`](../../docs/crawler-source-implementation.md)。连接器运行时必须遵守以下要求:
- 所有外部来源默认禁用,只有来源审批状态为 `approved` 才允许公网运行;
- 商业平台仅接入官方合作 API 或授权数据包,不实现登录自动化、验证码处理、私有接口逆向和反自动化规避;
- 公开页面任务同时执行书面授权、robots.txt、域名 allowlist、公共地址解析和来源级限速检查;
- 重定向后的每个 URL 重新执行相同安全校验,禁止访问回环、内网、链路本地和云元数据地址;
- User-Agent 必须标识本系统并提供可联系的技术邮箱,不伪装普通浏览器;
- Authorization、Cookie 和签名密钥只从 Vault/KMS 引用注入,不写入任务、Raw、日志或异常;
- 登录页、验证码、安全验证、访问封禁和结构变化均触发停止或隔离,不尝试绕过。
连接器发布物必须包含:
- 代码仓库、语义版本、提交摘要和构建镜像摘要;
- 支持的数据范围与来源 Schema;
- 小样本、结构回归和历史快照回放结果;
- 默认分片、并发、超时、重试和熔断策略;
- 变更日志、回滚版本和技术责任人。
## 4. 任务状态机
```text
DRAFT
→ PROBING
→ READY
→ QUEUED
→ RUNNING
→ RAW_COMMITTED
→ PARSING
→ NORMALIZING
→ QUALITY_CHECKING
→ AWAITING_APPROVAL
→ PUBLISHED
异常分支:
RUNNING → THROTTLED → RUNNING
任意执行态 → PARTIALLY_FAILED → RETRYING
任意执行态 → QUARANTINED
发布态 → ROLLED_BACK
```
任务必须持久化:
- `job_id`、`source_id`、`connector_version`、`target_contract`;
- 调度计划、业务范围、分片数量、租约和优先级;
- 上次成功水位、本次水位、开始/结束时间;
- 请求量、原始对象数、解析数、有效数、隔离数;
- 错误分类、重试次数、保护动作和 trace_id。
## 5. 数据分层
### Raw
只追加,不覆盖。保存源端响应、页面、文件、请求元数据、采集时间、任务、分片、连接器版本和哈希。
### Source
按来源解析,字段与源端页面或接口一一对应。来源 Schema 独立版本化,解析可通过 Raw 快照重放。
### Standard
映射到 `JOB-SIGNAL`、`SCHOOL-EMPLOYMENT` 等统一契约。企业、岗位、地区、薪资和技能完成归一。
### Product
按数据产品、业务截止日期和租户范围生成不可变版本。报告和分析只引用已发布产品版本。
### 查询与浏览
厂商控制台的“采集数据”页面统一访问 Data Query Service,不允许前端绕过服务直接连接存储:
- **标准岗位**:默认查询当前稳定 `JOB-SIGNAL` 版本,支持来源、地区、岗位、企业和记录编号分页检索;
- **源端记录**:保留来源业务字段、来源URL、采集任务、连接器和解析器版本;
- **原始快照**:先查询对象元数据、SHA-256和留存策略,再按权限获取短期只读访问地址;
- **隔离记录**:显示失败规则、任务、快照、处置状态和重放入口,不进入稳定数据版本;
- 每次查询和导出都执行 RBAC、租户范围、字段权限和审计记录,详情页通过 `record_id → task_id → snapshot_id → content_hash → data_version` 完成追溯。
## 6. 去重与版本
岗位信号建议同时维护:
- 来源幂等键:`source_platform + source_record_id`;
- 内容键:规范化企业、岗位、地区、职责摘要的哈希;
- `first_seen_at`、`last_seen_at`、`published_at`;
- 来源状态和平台状态;
- 原始版本、解析版本、标准版本和数据产品版本。
跨来源相似岗位不能直接删除,应归入同一个岗位信号组:
```text
JobSignalCluster
├─ BOSS source record
├─ 智联 source record
├─ 公共招聘 source record
└─ 企业正式确认需求
```
分析层可对信号簇去重计数,同时保留每个来源的独立证据。
## 7. 校内数据要求
- 每条记录必须携带 `tenant_id`;
- 学生使用不可逆 `student_token`,不接收姓名、身份证和明文学号;
- 学校专业代码映射到教育部专业目录;
- `source_record_id + source_updated_at` 支持增量和幂等;
- 业务状态必须携带确认时间、确认角色和来源系统;
- 文件导入、API 和数据库视图使用同一目标契约;
- 单租户失败隔离,不影响其他学校生产任务;
- 原始明细和租户交付均按数据范围策略隔离。
## 8. 导入与导出
### 导入
1. 病毒与文件类型检查;
2. 文件哈希、大小、编码和分片登记;
3. JSON Schema 结构检查;
4. 字段映射和代码字典验证;
5. 小样本质量干跑;
6. 全量暂存导入;
7. 质量报告、错误明细和业务复核;
8. 发布不可变版本。
### 导出
每个交付包包含:
- 业务数据文件;
- 精确版本 JSON Schema;
- 字段说明和代码字典;
- 质量报告与失败规则摘要;
- 来源与血缘清单;
- `PACKAGE-MANIFEST`;
- 每个文件的 SHA-256;
- 租户范围、截止日期和上一稳定版本。
### 候选、审批与租户交付流程
Manifest 生成与发布必须是两个不同事务:
```text
ISSUE / WORK_ORDER
→ INVESTIGATING
→ QUALITY_DISPOSITION(不可变)
→ FIX_REPLAY_VERIFIED
→ RELEASE_CANDIDATE
→ CANDIDATE_MANIFEST_FROZEN
→ PENDING_APPROVAL
→ APPROVED(approver != applicant)
→ PUBLISHED
→ TENANT_DELIVERY
→ DELIVERED
→ ACKNOWLEDGED(record_count 与 SHA-256 同时通过)
```
- `FIX_REPLAY`、`WAIVE`、`DISCARD` 必须记录原因、复核人、操作者、时间、trace_id 和证据;动作只追加,不可覆盖。只有 `FIX_REPLAY` 同时满足重放记录数一致、质量规则全部通过和独立复核签名时,才可写入 `VERIFIED` 并允许候选版本继续提交。
- `WAIVE` 不等于质量验证通过,若产品允许风险放行,必须进入单独的风险豁免审批状态、风险接受人和到期时间;`DISCARD` 必须先验证丢弃范围、完整性阈值和候选差异并重建候选。两者不得复用普通 `VERIFIED/PASS`。
- `PACKAGE-MANIFEST V1.2` 增加 `release_id` 与 `release_status`。每个租户数据文件必须携带自身记录数和 SHA-256,`tenant_scope`、文件路径和租户授权清单必须一致。
- 候选 Manifest 的 `release_status` 必须为 `DRAFT`,提交审批后不可修改;驳回后旧候选失效。发布事务生成 `PUBLISHED` Manifest,`approval_reference` 必须引用状态为 `APPROVED` 的审批单。
- 候选 Manifest 生成接口必须接受幂等键或服务端输入指纹;相同产品、租户、截止日期、格式、质量处置和交付摘要不得重复产生候选或审计事件。
- 后端必须强制申请人与审批人不同,前端校验只能作为交互提示。批准后再以原子别名切换发布稳定版本。
- 每个学校是独立交付状态机:`PENDING → SENDING → DELIVERED → ACKNOWLEDGED`;异常使用 `FAILED → RETRYING`,并支持单租户 `ROLLED_BACK`。成功租户的幂等键阻止重复发送。
- 只有回执记录数等于包记录数、回执 SHA-256 等于 Manifest 文件摘要且回执签名有效时,服务端才能写入 `ACKNOWLEDGED`。
- 全局版本回滚和单租户回滚是不同操作。全局回滚必须先创建独立回滚审批,审批人与申请人分离,再执行稳定别名切换;两类回滚均需目标上一稳定版本、范围锁与不可变审计事件。
原型中的 `localStorage` 只用于静态演示刷新后继续操作,不能作为跨端协议或正式数据来源。
## 9. 安全与运维
- 源端凭据使用 Vault/KMS 管理,配置和日志只保存密钥引用;
- 来源授权、条款与 robots 快照作为连接器发布证据;授权到期自动停止调度;
- 采集节点使用独立网络出口策略与最小权限;
- 控制台操作采用 RBAC,并区分运营、开发、发布审批和审计;
- 原始对象启用版本、对象锁和生命周期;
- 审计事件使用统一 trace_id,关键事件每日生成签名摘要;
- 指标覆盖采集成功率、源端延迟、解析成功率、队列延迟、质量和交付 SLA;
- 生产发布采用双版本别名,支持秒级回滚到上一稳定版本。
- 所有问题、工单、质量处置、审批、发布、交付和回执写入统一事件模型,至少携带 `id/status/actor/time/trace/evidence`;
- 状态迁移 API 使用乐观锁或版本号避免重复审批、重复发布与重复发送;租户交付以 `tenant_id + package_id + data_version` 作为幂等边界;
- 通知中心从服务端待办查询生成,不依赖前端硬编码。
## 10. 静态原型与正式 API 边界
厂商端和校园端静态页面没有直接连接。原型共享的 `TENANT-HZVTC`、`EDU-PKG-20260823-01`、`V2026.08.23` 仅用于人工对照,页面中的“发送”“回执”“重试”“回滚”不会访问学校。
正式环境至少提供:
- `POST /issues/{id}/acknowledge|assign|investigate|resolve|close` 与带版本条件的工单更新;
- `POST /quality-dispositions`、`POST /quality-dispositions/{id}/verify`,处置动作写不可变事件存储;
- `POST /releases/{id}/manifest|submit|approve|reject|publish|rollback`,服务端检查发布质量条件和职责分离;
- `POST /deliveries/{tenant_id}/send|retry|acknowledge|rollback`,执行租户授权、幂等、签名和回执校验;
- `GET /notifications` 与统一审计事件查询/导出 API;
- OAuth/OIDC、RBAC/ABAC、审批人实时身份、请求签名、幂等键、乐观锁、限流和 WORM 审计。
## 11. 分阶段实施
### 第一阶段
- Source Registry、Scheduler、Raw Store;
- BOSS、智联、百日招聘、NCSS、中国公共招聘网五个连接器;
- `JOB-SIGNAL V3.0`;
- 基础质量、岗位归一和 Parquet 交付。
### 第二阶段
- 国聘、区域人才网、校内就业和实习连接器;
- 企业归一、技能词典和薪资标准化;
- 多租户发布、Manifest、审批和回滚。
### 第三阶段
- 全量连接器回归平台;
- 质量规则编排、自动血缘和版本影响分析;
- 供需报告、专业诊断和大屏使用统一数据产品版本。