分组
法国PMSI(英语:Programme de Médicalization des Systèmes d'Information)中使用的官方ATIH分组引擎的节点js包装.
这个软件包可以将本地的C类组群模块整合起来,将住院时间分类为: 德国 (Homogène de Malades集团)和 全球统一制度 (Groupe Homogène de Séjours)代码,符合法国的T2A计费制度.
概览
本项目使用 : 节点- API 来包装官方的 ATIH 分组引擎。 分组引擎是法国医疗系统计费和分类基础设施的重要组成部分.
法国医学编码背景
法国的卫生保健系统使用PMSI(信息系统医疗方案),在T2A(Tadization Àl'Activité)系统下进行医疗活动编码和医院收费。 这个项目具体解决了将医疗停留自动分为标准化类别的必要性.
关于法国分组算法和医学编码的综合背景,请参见此 详细概览。 。 。 .
技术架构
该套装包括:
- 原产地 C/C++ 模块: 核心 ATIH 分组引擎
atih/文件夹(参见 doc/atih/分组 方法.md(中文(简体) ) - Java脚本接口:高级节点js API in
src/将 JS 对象转换为 ATIH RSS 字符串并解析本地结果 - 类型定义: 用于发展支持的脚本类型定义
- 运行时间数据: ATIH 参考表,随包一起运出
tables/V2024, (中文(简体) ),tables/V2025, (中文(简体) ),tables/V2026
仓库布局
| 路径 | 目的 |
|---|---|
atih/ | ATIH分组引擎的原生C源(grouping/)和FICUM控制模块(ficum/(中文(简体) ) |
src/ | 类型脚本 API : exports/ (公共职能+类型), utils/ (RUM型号,022/023格式序列器,enums) |
tables/V{2024,2025,2026}/ | ATIH 按年在运行时间装入的参考表格 |
atih/smr/, (中文(简体) ), tables/SMR/{2025,2026}/, (中文(简体) ), lib/SMR/ | FG SMR: ATIH 源 (未修改), N- API 包装器, 二进制表格, 标签文件(参见 FG 工管关系(中文(简体) ) |
lib/, (中文(简体) ), txt/ | 支持 ATIH 数据文件 |
doc/ | ATIH 格式规格和出版的运行本 |
tools/grouping-fixtures/ | 从AlphaCode API中获取确定性测试固定装置的工具(见它 读取(中文(简体) ) |
src/tests/fixtures/ | 已捕获 .case.json 组合测试套件所主张的固定装置 |
本地引擎加载相对于 软件包根 (通过
require.resolve('@beparallel/grouping/package.json')),而不是消费应用程序的工作目录. 这个tables/, (中文(简体) ),lib/,以及txt/文件夹是已出版的 tarball (files内package.json) (中文(简体) ).
公共 API
软件包的切入点导出分组函数、错误模型和所有类型:
import {
grpMco, // grpMco(input) picks the engine from the discharge dates; grpMco(input, { edition }) forces one
selectMcoEdition,
MCO_EDITIONS,
McoEngineUnavailableError,
grp, // deprecated: like grpMco(input), but silently falls back to 2026
grp2024,
grp2025,
grp2026,
GroupingError,
BlockingErrorGroup,
RUMEnums // TYPE_ETAB, RUM_ENTRY_MODE, RUM_EXIT_MODE, ...
} from '@beparallel/grouping'
导入包装入没有本地加通: 每个 .node 文件被第一个需要它的呼叫所装入,一个缺失的被丢到那里,它的预期路径在下面 build/Release/ 以及如何获得pnpm prebuild:install 或者说 pnpm build:c:native) (中文(简体) ).
这个 RUMObject 财务报告和审定财务报表 TYPE_ETAB 用于构建输入的类型也可以从生成的类型路径中获取(这就是 AlphaCode 如何构建的) valuation 服务进口:
import type { RUMObject } from '@beparallel/grouping/dist/types/utils'
编辑选择 : grpMco
grpMco(input, options?) 第一组保留一个FG MCO版MCO_EDITIONS =: '2024', (中文(简体) ), '2025', (中文(简体) ), '2026')返回引擎的结果+ engineYear (单位:千美元)2024 | 2025 | 2026,运行的引擎;类型 GrpMcoResult:
grpMco(input, { edition: '2025' })运行精确grp2025(input)不论出院日期如何 外边的版本MCO_EDITIONS(单位:千美元)'2027',数字... )McoEngineUnavailableError。 。 。 .grpMco(input)运行selectMcoEdition(input.rumObjects): 第一个 2026, 2025, 2024 (英语) 结束 任意 卢姆exitDate(单位:千美元)DDMMYYYY; RUM 无exitDate(见注5) 两年内与退伍日期有关的缓期执行是最新的(31122025+ 键02012026→'2026') (中文(简体) ). 当卸货日期与发货版本不符时(完全没有,或2023, (中文(简体) ),2027...,它抛出McoEngineUnavailableError指定所看到的日期和已发运的版本.selectMcoEdition(rumObjects)被导出,以便调用者能够在分组前知道(或日志)版本,而无需重新执行规则.- 输入由
GrpMcoInputSchema(zod,严格在上层:{ rumObjects, typeEtab }1至99卢比);aZodError否则会被扔出去。 RUM 字段由引擎检查(error code),和以前一样.
每版将 RUM 序列化为自己的格式: 023 (英语) 用于2026年, 022 (英语) 2025年和2024年的拨款. grp2024 编号 : grp2025 编号 : grp2026 仍可使用,也可返回 engineYear。 。 。 .
grp(input) 实值 已贬值: 它适用与 grpMco(input) 但是,当没有放出日期匹配时,记录一个控制台警告并默默运行2026引擎. 它维持现有呼叫者的行为 grpMco(input) (或 grpMco(input, { edition })相反.
投入
所有分组函数都取由 Zod 验证的单个对象 :
interface GroupingInput {
rumObjects: RUMObject[] // one or more Résumés d'Unité Médicale
typeEtab: TYPE_ETAB // 1 = PUBLIC_HOSPITAL (ex-DGF), 2 = PRIVATE_HOSPITAL (ex-OQN)
}
A 类 RUMObject 镜像 ATIH RSS 线条。 日期为 DDMMYYYY 字符串;诊断是CIM-10代码; ZAs 是CCAM的动作行。 一个真实( 抓取) 的例子 :
const input = {
typeEtab: 1, // PUBLIC_HOSPITAL
rumObjects: [
{
FINESS: '511928447',
RSS: '22676886701954659349',
RUM: '7319798297',
birthDate: '22011959',
sex: '1',
uMed: 'RAC',
entryDate: '19122025',
entryMode: '8',
exitDate: '22122025',
exitMode: '8',
nDA: 2,
nZA: 5,
DP: 'G553', // principal diagnosis
DAs: ['M4806', 'E6694'], // associated diagnoses
ZAs: [
// CCAM acts
{ date: '19122025', code: 'LFFA001', phase: '0', act: '1', mod: 'JK', AN: '1', qty: '1' },
{ date: '19122025', code: 'LFAA002', phase: '0', act: '4', diag: '1', AN: '2', qty: '1' }
]
}
]
}
const result = grpMco(input) // → 2025 engine (2025 discharge), result.engineYear === 2025
整个球场在 RUMObjectSchema (单位:千美元)src/utils/类型/rum.types.ts; 桶(出入境方式、性别、RAAC等) src/utils/类型/rum.enum.ts 和再出口为 RUMEnums对于更为完整的案例,请浏览以下所记录的案件: 弧/测试/固定/。 。 。 .
产出
每个函数都返回一年的具体结果(Grp2024Result 编号 : Grp2025Result 编号 : Grp2026Result,参见 市场/出口/类型/),加 (中文(简体) ) engineYear,形状像:
interface Grp2026Result {
engineYear: 2026 // engine that ran (2024 | 2025 | 2026)
returnCode: number // raw ATIH return code
returnError: GroupingError | null // mapped error (null when grouping succeeded)
grp_res: {
// classification result
cmd: string // Catégorie Majeure de Diagnostic
ghm: string // Groupe Homogène de Malades
version: string
cret: string
}
ghs_val: { ghs: string /* + supplement/billing counters */ }
rss_inf: { agea: number; dstot: number /* + diag/act lists, signatures */ }
}
错误模式
当引擎无法分组时, 它返回一个非零 returnCode,它被映射为 GroupingError 通过词典 市场/出口/管理不当/集团-管理不当数字 :
interface GroupingError {
code: number
errorName: string
scope: string | null
blockingErrorGroup: BlockingErrorGroup | null // 90Z00Z, 90Z01Z, 90Z02Z, 90Z03Z
description: string
}
BlockingErrorGroup 区分强制控制错误与组-1/组-2阻塞错误和FG执行错误. 关于成功, returnError 实值 null 财务报告和审定财务报表 returnCode 实值 0。 。 。 .
FG SMR(医学和适应学院)
包件还包了 ATIH FG 工管关系 (分发) SourcesFGSMR2026_15,它搭载了2025和2026引擎). 留宿是周刊的套间 生殖健康; 引擎返回 a 格林尼治平时 (例如:. 0871UC1翻译: 0871,重新调整级别 U,重度级别 C严重性 1)和a 数据 格林尼治标准时 (关税类,例如:. 0858· ; 9999 = 未估值).
import { grpSmr, grpSmr2025, grpSmr2026, RHSObject, TYPE_ETAB, toSmrWeek } from '@beparallel/grouping'
const result = grpSmr({ rhsObjects: weeks /* RHSObject[], one per week, sorted */, typeEtab: TYPE_ETAB.PUBLIC_HOSPITAL })
result.gme // '0871UC1' (HC stays; HTP stays: per RHS in result.rhs[i].htp)
result.gmt // '0858'
result.severity // 1
result.returnCode // 0, or the smallest blocking error code (HTP: smallest non-zero rhs[i].returnCode)
result.returnError // SmrGroupingError | null (label from LIBERR.TXT)
result.rhs // per-week rows: GME, return code, errors, 90-day threshold position, weekly GMT...
- 投入数字 :
RHSObject编号 :RHSObjectSchema(单位:千美元)斜弧/斜角/斜角/斜角/斜角/斜角)是一个RHS的命名域模型,序列化为固定宽度 M0D 软件 格式 (单位:千美元)m0d-格式图每个字段的M0D位置都在它的JSDoc. 日期为DDMMYYYY· ;weekNumber实值WWYYYY(ISO周+ISO年,见toSmrWeek()(三);presenceDays是 7× 个0/1,星期一至星期日; CIM-10 代码不写出点。 输入用 zod 验证(GrpSmrInputSchema,严格:未知密钥为出错; 1smrStayNumber,周排序,38,210-特征引擎缓冲器内的每行;医学有效性作为引擎出错代码回来. - 引擎选择数字 :
grpSmr2025编号 :grpSmr2026强制引擎( r)annee_transmission=该年).grpSmr跟着ATIH的调度器fgsmrmain.c页:1 上次访问 决定HC vs HTP;HC去FG 2026,当其上个星期为01/2026,其他FG 2025,并在第90个存在日(或排出日)于01/01/2026之前被重新组合为FG 2025;HTP RHS跟随自己的一周(绕一周)01/2026) (中文(简体) ). 它会扔SmrEngineUnavailableError当 FG 2024 (前几周)09/2025)或需要FG 2027+.result.routing说哪条规则适用.grpSmr(input, { edition: '2025' | '2026' })强迫一个版本(结果与grpSmr2025编号 :grpSmr2026; 未在SMR_EDITIONS掷出SmrEngineUnavailableError而不是回到调度员。 2025版开始于ISO周09/2025(2025年2月24日星期一,日内瓦),SMR_FIRST_WEEK_2025在2025年竞选活动正式开始前一周(2025年3月3日星期一,第10周). - 估价:在自己的竞选活动中停留的每个部分.
grpSmr复制fgsmrmain.c用于路由,GMEE,还原代码,出错和每2026个值,但故意不用于2025个部分. ATIH的可执行性在2026年的传输模式下运行了FG 2025(英语:annee_transmission = 2026N -1重新集结的HC会报告GMT的停留9999从90天起,每周格林尼治标准时间9999前几周为零天01/2026; HTP RHS 2025周获得0个值日.grpSmr返回那里真实的 FG 2025 值(FG 2025 运行与annee_transmission = 2025在一个HTP 分裂的周01/2026页:1previousEditionValuation(加上该行自己的2026年估值). 定值价格(gmt, (中文(简体) ),hc关税:engineYear编号 :version,每星期格林尼治平时加收rhs[i].weeklyGmtEngineYear中,每行HTP的关税rhs[i].engineYear联合国previousEditionValuation那个部分engineYear2025年竞选时的账单.src/tests/grouping-smr-reference.test.ts比较grpSmr产出fgsmrmain.c和钉住这些差异. - 模式数字 :
mode: SmrGroupingMode.VALORISATION(违约,“第1组”,用于计费)或DESCRIPTION(“第2组”,GMED). - 原生边: 一个加词
grpsmr.node(两个引擎),与MCO加法分开;表格tables/SMR/<year>/。ATIH 文档下atih/smr/SRCV2025|SRCV2026可移植性处理于binding.gyp(见关于grpsmr目标)和atih/smr/compat/malloc.h,以及.gitattributes保持正常的CRLF线的结束。 引擎状态为 process-global:不要调用几个 SMR 函数worker_threads马上.
如何建造
构建管道有两个阶段:本土C编译和TypeScript编译. 预建二进制通过GitHub Releases发售,因此消费者不需要本地C工具链.
土著汇编
node-gyp 汇编定义的 ATIH C 源文件 binding.gyp 输入 .node 二进制加分. 确定了四个目标:
- 缩写 - FG MCO 2025 + 2026 在一个加法中(FG分布与 2025+ 2026 保持:
fgmco_2026+ SRCV2025/2026,一次编译),出口grp_2025_wrapper(使用时间:grp2025和grp_2026_wrapper(使用时间:grp2026) (中文(简体) ). 两种包装没有修改:grp_mco_2025_unit.c编号 :grp_mco_2026_unit.c编译每个Init重新命名及其编号NAPI_MODULE已删除,以及grp_mco_module.c注册模块。 (在此之前,同一来源曾两次连通,与grp2025.node财务报告和审定财务报表grp2026.node. ) (中文(简体) ) - grp2024 (英语) - 留下2024个
fgmco_2025+ SRCV2024/2025 (中文(简体) ) - grpsmr (英语) - FG SMR 2025 + 2026年(
atih/smr/,参见 FG 工管关系(中文(简体) ) - 事实 - FICUM控制模块(UM授权文件生成/验证)
以 :
pnpm build:c:native
类型脚本汇编
tsc 汇编 src/ 输入普通JS输出的目录 dist/,将类型声明发布到 dist/types/。 。 。 .
pnpm build:ts
地方发展
# Use the pinned Node version (.nvmrc → 24.14.0)
nvm use 24
pnpm install
# Install prebuilt native binaries. `prebuild:install` resolves them in this order:
# 1. If GITHUB_TOKEN is set -> download from the GitHub Release.
# 2. Otherwise -> extract a matching tarball committed under prebuilds/.
# 3. If neither works -> prints guidance to build from source.
pnpm prebuild:install
# Optional: only needed for the remote download path
# cp .env-example .env.dev # set GITHUB_TOKEN
# export GITHUB_TOKEN=... # token with access to the GitHub Releases
# ...or compile the native modules from source (needs python3, make, g++)
pnpm build:c:native
pnpm test
运行测试
测试需要首先编译本土C模块. 这个 pretest 脚本自动处理 :
pnpm test
这个运行 pnpm build:c:native (通过 pretest 钩子) jest。当 C 代码不变时跳过本地重建:
npx jest
只运行分组固定套件 :
pnpm test:fixtures
要运行特定测试文件 :
npx jest src/tests/grouping.test.ts
npx jest src/tests/ficum.test.ts
在有意改变行为后更新快照:
npx jest --updateSnapshot
测试固定装置
组合套房由捕获驱动 .case.json 固定装置 src/tests/fixtures/**自动发现 斜弧/测试/固定/装载器.ts 并声称 src/测试/分组. test.ts。 。 。 .
由 AlphaCode 生成固定元件 compare-to-reference-grouping 使用 API 响应 pnpm capture-fixtures。见 工具/分组固定/README.md 用于完整抓取工作流程,Metabase基线查询,以及匹配与匹配的地块.
预建二进制
为避免要求消费者在当地编译C代码,该项目使用 prebuild 财务报告和审定财务报表 prebuild-install 加上一个小包装, 加一个本地反弹:
- 目录: 每个焦油球包括: 全部 本地目标来自
binding.gyp—— 说build/Release/grp2024.node, (中文(简体) ),grpmco.node, (中文(简体) ),grpsmr.node,以及ficum.node在与本地人相同的道路上node-gyp建筑(scripts/install-prebuild.cjs检查这四个。 这个binary.module_name输入package.json(单位:千美元)grpmco)是资产名称prebuild-install解析此软件包; 它确实 没有 表示只运出单一文件 . - 出版: 在版本标签上,
.github/workflows/prebuild.yml创建 GitHub 发布并运行prebuild打开 最高级 财务报告和审定财务报表 最高级 (节点ABI与CI对齐),每OS/arch矩阵行上传一发柏油球. 同样的工作流程也支持workflow_dispatch(手工运行),在这种情况下,它会构建相同的矩阵,但上传到 工作流程文物 而不是释放 - 所以维护者可以将其拉到本地pnpm prebuild:download并将它们置于prebuilds/。 。 。 . - 安装: 消费者运行
pnpm prebuild:install(见scripts/install-prebuild.cjs) (中文(简体) ). 包装器按此顺序解决二进制 :- 若为
GITHUB_TOKEN已经确定,代表prebuild-install -T $GITHUB_TOKEN(从 GitHub 发布主机下载). - 否则( 或失败时) 检测 libc 通过
detect-libc并按顺序将候选柏油球列表放入prebuilds/<scope>/数字 :- glibc Linux :
linuxglibc-{arch}接下来linux-{arch} - macOS / 其他 :
{platform}-{arch}
- glibc Linux :
- 第一个现有候选人被提取到包根中, 充入
build/Release/如果不存在,则用指向pnpm prebuild:create(建造当地柏油球)或pnpm build:c:native(编自出处. 使用pnpm prebuild:install:remote绕过包装并运行原始prebuild-install -T $GITHUB_TOKEN直接说.
- 若为
- 坚固的焦油丸: 手册制作的矩阵
prebuild.yml运行可以在prebuilds/并经由files阵列package.json。在匹配中结束消费者node_abi+ 键platform+ 键arch因此,不需要安装一个符号。 承诺集的被钉住的节点ABI是.nvmrc发布时(目前) 24.14.0 (简体中文)) (中文(简体) ). - 邮购数字 :
postinstall运行pnpm build,用于汇编 仅类型脚本。下载预建为 没有 自动; 运行prebuild:install安装后,或从源头编译出所有信息pnpm build:c:native在软件包目录中.
CI 管道
| 工作流程 | 触发 | 目的 |
|---|---|---|
prebuild.yml | 推动标签 v* 手动 | Tag push:创建 GitHub 释放并上传预建(macos x64/arm64,linux glibc x64/arm64). 手动发送: 建立相同的矩阵并上传工作流程的文物( 下载与 pnpm prebuild:download(中文(简体) ) |
test.yml | 调取请求 | 使用节点版本运行测试 .nvmrc |
软件包管理器
项目使用 小时,通过 corepack 通过 packageManager 输入 package.json。 。 。 .
安装
- 安装软件包
pnpm add @beparallel/grouping
- (可选)导出一个 GitHub 托肯
包裹船在下方装了预制的柏油丸 prebuilds/ 支助 node_abi + 键 platform + 键 arch 组合,所以一个符号是 没有 当您的运行时间符合此设定时需要。 只有在您需要从 GitHub Release 主机下载新构建时( 如在节点版本或未覆盖的拱上) 设置一个符号 :
export GITHUB_TOKEN=your_github_token
或设置在.env.dev文件中并运行 dotenv -f .env.dev run XXX。 。 。 .
- 安装本地模块
cd node_modules/@beparallel/grouping && pnpm prebuild:install
prebuild:install 将尝试 GITHUB_TOKEN 如果设定了,则先取出承诺的本地焦油丸。 如果两个路径都没有产生二进制,则会打印指导 pnpm prebuild:create 或者说 pnpm build:c:native。 。 。 .
在AlphaCode的单列上,这个步骤被接入 valuation 作为 grouping:build 剧本.
所需资源
- 节点.js 24.0.0以上(回波针) 24.14.0 (简体中文) 内
.nvmrc(中文(简体) ) - 兼容 macOS 和 Linux( Windows 不支持)
- 对于 本地语言 分组: 运行
prebuild:install添加依赖性后( 编译了下载).node文件),或安装 C 工具链(python3, (中文(简体) ),make, (中文(简体) ),g++运行pnpm build:c:native包内
* 额外资源
释放过程
- 释放过程: 医生/包装/publish.md
- 增加一个新的分组年(从ATIH + 非递归固定装置购买/卸载): 医生/包装/添加-新年
东帝汶
- RSS分组数据格式: doc/atih/122 format.md (中文(简体) )
- 分组算法 : doc/atih/分组 方法.md
- UM 授权文件格式( FIUM 输入) : doc/atih/um authorization file format.md (中文(简体) )
非分组 022/023 (中文(简体) ) RSS 序列化在以下代码中执行 rum/formats/surc/ utils/rum/formats/ (中文(简体) ) 而不是一个独立的医生.