Commit 638d27fb by luoqi

docs(integration): FRIDAY 推送数据契约 — 形态 A 的 15 个 source 字段定义

Push 通道形态 A 在 FRIDAY 宿主的具体化:每个 source 的 JSON 字段清单(类型/必填/语义),
形状与已验证的存量摄入(10.7 万患者/36 万事实)完全一致 → 宿主按此推送与存量无缝衔接
(幂等去重/版本演进/重叠无害)。

- 通用约定:id 一律字符串(存量实测坑)/updated_gmt_at 必须 bump(幂等键一半)/
  brand_id=源 tenant_id 改名/at-least-once
- 患者关系 3 source(含 upsert 主体待 PAC 排期的如实标注)/预约/病历链 3(含 diag/treat
  数组元素结构与 status∈{3,4} 推送范围)/结算链 4(status 拆分规则钉死)/计划咨询 3
- 待 FRIDAY 确认清单:两套关系码枚举/treat 语义/结算剩余 status

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
parent 9059386b
---
title: FRIDAY 推送数据契约
description: FRIDAY SaaS 按形态 A 推送的 15 个 source 及字段定义;与已验证的存量导出形状一致,push 无缝衔接。
icon: FileJson
---
> 本文是 [Push 通道](/docs/integration/channel-push)**形态 A** 在 FRIDAY SaaS 宿主的具体化:每个 `source` 的 JSON 字段清单。
> 字段形状与 PAC 已完成的存量摄入(2026-07,10.7 万患者 / 36 万事实)**完全一致**——宿主按此推送,与存量自动衔接:
> 同行同 `updated_gmt_at` 幂等去重,行更新(`updated_gmt_at` 变)自动版本演进。**重叠无害,宁多勿漏**。
---
## 1. 通用约定(所有 source 适用)
```jsonc
// POST /pac/v1/push/rows
{
"source": "med_emr_info", // 本文各节的 source 名
"rows": [ { /* 原生行,字段见各节 */ } ]
}
```
| 约定 | 说明 |
|---|---|
| **id 类字段一律字符串** | `patient_id` / `id` / `appointment_id` 等统一 String(数值型会被 PAC 校验拒收——存量摄入实测踩过的坑) |
| **时间格式** | `"YYYY-MM-DD HH:mm:ss"` 或 ISO8601;裸时间按 `Asia/Shanghai` 解释 |
| **`brand_id`** | = FRIDAY 源库的 `tenant_id` 列**改名**(避免与 PAC 租户概念撞名)。品牌 GUID,PAC 用它做集团内患者号消歧 |
| **`updated_gmt_at` 必须随行更新 bump** | 它是幂等键的一半:不 bump,该行的更新会被永久去重丢弃 |
| **空值** | 传 `null` 或省略字段;不要传 `"NULL"` 字符串 |
| **金额单位** | 元(decimal 原值);PAC 侧转分 |
| **投递语义** | at-least-once:未收到 2xx 确认就重推;重复由 PAC 幂等键吸收 |
---
## 2. 患者与关系(3 个 source)
### `customer_basic_info` — 患者主档
> ⚠️ 患者是 upsert 主体,push 通道对 upsert 主体的支持在 PAC 侧排期中;开通前患者主档走存量全量通道(周期性全表推送/导出均可,幂等覆盖)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 患者主键(= PAC externalId;其他表 `patient_id`/`customer_id` 指向它) |
| `name` | string | | 姓名 |
| `sex` | string | | `1`=男 `2`=女,其余置空 |
| `birthday` | string(date) | | 生日 |
| `file_number` | string | | 病历号/档案号(客服沟通用) |
| `brand_id` | string | ✅ | 品牌 GUID(源 tenant_id) |
| `organization_id` | string | | 建档诊所 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | 建档/更新时间 |
### `customer_contacts` — 联系方式(1:N)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 行主键 |
| `customer_id` | string | ✅ | → 患者 id |
| `contacts_tel` | string | ✅ | 电话号码 |
| `is_default` | string/number | | 默认号标记(PAC 挑默认号:is_default↓ → contacts_type↑ → id↑) |
| `contacts_type` | string/number | | 联系类型(`1` 本人号候选优先) |
| `tel_type` | string/number | | 号码类型 |
| `relationship` | string/number | | 该号与患者的关系码(1-9;**枚举定义待 FRIDAY 提供**,现 PAC 按 `1`=本人判定本人号/代接号) |
### `customer_referee_circle` — 转介绍圈(患者-患者关系)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 行主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `organization_id` | string | | 诊所 |
| `customer_id` | string | ✅ | 本人患者 id |
| `referee_patient_id` | string | ✅ | 关系人患者 id(也是在册患者) |
| `referee_relationship` | string/number | | 关系字典 id(**官方枚举待 FRIDAY 提供**;现 PAC 按统计推断解码,如 1=配偶/3=父母/8=朋友) |
| `type` | string/number | | 关系类型标记 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | | |
---
## 3. 预约(1 个 source)
### `appointment_base` — 预约(全状态推,PAC 侧过滤)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 预约主键 |
| `patient_appointment_id` | string | ✅ | → 患者 id |
| `organization_id` | string | ✅ | 诊所 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `appointment_date` | string(date) | ✅ | 预约日期 |
| `appointment_start` | string(time) | ✅ | 开始时刻(与 date 拼成预约时刻) |
| `appointment_status` | string | ✅ | `1`正常 `2`改约 `3`取消 `4`到诊 `5`接诊 `6`结算 `8`walkin `9`爽约;`10`草稿(推了也会被 PAC 丢弃) |
| `doctor_user_id` | string | | 医生 id |
| `appointment_time_length` | string/number | | 时长(分钟) |
| `in_time` | string(datetime) | | 到诊时刻(状态 4/5/6 时,PAC 据此产接诊事件) |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
---
## 4. 病历链(3 个 source)
### `med_emr_info` — 病历正文(Mongo 平铺;一张表喂诊断/治疗/建议/复查/病历全链)
**推送范围:`status ∈ {3, 4}`(已完成/归档);`status=2` 未完成草稿不推。**
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `emr_sub_id` | string | ✅ | 小病历号 uuid(病历主键;临床事实同诊聚合锚) |
| `emr_id` | string | ✅ | 病历号(如 `JY0A000231`;影像 `med_check.emr_id` 指向它) |
| `appointment_id` | string | | 关联预约 id(有则挂回预约链) |
| `brand_id` | string | ✅ | 品牌 GUID(源 tenantId) |
| `organization_id` | string | ✅ | 诊所 |
| `patient_id` | string | ✅ | → 患者 id |
| `user_id` / `user_name` | string | | 接诊医生 id / 姓名 |
| `clinic_time` | string(datetime) | ✅ | 就诊时刻 |
| `visit_indicator` | number | | `1`初诊 `2`复诊 |
| `status` | number | ✅ | `3`已完成 `4`归档(推送范围) |
| `diag` | array | | 诊断数组,元素 `{ "toothPosition": "41;42", "value": "慢性牙髓炎", "linkCode": "<std_diag.diag_code 或空>" }` |
| `treat` | array | | 本次治疗数组,元素同上结构(`value`=治疗名) |
| `dispose` | array | | 处置叙述数组,元素 `{ "toothPosition", "value" }` |
| `examine` | array | | 检查所见数组,元素同上 |
| `dispose_text` / `examine_text` | string | | 上两数组的 JSON 字符串形态(病历自由文本位;数组非空时必带) |
| `illness_desc` | string | | 主诉 |
| `pre_illness` / `past_hist` / `gen_cond` | string | | 现病史 / 既往史 / 全身情况 |
| `auxi_exam` | string | | 辅助检查 |
| `doc_order` | string | | 医嘱 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
> 牙位格式:FDI 牙位号,多牙分号分隔,可带牙面字母(`"42 L;43 D"` / `"11;12;13"`)。
### `std_diag` — 诊断字典(低频;变更时全量重推)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `diag_code` | string | ✅ | 字典主键(= `diag[].linkCode` 指向) |
| `diag_name` | string | ✅ | 诊断名 |
| `std_code` | string | | 标准码(`K02.901` 等;K 开头 PAC 截 K 大类,非 K 按自由文本处理) |
### `med_check` — 影像档案(metadata,不含文件本体)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 行主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `organization_id` | string | ✅ | 诊所 |
| `patient_id` | string | ✅ | → 患者 id |
| `emr_id` | string | | → 病历号(`med_emr_info.emr_id`) |
| `class_code` | string | | 影像类型 → `std_check_class` |
| `file_name` / `file_type` | string | | 文件名 / 类型 |
| `file_url` | string | | OSS 相对路径 |
| `files_size` | number | | 字节数 |
| `shooting_time` | string(datetime) | ✅ | 拍摄时间 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
配套字典 **`std_check_class`**(低频):`class_code`(主键) / `class_name`(口内像照片、小牙片、全景片…) / `brand_id`。
---
## 5. 结算链(4 个 source)
> **拆分规则(宿主侧按 status/金额分流成两个 source 推)** —— 语义 2026-07 与 PAC 联合钉死:
> `status`:`1`=已结算 `3`=含退费行的单 `4`=整单反向冲减。
### `patient_settlement` — 消费单
**推送范围:`status ∈ {1, 3}` 且 `receivable_this >= 0`。**
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `uuid` | string | ✅ | 结算单主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `organization_id` | string | ✅ | 诊所 |
| `patient_id` | string | ✅ | → 患者 id |
| `doctor_id` | string | | 开单医生 |
| `status` | string/number | ✅ | 见上 |
| `receivable_this` | number(元) | ✅ | 应收(PAC 计患者价值/LTV 用) |
| `net_receipts_this` | number(元) | | 实收 |
| `billing_date` | string(datetime) | | 开单时间 |
| `registration_id` | string | | 关联接诊号 |
| `ref_settlement_id` | string | | (消费单一般为空) |
| `settlement_serial_num` | string | | 结算流水号 |
| `reason` | string | | 备注/原因 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
### `patient_settlement_refund` — 整单退费
**推送范围:`status = 4` 或(`status = 3` 且 `receivable_this < 0`)。** 字段同 `patient_settlement`;其中:
- `net_receipts_this` 负值 = 冲减金额(PAC 取绝对值)
- `ref_settlement_id` = **被退的原结算单 uuid**(status=4 必带;PAC 据此把退费挂回原消费)
### `patient_settlement_spec_refund` — 行级部分退费
**推送范围:结算明细行中 `is_refund = 1` 的行。**
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 明细行主键 |
| `brand_id` / `organization_id` / `patient_id` | string | ✅ | 同上 |
| `settlement_id` | string | ✅ | 所属结算单 uuid(退费挂回原消费) |
| `cure_name` / `service_project_name` | string | | 被退项目名 |
| `receivable_this` / `net_receipts_this` | number(元) | ✅ | 被退金额(正值) |
| `is_refund` | string/number | ✅ | 恒为 `1` |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
### `settlement_modes` — 支付通道明细(每单×通道一行)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 行主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `settlement_id` | string | ✅ | → 结算单 uuid |
| `modes_name` | string | ✅ | 通道名(现金支付/微信支付/刷卡支付/医保支付…原样即可) |
| `money` | number(元) | ✅ | 该通道金额(PAC 取金额最大者为主导通道) |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | | |
---
## 6. 治疗计划与咨询(3 个 source)
### `customer_treat_plan` — 治疗计划(头)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 计划主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `organization_id` | string | ✅ | 诊所(**行项靠头表拿诊所,缺失该行会被丢弃**) |
| `customer_id` | string | ✅ | → 患者 id |
| `plan_group_id` / `plan_group_num` | string | | 方案分组(多方案对比) |
| `plan_name` | string | | 方案名 |
| `desired_effect` / `emergency_urgency` | string/number | | 期望效果 / 紧迫度 |
| `expect_cost` | string | | 期望费用 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
### `customer_treat_plan_item` — 治疗计划(行)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 行主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `customer_id` | string | ✅ | → 患者 id |
| `treat_plan_id` | string | ✅ | → 计划头 id |
| `tooth_position` | string | | 牙位 |
| `mode_name` | string | ✅ | 术式名(PAC 翻 11 类治疗类别) |
| `charge_min` / `charge_max` | number(元) | | 价格区间 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
### `customer_consult` — 咨询
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | string | ✅ | 咨询主键 |
| `brand_id` | string | ✅ | 品牌 GUID |
| `organization_id` | string | ✅ | 诊所 |
| `customer_id` | string | ✅ | → 患者 id |
| `task_director_id` / `task_director` | string | | 跟进人 id / 姓名 |
| `treatment_plan` | string | | 咨询中聊到的治疗方案 |
| `preferential_way` | string | | 优惠方式 |
| `unsettled_reason` | string | | **未成交原因**(强召回信号) |
| `unsettled_reason_description` | string | | 未成交原因补充 |
| `other_conditions` | string | | 其他情况 |
| `potential_treatment` | string | | 患者意向(潜在治疗) |
| `data_sources` | string/number | | 数据来源标记 |
| `created_gmt_at` / `updated_gmt_at` | string(datetime) | ✅ | |
---
## 7. 待 FRIDAY 确认清单
| 项 | 现状 | 需要 |
|---|---|---|
| `customer_contacts.relationship` 1-9 枚举 | PAC 按 `1`=本人统计推断 | 官方字典定义 |
| `customer_referee_circle.referee_relationship` 字典 | PAC 统计推断(配偶/父母/子女/朋友…) | 官方字典定义 |
| `med_emr_info.treat` vs `dispose` 语义 | 按 treat=本次治疗、dispose=处置叙述摄入 | 业务复核确认 |
| `patient_settlement.status` 0/2/5/6/7/8 语义 | 暂不摄入 | 枚举说明(决定是否纳入) |
| 患者主档 push(upsert 主体) | 走存量全量通道 | PAC 侧排期支持后切 push |
......@@ -8,6 +8,7 @@
"channel-rest",
"channel-clickhouse",
"channel-push",
"friday-push-payload",
"auth-login",
"execution-callback",
"runbook"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment