feat: add edu-industry platform demos
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@@ -0,0 +1,266 @@
|
||||
# 产教招聘数据中台生产架构建议
|
||||
|
||||
## 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() 返回入口可达性、延迟和错误分类
|
||||
```
|
||||
|
||||
连接器发布物必须包含:
|
||||
|
||||
- 代码仓库、语义版本、提交摘要和构建镜像摘要;
|
||||
- 支持的数据范围与来源 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 管理,配置和日志只保存密钥引用;
|
||||
- 采集节点使用独立网络出口策略与最小权限;
|
||||
- 控制台操作采用 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、审批和回滚。
|
||||
|
||||
### 第三阶段
|
||||
|
||||
- 全量连接器回归平台;
|
||||
- 质量规则编排、自动血缘和版本影响分析;
|
||||
- 供需报告、专业诊断和大屏使用统一数据产品版本。
|
||||
@@ -0,0 +1,129 @@
|
||||
# 产教数据中台,厂商运营原型
|
||||
|
||||
本目录用于讨论厂商侧招聘数据采集与治理产品。商业招聘平台、公共就业平台和校内系统统一作为正式数据来源纳入数据生产与治理体系。
|
||||
|
||||
## 运行
|
||||
|
||||
直接打开 `index.html`,或在本目录启动静态服务:
|
||||
|
||||
```bash
|
||||
python3 -m http.server 8080
|
||||
```
|
||||
|
||||
访问 <http://localhost:8080>。
|
||||
|
||||
## 产品定位
|
||||
|
||||
这不是多个招聘网站爬虫脚本的简单集合,而是面向产教分析的数据生产控制面:
|
||||
|
||||
1. 注册和版本化管理商业、公共、校内三类数据源;
|
||||
2. 调度采集任务,管理地域、行业、岗位族、分片、失败隔离和增量水位;
|
||||
3. 保存原始快照、内容哈希、连接器代码版本和任务追踪编号;
|
||||
4. 将不同来源映射到统一的招聘岗位、企业、薪资和技能契约;
|
||||
5. 执行质量校验、企业归一、岗位分类和技能抽取;
|
||||
6. 通过带 Manifest、Schema、质量报告、血缘和校验和的数据包向学校交付。
|
||||
|
||||
## 已纳入的正式数据源
|
||||
|
||||
| 类别 | 数据源 | 原型状态 | 目标数据 |
|
||||
|---|---|---|---|
|
||||
| 商业平台 | BOSS直聘 | 正式运行 | 岗位、企业、地区、薪资、岗位职责、技能 |
|
||||
| 商业平台 | 智联招聘 | 正式运行 | 岗位、企业、地区、薪资、岗位职责、技能 |
|
||||
| 公共平台 | 全国中小企业招聘平台 | 正式运行 | 中小企业岗位、校招、实习和招聘活动 |
|
||||
| 公共平台 | 国家大学生就业服务平台 | 正式运行 | 高校毕业生岗位、专场招聘和实习 |
|
||||
| 公共平台 | 中国公共招聘网 | 正式运行 | 公共就业岗位、重点行业和招聘活动 |
|
||||
| 公共平台 | 国聘 | 正式运行 | 国资央企岗位和校园招聘 |
|
||||
| 公共平台 | 杭州人才网 | 降速保护 | 杭州都市圈企业和岗位 |
|
||||
| 校内系统 | 就业管理系统 | 正式运行 | 毕业去向、岗位、企业、薪资和专业相关度 |
|
||||
| 校内系统 | 实习管理系统 | 正式运行 | 实习岗位、企业、工资、过程和企业评价 |
|
||||
|
||||
## 交互范围
|
||||
|
||||
- **运行总览**:生产批次、采集量、质量、来源健康度、流水线和运营事项。
|
||||
- **运营处置**:问题确认与指派、排障、不可变质量处置、独立发布审批、逐学校交付回执、失败重试与租户级回滚。
|
||||
- **数据源管理**:来源分类、搜索、资产详情、采集配置、字段映射、运行与审计。
|
||||
- **采集任务**:筛选、任务详情、暂停/恢复、新建任务和小样本预检。
|
||||
- **采集数据**:查看标准岗位、源端记录、原始快照和隔离记录,支持来源、地区、关键词检索、明细追溯和结果导出。
|
||||
- **数据标准**:外部岗位、校内就业、交付 Manifest 三套版本化契约。
|
||||
- **导入与导出**:文件拖放、CSV 头部预检、样例下载、Manifest 生成和记录导出。
|
||||
- **质量与归一**:质量规则、发布阈值、岗位别名人工确认和批量处理。
|
||||
- **审计与交付**:采集、质量、发布、导入导出事件及证据链。
|
||||
|
||||
## 原型黄金闭环
|
||||
|
||||
“运营处置”提供一条可重复演示、刷新后保留的最小生产黄金路径:
|
||||
|
||||
```text
|
||||
告警 → 确认 → 指派 → 开始排障
|
||||
→ 修复并重放 → 记录数 / 规则 / 复核签名 VERIFIED
|
||||
→ 豁免 / 丢弃 → REVIEWED_BLOCKED,继续阻断
|
||||
→ REL-20260823-01 候选版本 → 生成并冻结候选 Manifest → 提交审批
|
||||
→ 独立审批人批准 / 驳回 → 发布
|
||||
→ 逐学校发送状态 → 记录数 + SHA-256 回执
|
||||
→ ACKNOWLEDGED / 单校失败重试 / 单租户回滚
|
||||
→ 全局回滚申请 → 独立回滚审批 → 执行稳定别名回滚
|
||||
```
|
||||
|
||||
- 杭州人才网问题 `ISSUE-HZRC-20260823-01` 可完整流转。只有最后一次处置是 `FIX_REPLAY`,且重放记录数一致、质量规则通过、复核签名存在时,候选版本质量门禁才进入 `PASS`。
|
||||
- `WAIVE` 与 `DISCARD` 的独立复核会写入 `REVIEWED_BLOCKED`,分别提示另行风险审批或重建候选,不会复用 `VERIFIED/PASS`。
|
||||
- 发布申请人默认为陈致远,审批人若选择同一人会被四眼规则阻止。
|
||||
- 候选发布必须同时满足质量门禁和候选 Manifest 已生成;审批中 Manifest 冻结,驳回后返回草稿并使旧候选失效。
|
||||
- 候选 Manifest 使用输入指纹保证重复生成幂等;产品、租户、截止日期、格式、质量处置和交付摘要未变化时复用原候选,不重复写审计或交换日志。
|
||||
- 候选版本、数据版本和包分别为 `REL-20260823-01`、`V2026.08.23`、`EDU-PKG-20260823-01`。
|
||||
- 杭州科技职业技术学院使用共享标识 `TENANT-HZVTC`。另外展示浙江机电职业技术大学和宁波城市职业技术学院,交付状态按租户隔离。
|
||||
- 原型仓库使用 `localStorage` 命名空间 `eduIndustry.vendorOperations.v1`,当前 `schemaVersion=2`,包含 issues、workOrders、qualityDispositions、releases、approvals、deliveries、auditEvents。页面提供“重置演示数据”恢复种子。
|
||||
- `PACKAGE-MANIFEST V1.2` 新增 `release_id` 和 `release_status`,并按三个租户输出彼此独立的记录数与 SHA-256 文件项。候选 Manifest 保持 `DRAFT`,正式发布时生成 `PUBLISHED` Manifest,`approval_reference` 固定引用 `APPROVED` 审批单。
|
||||
- 全局回滚和单租户回滚严格分离。全局回滚必须填写原因、由不同于申请人的审批人批准后才可执行,审计证据保存目标稳定版本、审批引用和影响范围锁。
|
||||
- 静态演示的审计、质量处置、问题时间线和交换日志采用明确保留上限;正式系统必须使用服务端分页、归档和 WORM 审计。
|
||||
|
||||
## 静态跨端边界
|
||||
|
||||
本目录是**厂商端静态 SPA 原型**,与仓库根目录下的校园端 `/demo/` 没有运行时连接。双方仅通过约定标识(`TENANT-HZVTC`、`EDU-PKG-20260823-01`、`V2026.08.23`)对照展示,不共享浏览器存储,也不通过静态页面传输数据。
|
||||
|
||||
按钮中的发送、回执、重试与回滚均为本地状态机模拟:不会访问学校接口、不会写入校园端、不会发送真实数据。正式跨端同步必须由经过鉴权、签名、幂等和审计控制的服务端 API 执行。
|
||||
|
||||
## 标准文件
|
||||
|
||||
- `schemas/external-job-source.schema.json`
|
||||
- `JOB-SIGNAL V3.0`
|
||||
- 商业和公共招聘平台的统一岗位信号契约
|
||||
- `schemas/school-employment.schema.json`
|
||||
- `SCHOOL-EMPLOYMENT V2.2`
|
||||
- 校内就业事实契约,包含租户隔离和学生令牌化要求
|
||||
- `schemas/package-manifest.schema.json`
|
||||
- `PACKAGE-MANIFEST V1.2`
|
||||
- 版本化导入、导出和学校交付包清单
|
||||
- `samples/external-job-sample.csv`
|
||||
- 可在“导入与导出”页面上传并执行前端结构预检
|
||||
|
||||
## “可生产”的含义
|
||||
|
||||
原型已将正式产品必须具备的对象、状态和证据做进界面与标准,但静态页面不直接执行公网采集。正式后端应实现:
|
||||
|
||||
- 独立连接器运行时与容器化任务;
|
||||
- 消息队列、分片调度、租约、心跳和重试;
|
||||
- 原始对象存储、解析层、标准层和交付层分区;
|
||||
- 密钥管理、网络出口、源端策略和任务限额;
|
||||
- PostgreSQL 元数据、审计事件和数据版本;
|
||||
- Schema Registry、质量引擎、岗位与企业归一服务;
|
||||
- 数据包签名、租户范围校验和可回滚发布。
|
||||
- 问题与工单 API、质量处置不可变事件 API、独立审批 API、版本别名发布/回滚 API;
|
||||
- 按租户幂等交付 API、回执验签 API、失败隔离与单租户重试/回滚 API;
|
||||
- 服务端强制状态迁移、RBAC/职责分离、并发版本控制与 WORM 审计,不能信任浏览器 `localStorage`。
|
||||
|
||||
详细实现建议见 [PRODUCTION_ARCHITECTURE.md](./PRODUCTION_ARCHITECTURE.md)。
|
||||
|
||||
## 验收建议
|
||||
|
||||
- 桌面:`1440 × 900`
|
||||
- 移动:`390 × 844`
|
||||
- 可见业务文字不小于 13px
|
||||
- 页面级无横向溢出,宽表仅在自身容器内横向滚动
|
||||
- 所有深层按钮必须打开业务内容或形成列表状态变化
|
||||
- JavaScript 语法检查:`node --check app.js`
|
||||
- JSON 文件检查:`python3 -m json.tool <file>`
|
||||
|
||||
新增闭环预览:
|
||||
|
||||
- `preview-admin-operations.png`
|
||||
- `preview-admin-operations-mobile.png`
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<rect width="64" height="64" rx="15" fill="#102f26"/>
|
||||
<path d="M14 15h24a6 6 0 0 1 0 12H14a6 6 0 0 1 0-12Z" fill="#c8ec73"/>
|
||||
<path d="M21 27h29a6 6 0 0 1 0 12H21a6 6 0 0 1 0-12Z" fill="#83c6a0"/>
|
||||
<path d="M29 39h21a6 6 0 0 1 0 12H29a6 6 0 0 1 0-12Z" fill="#3c9b74"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 343 B |
@@ -0,0 +1,675 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="产教数据中台,面向厂商数据运营团队管理招聘数据采集、标准契约、导入导出、质量治理与审计交付"
|
||||
/>
|
||||
<title>产教数据中台 · 厂商运营中心</title>
|
||||
<link rel="icon" href="./favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<aside class="sidebar" id="sidebar">
|
||||
<div class="brand">
|
||||
<span class="brand-mark" aria-hidden="true"><i></i><i></i><i></i></span>
|
||||
<span>
|
||||
<strong>产教数据中台</strong>
|
||||
<small>INDUSTRY DATA OPS</small>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<nav class="main-nav" aria-label="数据中台主导航">
|
||||
<span class="nav-label">运营工作台</span>
|
||||
<button class="nav-item active" data-view="overview">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 13h6V4H4v9Zm0 7h6v-4H4v4Zm10 0h6v-9h-6v9Zm0-16v4h6V4h-6Z" /></svg>
|
||||
<span>运行总览</span>
|
||||
</button>
|
||||
<button class="nav-item" data-view="operations">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 4h16v5H4V4Zm0 11h7v5H4v-5Zm11 0h5v5h-5v-5ZM7 9v6m10-6v6" /></svg>
|
||||
<span>运营处置</span>
|
||||
<em class="warning" id="operationsNavCount">3</em>
|
||||
</button>
|
||||
<button class="nav-item" data-view="sources">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><ellipse cx="12" cy="5" rx="8" ry="3" /><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6" /></svg>
|
||||
<span>数据源管理</span>
|
||||
<em id="sourceNavCount">9</em>
|
||||
</button>
|
||||
<button class="nav-item" data-view="collectors">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 4h14v5H5V4Zm0 11h14v5H5v-5ZM8 9v6m8-6v6M9 6h.01M9 17h.01" /></svg>
|
||||
<span>采集任务</span>
|
||||
<i class="nav-live"></i>
|
||||
</button>
|
||||
<button class="nav-item" data-view="records">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5h16v14H4V5Zm0 5h16M9 5v14m6-9v9" /></svg>
|
||||
<span>采集数据</span>
|
||||
</button>
|
||||
<button class="nav-item" data-view="contracts">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 3h8l4 4v14H7V3Zm8 0v5h4M10 12h6m-6 4h6M4 7v14h11" /></svg>
|
||||
<span>数据标准</span>
|
||||
</button>
|
||||
<button class="nav-item" data-view="exchange">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 7h11M15 3l4 4-4 4M16 17H5m4-4-4 4 4 4" /></svg>
|
||||
<span>导入与导出</span>
|
||||
</button>
|
||||
<button class="nav-item" data-view="quality">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m12 3 8 4v5c0 5-3.4 8.3-8 9-4.6-.7-8-4-8-9V7l8-4Zm-4 9 2.5 2.5L16 9" /></svg>
|
||||
<span>质量与归一</span>
|
||||
<em class="warning">27</em>
|
||||
</button>
|
||||
<button class="nav-item" data-view="audit">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3h6l1 3h4v15H4V6h4l1-3Zm0 9 2 2 4-4m-6 8h6" /></svg>
|
||||
<span>审计与交付</span>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-runtime">
|
||||
<span><i></i>生产环境运行正常</span>
|
||||
<strong>华东主集群</strong>
|
||||
<small>采集节点 24 / 24 · 队列延迟 18s</small>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="workspace">
|
||||
<header class="topbar">
|
||||
<button class="icon-button mobile-menu" id="mobileMenu" aria-label="打开导航">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 6h16M4 12h16M4 18h16" /></svg>
|
||||
</button>
|
||||
<div class="topbar-context">
|
||||
<small>全国招聘数据运营中心</small>
|
||||
<strong id="breadcrumbCurrent">运行总览</strong>
|
||||
</div>
|
||||
<label class="global-search">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7" /><path d="m20 20-4-4" /></svg>
|
||||
<input id="globalSearch" type="search" placeholder="搜索数据源、任务或版本" />
|
||||
</label>
|
||||
<div class="topbar-actions">
|
||||
<span class="environment-chip"><i></i>生产环境</span>
|
||||
<button class="icon-button" id="notificationButton" aria-label="运行通知">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9M10 21h4" /></svg>
|
||||
<b>4</b>
|
||||
</button>
|
||||
<button class="operator-card" id="operatorButton">
|
||||
<span>陈</span>
|
||||
<span><strong>陈致远</strong><small>厂商数据运营管理员</small></span>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m7 10 5 5 5-5" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="main-content">
|
||||
<section class="view active" id="view-overview" data-title="运行总览">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> DATA OPERATIONS CONTROL PLANE</div>
|
||||
<h1>招聘数据生产运行总览</h1>
|
||||
<p>统一管理商业招聘平台、公共就业平台和校内业务系统,从采集到交付全链路可追溯。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" data-open-export>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
||||
导出运行日报
|
||||
</button>
|
||||
<button class="button secondary" data-open-source-modal>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
|
||||
新增数据源
|
||||
</button>
|
||||
<button class="button primary" data-view-jump="records">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5h16v14H4V5Zm0 5h16M9 5v14m6-9v9" /></svg>
|
||||
查看采集数据
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article class="production-hero">
|
||||
<div>
|
||||
<span class="hero-kicker"><i></i> NATIONAL DATA PIPELINE</span>
|
||||
<h2>今日生产批次 EDU-JOB-20260823</h2>
|
||||
<p>9 个数据源进入调度,7 个已完成,2 个持续采集中;当前稳定版本不受运行中任务影响。</p>
|
||||
<div class="hero-status-row">
|
||||
<span>运行中<strong>2</strong></span>
|
||||
<span>今日入湖<strong>190,420</strong></span>
|
||||
<span>隔离记录<strong>1,286</strong></span>
|
||||
<span>预计完成<strong>11:40</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-score">
|
||||
<span class="score-ring"><strong>94.7</strong><small>综合质量</small></span>
|
||||
<span><strong id="overviewReleaseState">候选发布受阻</strong><small id="overviewReleaseDetail">杭州人才网修复重放尚未验证</small></span>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="metric-grid">
|
||||
<article><span>有效岗位总量</span><strong>12.84<small>百万</small></strong><em>近90天去重信号</em><i class="positive">↑ 8.6%</i></article>
|
||||
<article><span>今日采集成功率</span><strong>98.7<small>%</small></strong><em>1,428 / 1,447 分片</em><i class="positive">SLA内</i></article>
|
||||
<article><span>岗位归一覆盖</span><strong>96.4<small>%</small></strong><em>国标 + 行业词典 V4.3</em><i class="warning">27项待审</i></article>
|
||||
<article><span>数据交付租户</span><strong>36<small>所</small></strong><em>旗舰版与区域项目</em><i class="positive">全部有效</i></article>
|
||||
</div>
|
||||
|
||||
<div class="overview-grid">
|
||||
<article class="panel source-health-panel">
|
||||
<div class="panel-head">
|
||||
<div><span>来源运行状态</span><h2>核心数据源健康度</h2></div>
|
||||
<button class="text-button" data-view-jump="sources">查看全部来源</button>
|
||||
</div>
|
||||
<div class="source-health-list" id="overviewSourceHealth"></div>
|
||||
</article>
|
||||
|
||||
<article class="panel flow-panel">
|
||||
<div class="panel-head">
|
||||
<div><span>处理链路</span><h2>今日数据流水线</h2></div>
|
||||
<span class="live-label"><i></i>实时</span>
|
||||
</div>
|
||||
<div class="pipeline-flow">
|
||||
<span class="done"><b>01</b><strong>源端采集</strong><small>190,420 条</small></span><i></i>
|
||||
<span class="done"><b>02</b><strong>原始留存</strong><small>100% 哈希</small></span><i></i>
|
||||
<span class="active"><b>03</b><strong>清洗归一</strong><small>96.4% 完成</small></span><i></i>
|
||||
<span><b>04</b><strong>质量验收</strong><small>11:20 预计</small></span><i></i>
|
||||
<span><b>05</b><strong>版本交付</strong><small>待审批</small></span>
|
||||
</div>
|
||||
<div class="flow-caption">
|
||||
<span><strong>RAW-20260823-09</strong> 原始快照</span>
|
||||
<span><strong>JOB-SIGNAL 3.0</strong> 目标契约</span>
|
||||
<span><strong>SHA-256</strong> 全量校验</span>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel alert-panel">
|
||||
<div class="panel-head">
|
||||
<div><span>运营关注</span><h2>待处理事项</h2></div>
|
||||
<em>4 项</em>
|
||||
</div>
|
||||
<div class="alert-list" id="overviewIssueList">
|
||||
<button data-open-issue="ISSUE-NORM-20260823-01"><i class="red"></i><span><strong>27 个岗位别名待人工归一</strong><small>涉及具身智能、低空经济等新增岗位</small></span><em>高</em></button>
|
||||
<button data-open-issue="ISSUE-HZRC-20260823-01"><i class="amber"></i><span><strong>杭州人才网响应时延升高</strong><small>最近 20 分钟 P95 为 4.8s,任务已自动降速</small></span><em>中</em></button>
|
||||
<button data-open-issue="ISSUE-CONTRACT-20260823-01"><i class="blue"></i><span><strong>校内就业契约 V2.2 待发布</strong><small>新增就业质量和去向确认字段</small></span><em>中</em></button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-operations" data-title="运营处置">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> OPERATIONS RESOLUTION LOOP</div>
|
||||
<h1>运营问题、发布与学校交付</h1>
|
||||
<p>从告警确认、排障和质量复核,到独立审批、版本发布、逐学校回执与租户级回滚,全程保留状态与审计证据。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="resetOperationsSeed">重置演示数据</button>
|
||||
<button class="button primary" id="operationsPrimaryAction">处理最高优先级问题</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="operations-metrics" id="operationsMetrics"></div>
|
||||
|
||||
<nav class="operations-tabs" id="operationsTabs" aria-label="运营处置工作区">
|
||||
<button class="active" data-operations-tab="issues">问题队列</button>
|
||||
<button data-operations-tab="releases">候选发布</button>
|
||||
<button data-operations-tab="deliveries">学校交付</button>
|
||||
</nav>
|
||||
|
||||
<div class="operations-workspace active" id="operations-issues">
|
||||
<article class="panel operations-panel">
|
||||
<div class="panel-head">
|
||||
<div><span>ISSUE & WORK ORDER</span><h2>问题处置队列</h2></div>
|
||||
<em id="issueQueueSummary">加载中</em>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table operations-table">
|
||||
<thead><tr><th>问题与追踪</th><th>级别 / SLA</th><th>影响</th><th>负责人</th><th>状态</th><th>最近动作</th><th>操作</th></tr></thead>
|
||||
<tbody id="operationsIssueTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="operations-workspace" id="operations-releases">
|
||||
<div id="releaseWorkspace"></div>
|
||||
</div>
|
||||
|
||||
<div class="operations-workspace" id="operations-deliveries">
|
||||
<article class="panel operations-panel">
|
||||
<div class="panel-head">
|
||||
<div><span>TENANT DELIVERY</span><h2>逐学校交付与回执</h2></div>
|
||||
<button class="text-button" id="startPendingDeliveries">启动待发送学校</button>
|
||||
</div>
|
||||
<div class="delivery-boundary-note">静态原型只模拟并持久化交付状态,不会向学校网络、接口或业务系统真实发送数据。</div>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table delivery-table">
|
||||
<thead><tr><th>学校 / 租户</th><th>包与数据版本</th><th>交付状态</th><th>记录数回执</th><th>SHA-256 回执</th><th>最近动作</th><th>操作</th></tr></thead>
|
||||
<tbody id="deliveryTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-sources" data-title="数据源管理">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> SOURCE REGISTRY</div>
|
||||
<h1>统一数据源注册中心</h1>
|
||||
<p>商业招聘平台、公共就业平台、活动聚合平台和校内系统使用同一套资产、版本和运行模型。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="sourceCatalogExport">导出数据源目录</button>
|
||||
<button class="button primary" data-open-source-modal>新增数据源</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-strip">
|
||||
<span><small>数据源总数</small><strong id="sourceTotal">9</strong><em>7外部 · 2校内</em></span>
|
||||
<span><small>正式运行</small><strong id="sourceRunning">8</strong><em>1个降速保护</em></span>
|
||||
<span><small>今日新增记录</small><strong>190,420</strong><em>有效率 98.1%</em></span>
|
||||
<span><small>稳定交付版本</small><strong>V2026.08.23</strong><em>36所学校引用</em></span>
|
||||
</div>
|
||||
|
||||
<article class="panel source-registry-panel">
|
||||
<div class="source-toolbar">
|
||||
<div class="filter-pills" id="sourceFilters">
|
||||
<button class="active" data-source-filter="all">全部来源</button>
|
||||
<button data-source-filter="commercial">商业平台</button>
|
||||
<button data-source-filter="public">公共平台</button>
|
||||
<button data-source-filter="school">校内系统</button>
|
||||
</div>
|
||||
<label class="inline-search">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7" /><path d="m20 20-4-4" /></svg>
|
||||
<input id="sourceSearch" type="search" placeholder="按名称、域名、适配器搜索" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="source-grid" id="sourceGrid"></div>
|
||||
<div class="list-summary" id="sourceListSummary">当前展示 9 个数据源</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-collectors" data-title="采集任务">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> COLLECTION ORCHESTRATION</div>
|
||||
<h1>采集任务编排中心</h1>
|
||||
<p>按来源、地域、行业和岗位族编排任务,支持分片、限速、失败隔离、断点续采和版本化原始留存。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="pauseAllJobs">暂停全部</button>
|
||||
<button class="button primary" id="newCollectionJob">新建采集任务</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collector-metrics">
|
||||
<article><span><i class="green"></i>运行中</span><strong id="runningJobCount">3</strong><small>64 个活跃分片</small></article>
|
||||
<article><span><i class="blue"></i>今日完成</span><strong>18</strong><small>平均耗时 42 分钟</small></article>
|
||||
<article><span><i class="amber"></i>自动保护</span><strong>1</strong><small>源端延迟触发降速</small></article>
|
||||
<article><span><i class="red"></i>失败分片</span><strong>6</strong><small>已进入重试队列</small></article>
|
||||
</div>
|
||||
|
||||
<article class="panel collector-table-panel">
|
||||
<div class="table-toolbar">
|
||||
<div class="segmented" id="jobFilters">
|
||||
<button class="active" data-job-filter="all">全部任务</button>
|
||||
<button data-job-filter="running">运行中</button>
|
||||
<button data-job-filter="scheduled">等待调度</button>
|
||||
<button data-job-filter="attention">需要关注</button>
|
||||
</div>
|
||||
<span>调度器心跳:刚刚 · 队列延迟 18s</span>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>任务与来源</th><th>采集范围</th><th>运行策略</th><th>进度</th><th>本批次数据</th><th>状态</th><th>操作</th></tr></thead>
|
||||
<tbody id="collectionJobTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-records" data-title="采集数据">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> DATA RECORD EXPLORER</div>
|
||||
<h1>采集数据浏览与追溯</h1>
|
||||
<p>按数据层、来源、地区和关键词检索岗位明细,向下追溯源端记录、原始快照、采集任务与内容哈希。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="recordRefresh">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 7v5h-5M4 17v-5h5M18 9a7 7 0 0 0-12-2l-2 3m2 5a7 7 0 0 0 12 2l2-3" /></svg>
|
||||
刷新查询
|
||||
</button>
|
||||
<button class="button primary" id="recordExport">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
||||
导出当前结果
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-strip record-summary-strip">
|
||||
<span><small>稳定标准岗位</small><strong>12.84M</strong><em>JOB-SIGNAL V3.0</em></span>
|
||||
<span><small>今日源端入湖</small><strong>190,420</strong><em>9个来源批次</em></span>
|
||||
<span><small>今日标准入湖</small><strong>189,134</strong><em>已通过生产质量规则</em></span>
|
||||
<span><small>隔离记录</small><strong>1,286</strong><em>未进入稳定版本</em></span>
|
||||
</div>
|
||||
|
||||
<article class="panel record-browser-panel">
|
||||
<div class="record-layer-tabs" id="recordLayers" aria-label="数据层">
|
||||
<button class="active" data-record-layer="standard"><span>STANDARD</span><strong>标准岗位</strong><small>清洗归一后的生产数据</small></button>
|
||||
<button data-record-layer="source"><span>SOURCE</span><strong>源端记录</strong><small>保留来源原始业务字段</small></button>
|
||||
<button data-record-layer="raw"><span>RAW</span><strong>原始快照</strong><small>请求响应、文件与内容哈希</small></button>
|
||||
<button data-record-layer="quarantine"><span>QUARANTINE</span><strong>隔离记录</strong><small>质量失败与人工处置</small></button>
|
||||
</div>
|
||||
|
||||
<div class="record-query-bar">
|
||||
<label><span>数据来源</span><select id="recordSourceFilter"></select></label>
|
||||
<label><span>工作地区</span><select id="recordRegionFilter"><option value="all">全部地区</option><option value="杭州">杭州</option><option value="宁波">宁波</option><option value="嘉兴">嘉兴</option><option value="绍兴">绍兴</option><option value="上海">上海</option><option value="苏州">苏州</option></select></label>
|
||||
<label class="record-search-field"><span>检索条件</span><input id="recordSearch" type="search" placeholder="岗位、企业、记录编号、任务或快照" /></label>
|
||||
</div>
|
||||
|
||||
<div class="query-service-note">
|
||||
<span><i></i>查询服务</span>
|
||||
<strong>当前绑定稳定版本 V2026.08.23</strong>
|
||||
<small>静态原型展示契约化结构样例;正式环境由数据查询服务分页返回已采集明细,并执行租户范围与字段权限控制。</small>
|
||||
</div>
|
||||
|
||||
<div id="recordTableContainer"></div>
|
||||
<div class="record-list-footer">
|
||||
<span id="recordQuerySummary">正在加载查询结果</span>
|
||||
<small>点击“查看”可核对业务字段、来源URL、任务、快照和SHA-256证据。</small>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-contracts" data-title="数据标准">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> DATA CONTRACT GOVERNANCE</div>
|
||||
<h1>产教数据标准与契约中心</h1>
|
||||
<p>第三方招聘数据和校内业务数据按版本化契约交付,字段、代码、质量、脱敏和变更策略一次定义、全链路执行。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="compareContractVersions">版本对比</button>
|
||||
<button class="button primary" id="downloadStandardKit">下载标准包</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="contract-tabs" id="contractTabs">
|
||||
<button class="active" data-contract="external-job"><span>JOB-SIGNAL</span><strong>外部岗位信号</strong><small>V3.0 · 39字段</small></button>
|
||||
<button data-contract="school-employment"><span>SCHOOL-EMPLOYMENT</span><strong>校内就业事实</strong><small>V2.2 · 32字段</small></button>
|
||||
<button data-contract="package-manifest"><span>PACKAGE-MANIFEST</span><strong>交付包清单</strong><small>V1.2 · 21字段</small></button>
|
||||
</div>
|
||||
<div id="contractContent"></div>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-exchange" data-title="导入与导出">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> DATA EXCHANGE</div>
|
||||
<h1>数据导入与交付中心</h1>
|
||||
<p>支持标准文件导入、Schema 预检、字段映射、质量干跑和带清单、校验和、质量报告的版本化导出。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<a class="button secondary" href="./samples/external-job-sample.csv" download>下载导入样例</a>
|
||||
<button class="button primary" id="buildExportPackage">创建交付包</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="exchange-grid">
|
||||
<article class="panel import-panel">
|
||||
<div class="panel-head"><div><span>标准导入</span><h2>上传并校验数据文件</h2></div><em>CSV / JSONL / XLSX / Parquet</em></div>
|
||||
<label class="upload-zone" id="uploadZone">
|
||||
<input id="importFile" type="file" accept=".csv,.json,.jsonl,.xlsx,.parquet" />
|
||||
<span class="upload-icon">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 16V4m0 0 4 4m-4-4L8 8M5 20h14" /></svg>
|
||||
</span>
|
||||
<strong>选择文件或拖放到此处</strong>
|
||||
<small>最大 2GB;大文件将自动分片并计算 SHA-256</small>
|
||||
</label>
|
||||
<div class="import-configuration">
|
||||
<label><span>目标契约</span><select id="importContract"><option value="external-job">JOB-SIGNAL V3.0</option><option value="school-employment">SCHOOL-EMPLOYMENT V2.2</option></select></label>
|
||||
<label><span>导入模式</span><select id="importMode"><option>新增或更新 UPSERT</option><option>初次全量 FULL</option><option>仅质量验证 DRY-RUN</option></select></label>
|
||||
</div>
|
||||
<div class="import-preview" id="importPreview">
|
||||
<span><small>等待文件</small><strong>尚未选择导入文件</strong></span>
|
||||
<button class="button primary" id="validateImport" disabled>执行预检</button>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel export-panel">
|
||||
<div class="panel-head"><div><span>版本交付</span><h2>构建数据交付包</h2></div><em>可复核、可回滚</em></div>
|
||||
<div class="export-form">
|
||||
<label><span>数据产品</span><select id="exportProduct"><option>区域招聘岗位基础包</option><option>薪资与企业画像增强包</option><option>产业趋势与政策信号包</option></select></label>
|
||||
<label><span>目标租户</span><select id="exportTenant"><option>36所已授权学校</option><option>杭州科技职业技术学院</option><option>华东区域项目组</option></select></label>
|
||||
<label><span>数据截止日期</span><input id="exportAsOf" type="date" value="2026-08-23" /></label>
|
||||
<label><span>格式</span><select id="exportFormat"><option>Parquet + Manifest</option><option>CSV UTF-8 + Manifest</option><option>JSONL + Manifest</option></select></label>
|
||||
</div>
|
||||
<div class="package-includes">
|
||||
<span><i>✓</i>业务数据文件</span><span><i>✓</i>JSON Schema</span><span><i>✓</i>代码字典</span>
|
||||
<span><i>✓</i>质量报告</span><span><i>✓</i>血缘与来源清单</span><span><i>✓</i>SHA-256 校验和</span>
|
||||
</div>
|
||||
<button class="button primary wide" id="generatePackage">生成候选包 / Manifest</button>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<article class="panel recent-exchange-panel">
|
||||
<div class="panel-head"><div><span>交换记录</span><h2>最近导入与交付任务</h2></div><button class="text-button" id="exportExchangeLog">导出记录</button></div>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table compact">
|
||||
<thead><tr><th>追踪编号</th><th>类型</th><th>对象</th><th>数据版本</th><th>记录数</th><th>执行人</th><th>结果</th><th>时间</th></tr></thead>
|
||||
<tbody id="exchangeLogTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-quality" data-title="质量与归一">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> QUALITY & NORMALIZATION</div>
|
||||
<h1>数据质量与岗位归一</h1>
|
||||
<p>执行结构、完整性、唯一性、时效性和业务规则校验,将多来源岗位映射到统一岗位与技能体系。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="qualityRuleButton">质量规则</button>
|
||||
<button class="button primary" id="normalizationBatch">批量处理待审项</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="quality-layout">
|
||||
<article class="quality-score-card">
|
||||
<span class="quality-ring"><strong>94.7</strong><small>综合质量</small></span>
|
||||
<div><span>生产发布阈值 ≥ 90</span><strong id="qualityReleaseState">当前批次仍需修复重放复核</strong><small id="qualityReleaseDetail">质量分达标不等于门禁通过,稳定版本继续保持不变</small></div>
|
||||
</article>
|
||||
<div class="quality-dimensions">
|
||||
<span><small>完整性</small><strong>97.8%</strong><i><b style="width:97.8%"></b></i></span>
|
||||
<span><small>唯一性</small><strong>99.6%</strong><i><b style="width:99.6%"></b></i></span>
|
||||
<span><small>时效性</small><strong>93.1%</strong><i><b style="width:93.1%"></b></i></span>
|
||||
<span><small>岗位归一</small><strong>96.4%</strong><i><b style="width:96.4%"></b></i></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="quality-grid">
|
||||
<article class="panel rule-panel">
|
||||
<div class="panel-head"><div><span>规则执行</span><h2>当前质量规则组</h2></div><em>32条启用</em></div>
|
||||
<div class="rule-list" id="qualityRuleList"></div>
|
||||
</article>
|
||||
<article class="panel normalization-panel">
|
||||
<div class="panel-head"><div><span>人工复核</span><h2>岗位归一待审队列</h2></div><em>27项</em></div>
|
||||
<div class="normalization-list" id="normalizationList"></div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-audit" data-title="审计与交付">
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow"><i></i> AUDIT & DELIVERY</div>
|
||||
<h1>全链路审计与生产交付</h1>
|
||||
<p>记录来源、采集任务、代码版本、原始快照、处理规则、发布审批和租户交付,实现问题可定位、版本可回滚。</p>
|
||||
</div>
|
||||
<div class="heading-actions">
|
||||
<button class="button secondary" id="auditPolicyButton">审计策略</button>
|
||||
<button class="button primary" id="exportAuditLog">导出审计日志</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="audit-summary">
|
||||
<article><small>今日审计事件</small><strong>2,846</strong><em>全部已签名</em></article>
|
||||
<article><small>数据版本</small><strong>128</strong><em>保留 36 个月</em></article>
|
||||
<article><small>可追踪任务</small><strong>100%</strong><em>原始快照已绑定</em></article>
|
||||
<article><small>交付租户</small><strong>36</strong><em>范围策略有效</em></article>
|
||||
</div>
|
||||
|
||||
<article class="panel audit-table-panel">
|
||||
<div class="table-toolbar">
|
||||
<div class="segmented" id="auditFilters">
|
||||
<button class="active" data-audit-filter="all">全部事件</button>
|
||||
<button data-audit-filter="collect">采集</button>
|
||||
<button data-audit-filter="quality">质量</button>
|
||||
<button data-audit-filter="publish">发布</button>
|
||||
<button data-audit-filter="operations">运营处置</button>
|
||||
<button data-audit-filter="exchange">导入导出</button>
|
||||
</div>
|
||||
<span>审计存储 WORM · 每日校验</span>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>时间与追踪编号</th><th>事件</th><th>对象</th><th>操作者/服务</th><th>结果</th><th>证据</th></tr></thead>
|
||||
<tbody id="auditTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-scrim" id="sidebarScrim"></div>
|
||||
<div class="toast-region" id="toastRegion" aria-live="polite"></div>
|
||||
|
||||
<div class="drawer-backdrop" id="sourceDrawer" aria-hidden="true">
|
||||
<aside class="drawer" role="dialog" aria-modal="true" aria-labelledby="sourceDrawerTitle">
|
||||
<header class="drawer-header">
|
||||
<div>
|
||||
<span id="sourceDrawerKicker">SOURCE DETAIL</span>
|
||||
<h2 id="sourceDrawerTitle">数据源详情</h2>
|
||||
<p id="sourceDrawerDescription">查看采集策略、映射、运行和审计证据。</p>
|
||||
</div>
|
||||
<button class="icon-button" id="closeSourceDrawer" aria-label="关闭数据源详情">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
</header>
|
||||
<nav class="drawer-tabs" id="sourceDrawerTabs">
|
||||
<button class="active" data-source-tab="overview">资产概览</button>
|
||||
<button data-source-tab="acquisition">采集配置</button>
|
||||
<button data-source-tab="mapping">字段映射</button>
|
||||
<button data-source-tab="runtime">运行记录</button>
|
||||
<button data-source-tab="audit">审计证据</button>
|
||||
</nav>
|
||||
<div class="drawer-content" id="sourceDrawerContent"></div>
|
||||
<footer class="drawer-footer" id="sourceDrawerFooter"></footer>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<div class="drawer-backdrop" id="recordDrawer" aria-hidden="true">
|
||||
<aside class="drawer record-drawer" role="dialog" aria-modal="true" aria-labelledby="recordDrawerTitle">
|
||||
<header class="drawer-header">
|
||||
<div>
|
||||
<span id="recordDrawerKicker">DATA RECORD</span>
|
||||
<h2 id="recordDrawerTitle">采集记录详情</h2>
|
||||
<p id="recordDrawerDescription">查看业务字段和全链路来源证据。</p>
|
||||
</div>
|
||||
<button class="icon-button" id="closeRecordDrawer" aria-label="关闭采集记录详情">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
</header>
|
||||
<div class="drawer-content" id="recordDrawerContent"></div>
|
||||
<footer class="drawer-footer" id="recordDrawerFooter"></footer>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<div class="drawer-backdrop" id="issueDrawer" aria-hidden="true">
|
||||
<aside class="drawer issue-drawer" role="dialog" aria-modal="true" aria-labelledby="issueDrawerTitle">
|
||||
<header class="drawer-header">
|
||||
<div>
|
||||
<span id="issueDrawerKicker">OPERATIONS ISSUE</span>
|
||||
<h2 id="issueDrawerTitle">问题详情</h2>
|
||||
<p id="issueDrawerDescription">查看负责人、SLA、影响、证据和处置时间线。</p>
|
||||
</div>
|
||||
<button class="icon-button" id="closeIssueDrawer" aria-label="关闭问题详情">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
</header>
|
||||
<div class="drawer-content" id="issueDrawerContent"></div>
|
||||
<footer class="drawer-footer issue-drawer-footer" id="issueDrawerFooter"></footer>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" id="sourceModal" aria-hidden="true">
|
||||
<section class="modal" role="dialog" aria-modal="true" aria-labelledby="sourceModalTitle">
|
||||
<button class="modal-close" data-close-modal aria-label="关闭">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
<span class="modal-kicker">SOURCE ONBOARDING</span>
|
||||
<h2 id="sourceModalTitle">注册新数据源</h2>
|
||||
<p>登记来源、连接方式和目标契约,保存后自动创建连接测试与初次全量任务。</p>
|
||||
<form id="sourceForm">
|
||||
<div class="form-grid">
|
||||
<label><span>数据源名称</span><input id="newSourceName" required placeholder="例如:区域人才招聘平台" /></label>
|
||||
<label><span>来源类别</span><select id="newSourceCategory"><option value="commercial">商业招聘平台</option><option value="public">公共就业平台</option><option value="school">校内业务系统</option></select></label>
|
||||
<label class="full"><span>入口域名或接口地址</span><input id="newSourceDomain" required placeholder="https://example.com/jobs" /></label>
|
||||
<label><span>接入方式</span><select id="newSourceMode"><option>网页采集器</option><option>官方 API</option><option>授权数据包</option><option>数据库视图</option><option>标准文件导入</option></select></label>
|
||||
<label><span>目标契约</span><select id="newSourceContract"><option>JOB-SIGNAL V3.0</option><option>SCHOOL-EMPLOYMENT V2.2</option><option>SCHOOL-INTERNSHIP V2.1</option></select></label>
|
||||
<label><span>更新频率</span><select id="newSourceSchedule"><option>每 6 小时</option><option>每日 02:00</option><option>每周一</option><option>人工触发</option></select></label>
|
||||
<label><span>技术负责人</span><input id="newSourceOwner" value="平台采集工程组" /></label>
|
||||
<label class="full"><span>采集范围</span><textarea id="newSourceScope" rows="3">全国 · 应届生与实习岗位 · 重点产业岗位族</textarea></label>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="button secondary" data-close-modal>取消</button>
|
||||
<button type="submit" class="button primary">注册并创建连接测试</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" id="jobModal" aria-hidden="true">
|
||||
<section class="modal" role="dialog" aria-modal="true" aria-labelledby="jobModalTitle">
|
||||
<button class="modal-close" data-close-modal aria-label="关闭">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
<span class="modal-kicker">COLLECTION JOB</span>
|
||||
<h2 id="jobModalTitle">新建采集任务</h2>
|
||||
<p>选择来源、范围和运行策略,任务会先进行小样本预检,再进入生产队列。</p>
|
||||
<form id="jobForm">
|
||||
<div class="form-grid">
|
||||
<label><span>任务名称</span><input id="jobName" required value="重点产业岗位增量采集" /></label>
|
||||
<label><span>数据源</span><select id="jobSource"></select></label>
|
||||
<label><span>地域范围</span><input id="jobRegion" value="杭州、宁波、嘉兴、绍兴" /></label>
|
||||
<label><span>岗位范围</span><input id="jobScope" value="数字技术、智能制造、现代服务" /></label>
|
||||
<label><span>任务模式</span><select id="jobMode"><option>增量采集</option><option>初次全量</option><option>样本验证</option></select></label>
|
||||
<label><span>优先级</span><select id="jobPriority"><option>P1 标准</option><option>P0 紧急</option><option>P2 后台</option></select></label>
|
||||
<label><span>调度时间</span><select id="jobSchedule"><option>立即执行</option><option>下个调度窗口</option><option>每日 02:00</option></select></label>
|
||||
<label><span>失败策略</span><select><option>分片隔离,其他继续</option><option>任一失败则停止</option></select></label>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="button secondary" data-close-modal>取消</button>
|
||||
<button type="submit" class="button primary">创建并进入预检</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" id="infoModal" aria-hidden="true">
|
||||
<section class="modal compact-modal" role="dialog" aria-modal="true" aria-labelledby="infoModalTitle">
|
||||
<button class="modal-close" data-close-modal aria-label="关闭">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
<span class="modal-kicker" id="infoModalKicker">DETAIL</span>
|
||||
<h2 id="infoModalTitle">详情</h2>
|
||||
<div id="infoModalContent"></div>
|
||||
<div class="modal-actions"><button class="button primary" data-close-modal>完成</button></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script src="./app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 279 KiB |
|
After Width: | Height: | Size: 332 KiB |
|
After Width: | Height: | Size: 414 KiB |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 350 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 297 KiB |
|
After Width: | Height: | Size: 480 KiB |
|
After Width: | Height: | Size: 282 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 589 KiB |
|
After Width: | Height: | Size: 398 KiB |
@@ -0,0 +1,4 @@
|
||||
record_id,source_platform,source_record_id,source_url,collector_task_id,collector_version,raw_snapshot_id,collected_at,first_seen_at,last_seen_at,published_at,status,job_title_raw,job_title_normalized,job_code,job_description,enterprise_name,enterprise_id,region_code,workplace,employment_type,recruitment_count,education_level,experience_min_years,salary_min,salary_max,salary_currency,salary_period,skills,source_payload_hash,content_hash,parsing_version,normalized_at,data_version
|
||||
e5a87030-3c5f-4d74-a3ca-89427e2f75a1,BOSS,BOSS-20260823-884201,https://www.bosszhipin.com/job_detail/sample-884201.html,JOB-20260823-1042,BOSS-Collector-4.6.2,RAW-BOSS-20260823-000884,2026-08-23T10:42:18+08:00,2026-08-21T09:10:00+08:00,2026-08-23T10:42:18+08:00,2026-08-21T08:56:00+08:00,active,云原生开发工程师,云计算工程技术人员,IT.CLOUD.DEV,"负责容器平台应用开发、持续集成和服务可观测性建设。",杭州示例数字科技有限公司,ENT_7f40a90d45c72b18,330100,杭州市滨江区,full_time,6,bachelor,1,12000,18000,CNY,month,"Docker|Kubernetes|Java|CI/CD",4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32,96c2be742dc43f8e7ee526db6358030873406c450f15e67225c605dc39b431a8,PARSER-BOSS-4.6.2,2026-08-23T10:45:00+08:00,V2026.08.23
|
||||
57df68fe-2454-44d2-9f3d-20e91ac0912a,ZHAOPIN,ZL-20260823-620311,https://www.zhaopin.com/jobdetail/sample-620311.htm,JOB-20260823-1038,ZHAOPIN-Collector-3.8.1,RAW-ZHAOPIN-20260823-000620,2026-08-23T10:38:06+08:00,2026-08-22T14:20:00+08:00,2026-08-23T10:38:06+08:00,2026-08-22T14:05:00+08:00,active,工业视觉应用工程师,人工智能工程技术人员,AI.VISION.APP,"负责机器视觉方案部署、相机标定、缺陷检测模型优化和产线集成。",浙江示例智能装备股份有限公司,ENT_143c8d80f501e6a9,330200,宁波市鄞州区,full_time,4,associate,2,10000,16000,CNY,month,"Python|OpenCV|机器视觉|PLC",c2d8f733e6711219823110d7d35fdc5535f133ed60f60950f9dc78a228cb402d,66e102b99bf056868670ac971011740c6f66f62b86ea43cc66326ed9a0a5807e,PARSER-ZHAOPIN-3.8.1,2026-08-23T10:41:00+08:00,V2026.08.23
|
||||
62eaa80d-0b30-462b-8eca-c6c9bb5e8446,BRZP,BRZP-20260823-110028,https://brzp.chinasme.cn/brzp/job/sample-110028,JOB-20260823-0955,BRZP-Collector-2.1.0,RAW-BRZP-20260823-000110,2026-08-23T09:55:12+08:00,2026-08-23T01:42:00+08:00,2026-08-23T09:55:12+08:00,2026-08-22T18:00:00+08:00,active,跨境电商运营实习生,电子商务师,EC.CROSSBORDER.OPS,"协助店铺运营、海外内容制作、经营数据分析与合规资料整理。",浙江示例跨境服务有限公司,ENT_82b038ab219c4e80,330400,嘉兴市南湖区,internship,12,associate,0,3500,5000,CNY,month,"跨境电商|内容运营|数据分析|英语",a831bd0d4e29cab1e650f36a4fc9c5d5cc8053f560b5d3dc7aac62b384b47e11,310ae74d6d695235229da958f8fb8e59af6ea4bebef659dfdc1a6bc0764f3f30,PARSER-BRZP-2.1.0,2026-08-23T10:00:00+08:00,V2026.08.23
|
||||
|
@@ -0,0 +1,20 @@
|
||||
# 数据契约目录
|
||||
|
||||
所有契约使用 JSON Schema Draft 2020-12。
|
||||
|
||||
## 发布要求
|
||||
|
||||
1. 契约名称和版本必须唯一;
|
||||
2. 兼容变更提升次版本,修订说明或约束修复提升补丁版本;
|
||||
3. 删除字段、改变类型或收紧必填要求属于破坏性变更,必须提升主版本;
|
||||
4. 发布前执行历史样本回放、来源映射测试和下游影响分析;
|
||||
5. 交付包必须绑定精确契约版本,不允许只引用“最新版本”;
|
||||
6. Schema、样例、字段说明、代码字典和变更日志作为同一发布物。
|
||||
|
||||
## 当前契约
|
||||
|
||||
| 契约 | 版本 | 适用范围 |
|
||||
|---|---|---|
|
||||
| `JOB-SIGNAL` | 3.0.0 | 商业招聘平台、公共就业平台、活动聚合平台 |
|
||||
| `SCHOOL-EMPLOYMENT` | 2.2.0 | 学校就业管理系统、数据库视图、API和标准文件 |
|
||||
| `PACKAGE-MANIFEST` | 1.2.0 | 导入、导出、租户交付和归档;新增可选发布候选编号与状态 |
|
||||
@@ -0,0 +1,266 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.edu-industry.cn/job-signal/3.0.0/schema.json",
|
||||
"title": "JOB-SIGNAL V3.0 外部招聘岗位信号",
|
||||
"description": "商业招聘平台、公共就业平台与招聘活动平台统一岗位信号契约。",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"record_id",
|
||||
"source_platform",
|
||||
"source_record_id",
|
||||
"source_url",
|
||||
"collector_task_id",
|
||||
"collector_version",
|
||||
"raw_snapshot_id",
|
||||
"collected_at",
|
||||
"first_seen_at",
|
||||
"last_seen_at",
|
||||
"status",
|
||||
"job_title_raw",
|
||||
"job_description",
|
||||
"enterprise_name",
|
||||
"region_code",
|
||||
"employment_type",
|
||||
"source_payload_hash",
|
||||
"content_hash",
|
||||
"data_version"
|
||||
],
|
||||
"properties": {
|
||||
"record_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "平台生成的全局唯一记录标识。"
|
||||
},
|
||||
"source_platform": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z][A-Z0-9_]{1,31}$",
|
||||
"description": "来源平台代码,例如 BOSS、ZHAOPIN、BRZP、NCSS、MOHRSS。"
|
||||
},
|
||||
"source_record_id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 256,
|
||||
"description": "来源平台内的记录标识,与 source_platform 组成幂等键。"
|
||||
},
|
||||
"source_url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"maxLength": 2048,
|
||||
"description": "可回溯的来源页面或接口定位。"
|
||||
},
|
||||
"collector_task_id": {
|
||||
"type": "string",
|
||||
"pattern": "^JOB-[A-Za-z0-9-]{8,64}$",
|
||||
"description": "生产采集任务追踪编号。"
|
||||
},
|
||||
"collector_version": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128,
|
||||
"description": "采集器名称、语义版本与代码提交摘要。"
|
||||
},
|
||||
"raw_snapshot_id": {
|
||||
"type": "string",
|
||||
"pattern": "^RAW-[A-Za-z0-9-]{8,96}$",
|
||||
"description": "原始响应或页面快照编号。"
|
||||
},
|
||||
"collected_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "平台实际采集时间,必须包含时区。"
|
||||
},
|
||||
"first_seen_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "平台首次发现该岗位的时间。"
|
||||
},
|
||||
"last_seen_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "平台最近一次确认该岗位仍存在的时间。"
|
||||
},
|
||||
"published_at": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date-time",
|
||||
"description": "来源平台显示的岗位发布时间。"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["active", "inactive", "expired", "unknown"],
|
||||
"description": "岗位在当前数据版本中的状态。"
|
||||
},
|
||||
"job_title_raw": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 200,
|
||||
"description": "来源岗位名称原文。"
|
||||
},
|
||||
"job_title_normalized": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 200,
|
||||
"description": "映射到统一岗位词典后的标准名称。"
|
||||
},
|
||||
"job_code": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[A-Z0-9.-]{2,32}$",
|
||||
"description": "统一岗位分类代码。"
|
||||
},
|
||||
"job_description": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 30000,
|
||||
"description": "去除展示标记与联系方式后的岗位职责和要求文本。"
|
||||
},
|
||||
"enterprise_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 300,
|
||||
"description": "来源企业名称原文。"
|
||||
},
|
||||
"enterprise_id": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 128,
|
||||
"description": "平台企业归一标识。"
|
||||
},
|
||||
"enterprise_credit_code": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[0-9A-Z]{18}$",
|
||||
"description": "可公开确认时使用的统一社会信用代码。"
|
||||
},
|
||||
"enterprise_industry_code": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 32,
|
||||
"description": "企业所属行业代码。"
|
||||
},
|
||||
"enterprise_scale": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["micro", "small", "medium", "large", "unknown", null],
|
||||
"description": "统一企业规模分组。"
|
||||
},
|
||||
"region_code": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{6}$",
|
||||
"description": "GB/T 2260 六位行政区划代码。"
|
||||
},
|
||||
"workplace": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 500,
|
||||
"description": "来源工作地点文本。"
|
||||
},
|
||||
"employment_type": {
|
||||
"type": "string",
|
||||
"enum": ["full_time", "internship", "part_time", "contract", "campus", "other"],
|
||||
"description": "统一用工或招聘类型。"
|
||||
},
|
||||
"recruitment_count": {
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 1000000,
|
||||
"description": "明确披露时记录计划招聘人数。"
|
||||
},
|
||||
"education_level": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["none", "secondary", "vocational", "associate", "bachelor", "master", "doctor", "unknown", null],
|
||||
"description": "最低学历要求。"
|
||||
},
|
||||
"experience_min_years": {
|
||||
"type": ["number", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 60,
|
||||
"description": "最低工作经验年限。"
|
||||
},
|
||||
"salary_min": {
|
||||
"type": ["number", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 10000000,
|
||||
"description": "统一折算后的税前月薪下限,单位为 salary_currency。"
|
||||
},
|
||||
"salary_max": {
|
||||
"type": ["number", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 10000000,
|
||||
"description": "统一折算后的税前月薪上限。"
|
||||
},
|
||||
"salary_currency": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[A-Z]{3}$",
|
||||
"description": "ISO 4217 币种代码,境内岗位通常为 CNY。"
|
||||
},
|
||||
"salary_period": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["month", "year", "day", "hour", "negotiable", "unknown", null],
|
||||
"description": "来源薪资周期,统一月薪字段与原始周期同时保留。"
|
||||
},
|
||||
"benefits": {
|
||||
"type": "array",
|
||||
"maxItems": 100,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
},
|
||||
"uniqueItems": true,
|
||||
"description": "福利标签。"
|
||||
},
|
||||
"skills": {
|
||||
"type": "array",
|
||||
"maxItems": 200,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
},
|
||||
"uniqueItems": true,
|
||||
"description": "基于技能词典提取并归一的技能标签。"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "array",
|
||||
"maxItems": 200,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
},
|
||||
"uniqueItems": true,
|
||||
"description": "用于检索的业务关键词。"
|
||||
},
|
||||
"source_payload_hash": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "原始响应载荷 SHA-256。"
|
||||
},
|
||||
"content_hash": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "规范化业务内容 SHA-256,用于内容去重。"
|
||||
},
|
||||
"parsing_version": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 128,
|
||||
"description": "解析规则版本。"
|
||||
},
|
||||
"normalized_at": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date-time",
|
||||
"description": "岗位和技能归一完成时间。"
|
||||
},
|
||||
"data_version": {
|
||||
"type": "string",
|
||||
"pattern": "^V[0-9]{4}\\.[0-9]{2}\\.[0-9]{2}(?:\\.[0-9]+)?$",
|
||||
"description": "进入分析层的数据版本。"
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"required": ["salary_min", "salary_max"]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"salary_max": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.edu-industry.cn/package-manifest/1.2.0/schema.json",
|
||||
"title": "PACKAGE-MANIFEST V1.2 数据交付包清单",
|
||||
"description": "数据导入、导出和租户交付使用的版本、范围、文件、质量与血缘清单。",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"manifest_version",
|
||||
"package_id",
|
||||
"data_product",
|
||||
"data_version",
|
||||
"contract_name",
|
||||
"contract_version",
|
||||
"data_as_of",
|
||||
"tenant_scope",
|
||||
"record_count",
|
||||
"quality_score",
|
||||
"lineage_snapshot",
|
||||
"files",
|
||||
"generated_at",
|
||||
"generated_by"
|
||||
],
|
||||
"properties": {
|
||||
"manifest_version": {
|
||||
"type": "string",
|
||||
"const": "1.2.0"
|
||||
},
|
||||
"package_id": {
|
||||
"type": "string",
|
||||
"pattern": "^EDU-PKG-[0-9]{8}-[A-Z0-9]{2,24}$",
|
||||
"description": "数据交付包唯一编号。"
|
||||
},
|
||||
"release_id": {
|
||||
"type": "string",
|
||||
"pattern": "^REL-[0-9]{8}-[A-Z0-9-]{2,32}$",
|
||||
"description": "生成此 Manifest 的发布候选编号。"
|
||||
},
|
||||
"release_status": {
|
||||
"type": "string",
|
||||
"enum": ["DRAFT", "PENDING_APPROVAL", "APPROVED", "REJECTED", "PUBLISHED", "ROLLED_BACK"],
|
||||
"description": "Manifest 生成时的候选或发布状态。"
|
||||
},
|
||||
"data_product": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 200,
|
||||
"description": "平台数据产品名称或代码。"
|
||||
},
|
||||
"data_version": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128,
|
||||
"description": "业务数据版本。"
|
||||
},
|
||||
"contract_name": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z][A-Z0-9-]{2,63}$",
|
||||
"description": "绑定的数据契约名称。"
|
||||
},
|
||||
"contract_version": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
|
||||
"description": "精确的数据契约版本。"
|
||||
},
|
||||
"data_as_of": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"description": "交付数据业务截止日期。"
|
||||
},
|
||||
"tenant_scope": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 10000,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128
|
||||
},
|
||||
"description": "允许接收此交付包的租户或数据范围代码。"
|
||||
},
|
||||
"output_format": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["parquet", "csv_utf8", "jsonl", "xlsx", null],
|
||||
"description": "主数据文件格式。"
|
||||
},
|
||||
"record_count": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "有效业务记录总数。"
|
||||
},
|
||||
"quality_score": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "与质量报告一致的综合质量评分。"
|
||||
},
|
||||
"quality_report_path": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 1024,
|
||||
"description": "质量报告在交付包中的相对路径。"
|
||||
},
|
||||
"lineage_snapshot": {
|
||||
"type": "string",
|
||||
"pattern": "^LINEAGE-[A-Z0-9-]{8,96}$",
|
||||
"description": "数据血缘快照编号。"
|
||||
},
|
||||
"previous_stable_version": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 128,
|
||||
"description": "上一稳定版本,用于回滚和版本对比。"
|
||||
},
|
||||
"files": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 10000,
|
||||
"items": {
|
||||
"$ref": "#/$defs/file"
|
||||
},
|
||||
"description": "交付包内全部文件和校验信息。"
|
||||
},
|
||||
"generated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "交付包生成时间。"
|
||||
},
|
||||
"generated_by": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128,
|
||||
"description": "生成任务、服务账号或操作人。"
|
||||
},
|
||||
"approval_reference": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 256,
|
||||
"description": "生产发布审批记录编号。"
|
||||
},
|
||||
"notes": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 4000,
|
||||
"description": "交付说明、限制和已知问题。"
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"file": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "media_type", "bytes", "sha256"],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"pattern": "^(?!/)(?!.*\\.\\.).+$",
|
||||
"maxLength": 1024,
|
||||
"description": "包内相对路径,不允许绝对路径和父目录穿越。"
|
||||
},
|
||||
"media_type": {
|
||||
"type": "string",
|
||||
"maxLength": 128,
|
||||
"description": "IANA 媒体类型。"
|
||||
},
|
||||
"bytes": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "文件字节数。"
|
||||
},
|
||||
"sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "文件 SHA-256 完整值。"
|
||||
},
|
||||
"record_count": {
|
||||
"type": ["integer", "null"],
|
||||
"minimum": 0,
|
||||
"description": "数据文件的记录数。"
|
||||
},
|
||||
"compression": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["none", "gzip", "zstd", "zip", null],
|
||||
"description": "文件压缩方式。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.edu-industry.cn/school-employment/2.2.0/schema.json",
|
||||
"title": "SCHOOL-EMPLOYMENT V2.2 校内就业事实",
|
||||
"description": "职业院校毕业生就业事实统一契约,采用租户隔离和身份最小化设计。",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"tenant_id",
|
||||
"record_id",
|
||||
"student_token",
|
||||
"cohort",
|
||||
"college_code",
|
||||
"program_code",
|
||||
"employment_status",
|
||||
"destination_type",
|
||||
"confirmed_at",
|
||||
"confirmation_role",
|
||||
"source_system",
|
||||
"source_record_id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"data_version",
|
||||
"content_hash"
|
||||
],
|
||||
"properties": {
|
||||
"tenant_id": {
|
||||
"type": "string",
|
||||
"pattern": "^TENANT-[A-Z0-9-]{4,64}$",
|
||||
"description": "学校租户标识,所有存储、任务和查询必须同时校验。"
|
||||
},
|
||||
"record_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "平台全局唯一记录标识。"
|
||||
},
|
||||
"student_token": {
|
||||
"type": "string",
|
||||
"pattern": "^STU_[A-Za-z0-9_-]{32,128}$",
|
||||
"description": "学校侧生成的学生不可逆令牌,禁止传输姓名、身份证和明文学号。"
|
||||
},
|
||||
"cohort": {
|
||||
"type": "integer",
|
||||
"minimum": 2000,
|
||||
"maximum": 2100,
|
||||
"description": "毕业届次。"
|
||||
},
|
||||
"college_code": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64,
|
||||
"description": "学校内部学院代码。"
|
||||
},
|
||||
"program_code": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9A-Z]{4,12}$",
|
||||
"description": "教育部职业教育专业目录代码。"
|
||||
},
|
||||
"class_code": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 64,
|
||||
"description": "学校内部教学班代码。"
|
||||
},
|
||||
"employment_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"employed",
|
||||
"self_employed",
|
||||
"further_study",
|
||||
"military",
|
||||
"flexible",
|
||||
"unemployed",
|
||||
"pending_confirmation"
|
||||
],
|
||||
"description": "统一就业状态。"
|
||||
},
|
||||
"destination_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"enterprise",
|
||||
"public_institution",
|
||||
"government",
|
||||
"further_study",
|
||||
"entrepreneurship",
|
||||
"military",
|
||||
"other"
|
||||
],
|
||||
"description": "毕业去向类型。"
|
||||
},
|
||||
"job_title": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 200,
|
||||
"description": "就业岗位业务原文。"
|
||||
},
|
||||
"job_code": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 32,
|
||||
"description": "映射到统一岗位词典后的岗位代码。"
|
||||
},
|
||||
"enterprise_token": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^ENT_[A-Za-z0-9_-]{24,128}$",
|
||||
"description": "企业统一标识令牌。"
|
||||
},
|
||||
"enterprise_name": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 300,
|
||||
"description": "用于业务核验的企业名称;导出时按数据范围策略处理。"
|
||||
},
|
||||
"enterprise_industry_code": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 32,
|
||||
"description": "企业行业代码。"
|
||||
},
|
||||
"region_code": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[0-9]{6}$",
|
||||
"description": "就业地区 GB/T 2260 六位代码。"
|
||||
},
|
||||
"salary_monthly": {
|
||||
"type": ["number", "null"],
|
||||
"minimum": 0,
|
||||
"maximum": 10000000,
|
||||
"description": "确认后的税前月薪,单位元。"
|
||||
},
|
||||
"salary_confirmed": {
|
||||
"type": ["boolean", "null"],
|
||||
"description": "薪资是否经过业务确认。"
|
||||
},
|
||||
"job_relevance": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["high", "medium", "low", "unconfirmed", null],
|
||||
"description": "就业岗位与专业培养方向相关度。"
|
||||
},
|
||||
"employment_start_date": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date",
|
||||
"description": "就业开始日期。"
|
||||
},
|
||||
"contract_signed": {
|
||||
"type": ["boolean", "null"],
|
||||
"description": "是否签署就业协议或劳动合同。"
|
||||
},
|
||||
"evidence_type": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["contract", "offer", "registration", "enterprise_confirmation", "student_confirmation", "other", null],
|
||||
"description": "就业确认材料类型,不在平台保存原始敏感附件。"
|
||||
},
|
||||
"evidence_reference": {
|
||||
"type": ["string", "null"],
|
||||
"maxLength": 256,
|
||||
"description": "学校系统内的材料引用编号。"
|
||||
},
|
||||
"confirmed_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "业务确认时间。"
|
||||
},
|
||||
"confirmation_role": {
|
||||
"type": "string",
|
||||
"enum": ["employment_office", "college", "student", "enterprise", "system"],
|
||||
"description": "执行确认的业务角色。"
|
||||
},
|
||||
"source_system": {
|
||||
"type": "string",
|
||||
"maxLength": 128,
|
||||
"description": "学校来源系统代码。"
|
||||
},
|
||||
"source_record_id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 256,
|
||||
"description": "校内来源系统记录标识。"
|
||||
},
|
||||
"source_updated_at": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date-time",
|
||||
"description": "校内来源系统业务更新时间,建议作为增量水位。"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "平台记录创建时间。"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "平台记录更新时间。"
|
||||
},
|
||||
"data_version": {
|
||||
"type": "string",
|
||||
"pattern": "^SCH-EMP-[0-9]{8}(?:-[0-9]{2})?$",
|
||||
"description": "校内就业数据版本。"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "版本化软删除标识。"
|
||||
},
|
||||
"content_hash": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "去除非业务差异后的记录内容 SHA-256。"
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"destination_type": {
|
||||
"const": "enterprise"
|
||||
}
|
||||
},
|
||||
"required": ["destination_type"]
|
||||
},
|
||||
"then": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": ["enterprise_token"]
|
||||
},
|
||||
{
|
||||
"required": ["enterprise_name"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||