Multi-Region & Market Packs
medOS-ultra runs the same application code in every country. A deployment becomes Japanese, Filipino, or Thai not by forking the code, but by loading a market pack — a self-contained bundle of region-specific seed data, locale, timezone, currency, and insurance-rate tables.
The result is one codebase, many jurisdictions: the clinical logic, workflows, and APIs are byte-identical, and everything that varies by country lives in data rows you can inspect, version, and re-seed.
What a market pack contains
Each region has a market pack directory holding a manifest plus a set of seed files. The manifest declares the region's identity; the seeds populate the read model with country-specific master data and rate tables.
| Component | Role |
|---|---|
manifest.json | Region metadata: country code, locale, timezone, currency, terminology tier, facility types, and the ordered list of seeds to apply |
seed-*.sql | SQL seeds — facility master data, ward configuration, insurance rate tables, localized catalogs |
seed-*.ts | TypeScript seeds for data that is loaded through the platform client (e.g. blood-donor demo data) |
| Connector packs | Per-insurer claim/billing adapters where a country needs direct billing integrations |
A seeding command reads the manifest and applies every seed in order, so a fresh region comes up with one invocation rather than a manual checklist.
The four levers a market pack moves
Locale & language
Each pack sets the default UI locale and seeds bilingual master data — the local language alongside English — so the same screens render correctly in Japanese, Filipino, Thai, or Chinese.
Timezone & currency
Timezone and currency are declared per region so timestamps, billing, and reports follow local conventions.
Insurance rate tables
The country's payer scheme and rate logic ship as pack-owned tables — long-term-care units, case rates, or fee schedules — never as branching code.
Code systems
Each pack records which billing, diagnosis, and drug code systems apply, so the same clinical engine speaks the right coding language per jurisdiction.
Reference regions
The shipped packs illustrate how one engine adapts to very different insurance systems by swapping data, not code.
| Region | Locale | Currency | Insurance model | Coverage seed |
|---|---|---|---|---|
| Japan | ja | JPY | Long-Term Care Insurance (Kaigo) — per-unit care rates | seed-kaigo-rates |
| Philippines | fil | PHP | PhilHealth — case rates over ICD-10 + procedure codes | seed-philhealth-rates |
| Thailand | th | THB | NHSO and related national schemes | payer-scheme seeds |
| China | zh | CNY | Commercial + international direct billing, national health insurance | seed-china-insurers |
Each region also carries a localized pathology/master catalog (for example a Japanese or Filipino name column alongside English), facility-type definitions appropriate to that country, and ward configuration. The clinical workflows that consume these tables are the same everywhere.
How seeding flows
Seeds are layered so dependencies resolve cleanly. Schema migrations create the tables first; baseline rule data ships inside those migrations; then the market pack overlays the country-specific rows on top.
1. Schema migrations
└── tables, access policies, triggers, functions
2. Baseline rule/config data (shipped inside migrations)
└── default behavior, present in every region
3. Market pack SQL seeds
└── facility master, ward config, insurance rates, localized catalogs
4. Market pack TypeScript seeds
└── data loaded through the platform client
Every seed is written to be idempotent — re-running it is safe and will not duplicate or delete existing data. That means you can layer a region's seeds onto an existing deployment additively, and re-apply after a schema change without fear.
Locale-aware behavior beyond billing
A few platform features read the region identity directly. For example, the behavioral-security layer uses the deployment's home country (taken from the manifest's country code) plus a list of neighboring countries treated as "local," so geographic anomaly rules tune themselves per region without manual configuration. The pattern generalizes: declare the country once in the manifest, and region-aware features derive their defaults from it.
Adding a new region
Because regions are data, onboarding a new country is mostly authoring seed files — not writing application code.
1. Create the market pack directory for the new region
2. Write manifest.json
└── country code, locale, timezone, currency,
terminology tier, facility types, seeds[]
3. Author the seed files
├── facility master data
├── ward / facility-type configuration
├── the country's insurance rate tables
└── localized catalogs (local language + English)
4. Make every seed idempotent and bilingual
5. Apply schema migrations, then run the pack's seeds
Practical rules that keep packs portable:
- Bilingual always — every seed carries a local-language column and an English column so the UI works in either language.
- Idempotent always — guard inserts so re-runs are no-ops, allowing additive, repeatable seeding.
- Insurance as data — express the payer scheme as pack-owned rate tables, mirroring how Kaigo, PhilHealth, and the Thai schemes are modeled. No per-country branches in the clinical or billing engines.
- Declare the identity once — set the country code, locale, timezone, and currency in the manifest; region-aware features read from there.
This keeps the invariant the whole architecture depends on: the application code is identical across regions, and only seeds, locale, and insurance-rate tables differ.
See also
- Architecture Overview — topology and the read-model projection layer
- Backend services — the microservices that consume regional master data
- FHIR integration — code-system-based external exchange that spans regions