|
| 1 | +--- |
| 2 | +title: "FHIR Bucket Config" |
| 3 | +sidebar_position: 2 |
| 4 | +--- |
| 5 | + |
| 6 | +# Validation & Profiles |
| 7 | + |
| 8 | +Couchbase FHIR CE validates all incoming and outgoing resources using the HAPI FHIR validator. |
| 9 | +Validation behavior depends on two factors: |
| 10 | + |
| 11 | +- Validation Mode — how strictly the resource is checked. |
| 12 | +- Validation Profile — which FHIR/US Core specification the resource is checked against. |
| 13 | + |
| 14 | +## FHIR Validation Modes |
| 15 | + |
| 16 | +| Mode | Behavior | Typical Use | Example that Passes | Example that Fails | |
| 17 | +| ----------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------ | --------------------------------------- | |
| 18 | +| **none** | No validation performed. Accepts any JSON containing `resourceType`. | Rapid development, bulk import, trusted data sources | `{ "resourceType": "Patient", "gender": "xyz" }` | _Never fails_ | |
| 19 | +| **lenient** | Validates against the FHIR R4 spec but logs warnings instead of rejecting errors. | Integration with legacy systems, relaxed QA | Valid resource with minor omissions | Missing required field → ⚠ Warning only | |
| 20 | +| **strict** | Fully enforces FHIR R4 and profile constraints. Rejects invalid or incomplete resources. | Production, regulated environments | Valid, well-formed resource | Missing identifier → ❌ Rejects | |
| 21 | + |
| 22 | +## FHIR Normalization (applies to all modes) |
| 23 | + |
| 24 | +Couchbase FHIR always normalizes input before validation: |
| 25 | +| Input | Normalized Output | Note | |
| 26 | +| --------------------- | ------------------- | ---------------- | |
| 27 | +| `"given": "John"` | `"given": ["John"]` | Single → array | |
| 28 | +| `"active": [true]` | `"active": true` | Array → scalar | |
| 29 | +| `"family": " Smith "` | `"family": "Smith"` | Trims whitespace | |
| 30 | + |
| 31 | +:::warning |
| 32 | +Because normalization happens first, even strict mode won’t flag these shorthand formats as errors. Validation occurs after parsing. |
| 33 | +::: |
| 34 | + |
| 35 | +## Validation Examples |
| 36 | + |
| 37 | +#### ✅ Valid in all modes |
| 38 | + |
| 39 | +``` |
| 40 | +{ "resourceType": "Patient", |
| 41 | + "name": [{ "use": "official", "family": "Smith", "given": ["John"] }], |
| 42 | + "gender": "male", |
| 43 | + "birthDate": "1990-01-01" |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +#### ⚠ Passes lenient / none, fails strict |
| 48 | + |
| 49 | +``` |
| 50 | +{ "resourceType": "Patient", |
| 51 | + "name": [{ "family": "Smith" }], |
| 52 | + "gender": "male" |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +- Reason: US Core requires an identifier and a full name. |
| 57 | + - none → ✅ accepts |
| 58 | + - lenient → ⚠ warns, still stores |
| 59 | + - strict → ❌ rejects |
| 60 | + |
| 61 | +#### ❌ Fails lenient and strict |
| 62 | + |
| 63 | +``` |
| 64 | +{ "resourceType": "Patient", |
| 65 | + "gender": "attack-helicopter", |
| 66 | + "birthDate": "1990-01-01" } |
| 67 | +``` |
| 68 | + |
| 69 | +- Invalid enum (gender must be male | female | other | unknown). |
| 70 | + |
| 71 | +#### ❌ Fails lenient and strict |
| 72 | + |
| 73 | +``` |
| 74 | +{ "resourceType": "Patient", |
| 75 | + "gender": "Male", |
| 76 | + "birthDate": "01/01/1990" } |
| 77 | +``` |
| 78 | + |
| 79 | +- Wrong case + date format (YYYY-MM-DD expected). |
| 80 | + |
| 81 | +#### ❌ Fails lenient and strict |
| 82 | + |
| 83 | +``` |
| 84 | +{ "resourceType": "Patient", |
| 85 | + "name": "Smith", |
| 86 | + "gender": "male" } |
| 87 | +``` |
| 88 | + |
| 89 | +- name must be an array; invalid cardinality. |
| 90 | + |
| 91 | +## lenient vs strict — the Real Difference |
| 92 | + |
| 93 | +- For base FHIR R4 (no profiles) the spec is permissive, so lenient ≈ strict. |
| 94 | +- Both reject obvious schema errors (invalid enum, wrong data type, bad cardinality). |
| 95 | +- They differ only when profiles or terminology validation are active. |
| 96 | + | Scenario | lenient | strict | |
| 97 | + | ------------------------------------ | --------- | ----------------- | |
| 98 | + | Missing required field (per profile) | ⚠ Warns | ❌ Rejects | |
| 99 | + | Invalid value set binding | ⚠ Warns | ❌ Rejects | |
| 100 | + | Profile constraint violation | ⚠ Warns | ❌ Rejects | |
| 101 | + | Unknown extension | ✅ Accepts | ⚠ Warns / rejects | |
| 102 | + | Base FHIR structural error | ❌ Rejects | ❌ Rejects | |
| 103 | + |
| 104 | +## When Profiles Are Enabled |
| 105 | + |
| 106 | +When you set the profile for a bucket (e.g., US Core 6.1.0), validation extends beyond base FHIR: |
| 107 | + |
| 108 | +US Core Patient requires: |
| 109 | + |
| 110 | +- ≥ 1 identifier |
| 111 | +- ≥ 1 name |
| 112 | +- gender |
| 113 | +- Example: |
| 114 | + `{ "resourceType": "Patient", "gender": "male" }` |
| 115 | + | Mode | Result | |
| 116 | + | ------- | ----------------------------------- | |
| 117 | + | none | ✅ Accepted | |
| 118 | + | lenient | ⚠ Logs warnings, stores anyway | |
| 119 | + | strict | ❌ Rejects (missing required fields) | |
| 120 | + |
| 121 | +## Recommended Modes |
| 122 | + |
| 123 | +| Use Case | Recommended Mode | |
| 124 | +| --------------------------------------------- | ----------------------------------------------- | |
| 125 | +| Development / testing | **none** — fastest, skip validation | |
| 126 | +| Integration / external sources | **lenient** — allow warnings, keep data flowing | |
| 127 | +| Production / quality enforcement | **strict** — reject invalid resources | |
| 128 | +| Regulated environments (HIPAA, GDPR, US Core) | **strict + profile** — required for compliance | |
| 129 | +| Internal tools / synthetic data | **lenient** — balance speed and safety | |
| 130 | + |
| 131 | +## Understanding “Helpful” Parsing |
| 132 | + |
| 133 | +Couchbase FHIR intentionally makes parsing forgiving to simplify developer experience: |
| 134 | + |
| 135 | +- Converts single values to arrays automatically. |
| 136 | +- Trims whitespace. |
| 137 | +- Normalizes data types where unambiguous. |
| 138 | + |
| 139 | +This means lenient and strict share the same parser — strict mode focuses on semantic validation, not raw JSON schema enforcement. |
| 140 | + |
| 141 | +## Summary |
| 142 | + |
| 143 | +| Mode | Checks | Rejects | Best For | |
| 144 | +| ------- | ------------------------------- | ------------------------ | ----------------------- | |
| 145 | +| none | None | Nothing | Bulk load, dev | |
| 146 | +| lenient | FHIR rules (+ warnings) | Severe structural errors | Integration | |
| 147 | +| strict | FHIR + profiles (+ terminology) | Any violation | Production / Compliance | |
| 148 | + |
| 149 | +### Bottom line: |
| 150 | + |
| 151 | +- Without profiles, lenient ≈ strict. |
| 152 | +- With profiles, strict enforces structure, bindings, and required fields. |
| 153 | +- Use none only for development or trusted bulk imports. |
0 commit comments