7 core resource builders.
All builders are stable. They return plain FHIR R4 resource objects — no wrapper classes. Builders know profile rules (KBV slices, cardinality constraints, identifier systems) so application code does not have to.
buildPatient, buildPraxisPatient
Patient
Profile: KBV_PR_FOR_Patient (default) / FPDEPatient (praxis variant)
import { buildPatient, buildPraxisPatient } from '@polaris/fhir-de'
// GKV patient (KBV_PR_FOR_Patient profile)
const gkvPatient = buildPatient({
id: 'pat-001',
firstName: 'Anna',
lastName: 'Müller',
birthDate: '1985-04-12', // omit key entirely if unknown (not empty string)
gender: 'female',
kvid10: 'A123456789', // adds GKV identifier slice
address: {
line: ['Hauptstraße 1'],
city: 'München',
postalCode: '80331',
},
})
// PKV patient (same builder, different identifier)
const pkvPatient = buildPatient({
id: 'pat-002',
firstName: 'Max',
lastName: 'Schmidt',
pkvKvid: 'PKV98765432', // adds PKV identifier slice
})
// Praxis-context patient (FPDEPatient profile)
const praxisPatient = buildPraxisPatient({ id: 'pat-003', firstName: 'Lena', lastName: 'Bauer' }) birthDate must be absent (not an empty string) when unknown. The builder deletes the key when not provided.
buildPractitioner
Practitioner
Profile: KBV_PR_FOR_Practitioner
import { buildPractitioner } from '@polaris/fhir-de'
const practitioner = buildPractitioner({
id: 'prac-001',
firstName: 'Thomas',
lastName: 'Weber',
lanr: '123456789', // Lebenslange Arztnummer — added with SID_LANR system
gender: 'male',
address: {
line: ['Praxisstraße 5'],
city: 'Hamburg',
postalCode: '20095',
},
})
// Dentist with ZANR instead of LANR
const dentist = buildPractitioner({
id: 'prac-002',
firstName: 'Petra',
lastName: 'Braun',
zanr: '987654321', // Zahnarztnummer — added with SYSTEM_ZANR system
}) LANR and ZANR are mutually exclusive in practice. Both can be added; the builder appends both as separate identifier slices.
buildPractitionerRole
PractitionerRole
Profile: FHIR R4 PractitionerRole (no KBV profile constraint)
import { buildPractitionerRole, SYSTEM_KBV_FACHGRUPPE } from '@polaris/fhir-de'
const role = buildPractitionerRole({
id: 'role-001',
practitioner: { reference: 'Practitioner/prac-001' },
organization: { reference: 'Organization/org-001' },
specialty: [{
coding: [{
system: SYSTEM_KBV_FACHGRUPPE, // 'urn:oid:1.2.276.0.76.5.114' — KBV Fachgruppe OID
code: '010',
display: 'Hausarzt',
}],
}],
}) A doctor working in multiple Abrechnungskreise is represented by multiple PractitionerRole resources — one per Organization. This is the canonical FHIR approach.
buildOrganization
Organization
Profile: KBV_PR_FOR_Organization
import { buildOrganization } from '@polaris/fhir-de'
const practice = buildOrganization({
id: 'org-001',
name: 'MVZ Musterpraxis',
bsnr: '123456789', // Betriebsstättennummer — added with SID_BSNR system
ik: '123456789', // Institutionskennzeichen — added with SYSTEM_IK system
address: {
// address.type defaults to 'both' — required by KBV slice (type='both')
// Do not pass type: 'postal' — the KBV slice only accepts 'both'
line: ['Praxisstraße 1'],
city: 'Berlin',
postalCode: '10115',
country: 'DE',
},
}) Organization.address.type must be 'both'. The builder defaults to this. Passing type: 'postal' will cause a KBV slice validation error in Aidbox.
buildEncounter
Encounter
Profile: KBV_PR_Base_Encounter
import { buildEncounter } from '@polaris/fhir-de'
const encounter = buildEncounter({
id: 'enc-001',
status: 'finished',
class: {
system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
code: 'AMB',
display: 'ambulatory',
},
subject: { reference: 'Patient/pat-001' },
serviceProvider: { reference: 'Organization/org-001' },
period: {
start: '2026-04-01T09:00:00+02:00',
end: '2026-04-01T09:30:00+02:00',
},
})
// Optional: waiting room timestamps (MIRA-specific extensions)
const encounterWithWaiting = buildEncounter({
id: 'enc-002',
status: 'in-progress',
class: { system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode', code: 'AMB' },
arrivalTime: '2026-04-01T08:55:00+02:00', // EXT_ENCOUNTER.arrivalTime
calledTime: '2026-04-01T09:05:00+02:00', // EXT_ENCOUNTER.encounterCalled
}) The arrival and called timestamps are MIRA-specific extensions sourced from EXT_ENCOUNTER constants. They are added only when provided.
buildCondition
Condition
Profile: KBV_PR_Base_Condition_Diagnosis (default) / PraxisCondition (usePraxis: true)
import { buildCondition, SYSTEM_ICD_10_GM } from '@polaris/fhir-de'
// Standard KBV diagnosis (ICD-10-GM)
const diagnosis = buildCondition({
id: 'cond-001',
code: {
system: SYSTEM_ICD_10_GM, // 'http://fhir.de/CodeSystem/bfarm/icd-10-gm'
code: 'J06.9',
display: 'Akute Infektion der oberen Atemwege',
},
subject: { reference: 'Patient/pat-001' },
clinicalStatus: { code: 'active' },
isPermanentDiagnosis: false, // EXT_CONDITION.dauerdiagnose extension
})
// Praxis-context condition (PraxisCondition profile)
const praxisDiag = buildCondition(
{ code: { code: 'E11.9' }, subject: { reference: 'Patient/pat-001' } },
{ usePraxis: true }
) isPermanentDiagnosis maps to the EXT_CONDITION.dauerdiagnose extension — a MIRA-specific extension with no standard FHIR equivalent.
buildClaim
Claim
Profile: FHIR R4 Claim
import { buildClaim, SYSTEM_EBM } from '@polaris/fhir-de'
const claim = buildClaim({
id: 'claim-001',
status: 'active',
use: 'claim',
patient: { reference: 'Patient/pat-001' },
insurer: { reference: 'Organization/org-kasse' },
provider: { reference: 'Organization/org-001' },
created: '2026-04-01',
priority: { code: 'normal' },
insurance: [{
sequence: 1,
focal: true,
coverage: { reference: 'Coverage/cov-001' },
}],
item: [{
sequence: 1,
productOrService: {
system: SYSTEM_EBM, // 'http://fhir.de/CodeSystem/ebm' — EBM coding system
code: '03000',
},
servicedDate: '2026-04-01',
}],
}) Claim resources are used for GKV and private billing. For EBM billing use SYSTEM_EBM as the coding system; for GOÄ use SYSTEM_GOAE.
All builders return plain resources
Builder return types are FHIR R4 resource interfaces (e.g. Patient, Organization). No wrapper class is returned. The result can be serialized directly to JSON for NDJSON import.
Profile classes for validation
To validate an existing resource against a profile, use the generated profile class: KBV_PR_FOR_PatientProfile.from(raw) (strict) or KBV_PR_FOR_PatientProfile.apply(raw) (less strict). These classes are re-exported from the main barrel.