# grouping

A Node.js wrapper for the official ATIH grouping engine used in the French PMSI (Programme de Médicalisation des Systèmes d'Information).

This package allows integration of the native C-based groupage module to classify hospital stays into **GHM** (Groupe Homogène de Malades) and **GHS** (Groupe Homogène de Séjours) codes, in compliance with the T2A billing system in France.

## Overview

This project implements a Node.js native addon using [Node-API](https://nodejs.github.io/node-addon-examples/about/what/) to wrap the official ATIH (Agence Technique de l'Information sur l'Hospitalisation) grouping engine. The grouping engine is a critical component of the French healthcare system's billing and classification infrastructure.

### French Medical Coding Context

The French healthcare system uses the PMSI (Programme de Médicalisation des Systèmes d'Information) for medical activity coding and hospital billing under the T2A (Tarification À l'Activité) system. This project specifically addresses the need for automated grouping of medical stays into standardized categories.

For comprehensive background on grouping algorithms and medical coding in France, refer to this [detailed overview](https://www.notion.so/Grouping-for-Medical-Coding-in-France-205ef7290c5f805ea356fdc1fc7fe94f).

## Technical Architecture

This package consists of:

1. **Native C/C++ Module**: The core ATIH grouping engine in the `atih` folder (see [doc/grouping_method.md](doc/grouping_method.md))
2. **JavaScript Interface**: High-level Node.js API for application integration
3. **Type Definitions**: TypeScript definitions for development support

## How It's Built

The build pipeline has two stages: native C compilation and TypeScript compilation. Prebuilt binaries are distributed via GitHub Releases so consumers don't need a local C toolchain.

### Native C Compilation

[`node-gyp`](https://github.com/nodejs/node-gyp) compiles the ATIH C source files defined in `binding.gyp` into `.node` binary addons. Three targets are built:

- **grp2025** -- the 2025 grouping engine
- **grp2024** -- the 2024 grouping engine
- **ficum** -- FICUM control module

Build locally with:

```bash
pnpm build:c:native
```

### TypeScript Compilation

`tsc` compiles the `src/` directory into CommonJS output in `dist/`, with type declarations emitted to `dist/types/`.

```bash
pnpm build:ts
```

### Prebuilt Binaries

To avoid requiring consumers to compile C code locally, the project uses [`prebuild`](https://github.com/prebuild/prebuild) and [`prebuild-install`](https://github.com/prebuild/prebuild-install):

- **Publishing**: GitHub Actions workflows (triggered by version tags) build platform-specific tarballs for macOS (x64, arm64), Linux glibc (x64, arm64), and Alpine musl (x64), then upload them to the corresponding GitHub Release.
- **Installing**: Consumers run `pnpm prebuild:install`, which downloads the correct prebuilt binary from the GitHub Release matching their platform and Node ABI version.

### CI Pipeline

| Workflow | Trigger | Purpose |
|---|---|---|
| `prebuild.yml` | Push tag `v*` | Creates a GitHub Release, builds prebuilts on ubuntu-latest and macos-latest |
| `wr-build-prebuild-node.yml` | Reusable (called) | Builds prebuilt in a `node:24` container (Linux glibc) |
| `wr-build-prebuild-alpine.yml` | Reusable (called) | Builds prebuilt in a `node:24-alpine` container (Linux musl) |
| `wr-build-prebuild-ubuntu.yml` | Manual dispatch | Builds Linux prebuilts on ubuntu-latest |
| `test.yml` | Pull request | Runs tests using the Node version from `.nvmrc` |

### Package Manager

The project uses **pnpm**, pinned via `corepack` through the `packageManager` field in `package.json`.

## Installation

1. Install the package

```bash
pnpm add @beparallel/grouping
```

2. Export Github Token

```bash
export GITHUB_TOKEN=your_github_token
```

or set it in the .env.dev file and run `dotenv -f .env.dev run XXX`

3. Build the native module

```bash
cd node_modules/@beparallel/grouping && pnpm prebuild:install
```

## Requirements

- Node.js 24.0.0 or higher
- Compatible with macOS and Linux
- Native compilation tools (node-gyp)

## 📚 Additional Resources

### Release process

- Release process: [doc/package/publish.md](doc/package/publish.md)

### Atih

- Format of the RSS non grouped data: [doc/atih/022_format.md](doc/atih/022_format.md)
- Format of the RSS grouped data: [doc/atih/122_format.md](doc/atih/122_format.md)
- Grouping algorithm: [doc/atih/grouping_method.md](doc/atih/grouping_method.md)

## API Reference

### Basic Usage

```javascript
import { grp } from '@beparallel/grouping'

const result = grp.grp2025({...})
```

## Input Format

The module expects RSS (Résumé de Sortie Standardisé) formatted data conforming to ATIH specifications:

```javascript
const rssData = {
  // Patient demographics
  age: 65,
  sex: 'M',

  // Medical coding
  mainDiagnosis: 'I21.0',
  secondaryDiagnoses: ['E11.9', 'N18.6'],
  procedures: ['DEQP003'],

  // Stay information
  entryMode: '6',
  exitMode: '9',
  lengthOfStay: 7,

  // Additional classification data
  severity: 2,
  complexity: 1
}
```

## Output Format

```javascript
{
  ghm: 'GHM_CODE',        // Groupe Homogène de Malades
  ghs: 'GHS_CODE',        // Groupe Homogène de Séjours
  severity: 2,            // Severity level
  complexity: 1,          // Complexity level
  errors: [],             // Array of error codes/messages
  warnings: [],           // Array of warning messages
  processingTime: 1.2     // Processing time in milliseconds
}
```
