feat(data-loading): load fee schedule catalogs and data from generated JSON payloads instead of bundled Germany TypeScript exports

This commit is contained in:
2026-05-14 12:41:31 +00:00
parent 04248e0629
commit d79e013ebf
34 changed files with 90609 additions and 90525 deletions
+29 -20
View File
@@ -17,9 +17,10 @@ pnpm add @fin.cx/fee-schedules
## Quick Start
```ts
import { FeeSchedules, GERMANY_FEE_SCHEDULES, feeSchedules } from '@fin.cx/fee-schedules';
import { FEE_SCHEDULE_CATALOGS, FeeSchedules, feeSchedules } from '@fin.cx/fee-schedules';
const schedules = new FeeSchedules();
const germanyCatalog = FEE_SCHEDULE_CATALOGS.find((catalog) => catalog.countryCode === 'DE');
const germany = schedules.getByCountry('DE');
const goae = schedules.findByAbbreviation('GOÄ');
@@ -27,7 +28,7 @@ const goaeNumber1 = schedules.getFeeRow('de-goae', '1');
const legalFeeRows = schedules.searchFeeRows('Einigungsgebühr', 'de-rvg');
const courtFees = feeSchedules.getById('de-gkg');
console.log(GERMANY_FEE_SCHEDULES.length); // 21
console.log(germanyCatalog?.schedules.length); // 21
console.log(goae?.description); // Gebührenordnung für Ärzte; privatärztliche Leistungen außerhalb GKV.
console.log(goaeNumber1?.cells); // ['1', 'Beratung - auch mittels Fernsprecher -', '80', '9,12']
console.log(legalFeeRows.map((item) => item.code));
@@ -50,11 +51,12 @@ console.log(germany.map((item) => item.id));
| Export | Description |
| --- | --- |
| `GERMANY_FEE_SCHEDULES` | Flat list of German fee schedule records. |
| `GERMANY_FEE_SCHEDULE_DATA` | Imported German fee data, rule sections, source metadata, and import status. |
| `GERMANY_GOAE_FEE_SCHEDULE_DATA` | GOÄ fee data generated into `ts/germany/goae.ts`. Other German schedules follow the same one-file-per-schedule pattern. |
| `GERMANY_FEE_SCHEDULE_CATALOG` | Germany catalog metadata plus all German schedules. |
| `FEE_SCHEDULE_CATALOGS` | All available country catalogs. Currently contains Germany. |
| `FEE_SCHEDULE_DATA_URL` | Raw `code.foss.global` URL used for startup data loading. |
| `feeSchedulePayload` | Full remotely loaded payload. |
| `FEE_SCHEDULE_CATALOGS` | All available country catalogs from the remotely loaded payload. |
| `FEE_SCHEDULE_DATA` | Imported fee data, rule sections, source metadata, and import status from the remotely loaded payload. |
| `SUPPORTED_COUNTRY_CODES` | Country codes derived from `FEE_SCHEDULE_CATALOGS`. |
| `loadFeeSchedulePayload(url?)` | Loads and validates a fee schedule payload from a URL. |
| `FeeSchedules` | Lookup/search class. Can be constructed with the default catalog/data lists or custom lists. |
| `feeSchedules` | Default singleton instance of `FeeSchedules`. |
@@ -69,7 +71,7 @@ console.log(germany.map((item) => item.id));
| `getFeeRows(scheduleId)` | Returns all imported fee rows for a schedule. |
| `getFeeRow(scheduleId, code)` | Returns the first imported coded fee row matching a schedule and code. |
| `getRuleSections(scheduleId)` | Returns imported rule sections for a schedule. |
| `findByAbbreviation(abbreviation, countryCode?)` | Returns the first schedule matching an abbreviation. Abbreviation lookup normalizes whitespace and casing using German locale rules. |
| `findByAbbreviation(abbreviation, countryCode?)` | Returns the first schedule matching an abbreviation. Abbreviation lookup normalizes whitespace and casing. |
| `search(query, countryCode?)` | Searches `id`, `area`, `abbreviation`, and `description`. Returns an empty array for empty queries. |
| `searchFeeRows(query, scheduleId?)` | Searches imported fee rows and original source cells. |
| `searchRuleSections(query, scheduleId?)` | Searches imported rule sections. |
@@ -77,7 +79,7 @@ console.log(germany.map((item) => item.id));
### Data Shape
```ts
export type TFeeScheduleCountryCode = 'DE';
export type TFeeScheduleCountryCode = string;
export interface IFeeSchedule {
id: string;
@@ -102,6 +104,13 @@ export interface IFeeScheduleData {
ruleSections: IFeeScheduleRuleSection[];
notes: string[];
}
export interface IFeeSchedulePayload {
schemaVersion: number;
generatedAt?: string;
catalogs: ICountryFeeScheduleCatalog[];
scheduleData: IFeeScheduleData[];
}
```
Fee rows preserve the original source cells in order. Where the row is code-based, `code`, `description`, `points`, and `amountEur` are populated when those values can be read directly from the source table.
@@ -121,26 +130,26 @@ Some German fee schedules are not federal XML laws on `gesetze-im-internet.de`.
## Generated Files
German fee data is generated by:
The npm package does not ship the catalog or fee data payload. Supported countries, schedule metadata, generation source config, fee rows, and rule sections live under `.onlygit/` in git.
Runtime startup loads the generated payload from:
```text
https://code.foss.global/fin.cx/fee-schedules/raw/branch/main/.onlygit/fee-schedules.json
```
Maintainers regenerate the git-only JSON payload with:
```bash
pnpm run generate:germany
```
The generator lives in `scripts/generate-germany.mjs`. It downloads the official XML ZIP files into `.nogit/fee-schedules-sources/`, extracts them, parses fee table rows and rule sections, and writes generated TypeScript files into `ts/germany/`.
The generated layout is one file per German fee structure:
The generator lives in `scripts/generate-germany.mjs`. It reads `.onlygit/fee-schedules.sources.json`, downloads the official XML ZIP files into `.nogit/fee-schedules-sources/`, extracts them, parses fee table rows and rule sections, and writes:
```text
ts/germany/goae.ts
ts/germany/goz.ts
ts/germany/rvg.ts
ts/germany/gnotkg.ts
ts/germany/index.ts
.onlygit/fee-schedules.json
```
The filename uses ASCII transliteration, so `GOÄ` is generated as `goae.ts`. Each generated file exports one `IFeeScheduleData` object, and `ts/germany/index.ts` re-exports the individual objects plus the combined `GERMANY_FEE_SCHEDULE_DATA` array.
## Germany Catalog
The initial catalog covers 21 German fee schedule systems.