# 1. Support RM 1.1.0 Using JSON Schema Files

Date: 2026-01-06

## Status

Accepted (Updated 2026-01-06 with JSON Schema discovery)

## Context

The project currently supports openEHR Reference Model (RM) 1.0.4 by parsing BMM (Basic Meta-Model) files in JSON format. However, RM 1.1.0 is the latest published release (September 2020) and brings important improvements:

- **DV_SCALE**: New data type for scales/scores with decimal values (extends DV_ORDINAL which only supports integers)
- **preferred_term field**: Added to DV_CODED_TEXT for better terminology mapping in integration scenarios
- **Enhanced Folder support**: Archetypeable meta-data, unlimited folder hierarchies

### The Problem (Initial Assessment)

RM 1.1.0 BMM specifications in the **specifications-ITS-BMM** repository are **not available in JSON format**:

- **RM 1.0.4**: Available in JSON, ODIN, XML, and YAML formats
- **RM 1.1.0**: Available in **ODIN format only** (.bmm files)
- **RM latest**: Available in ODIN format only

Our current `bmm_parser.py` only supports JSON format, which initially appeared to block us from supporting RM 1.1.0.

### Discovery: JSON Schema Files Available

**UPDATE:** Further investigation revealed that RM 1.1.0 **IS available in JSON format** through the [specifications-ITS-JSON](https://github.com/openEHR/specifications-ITS-JSON) repository:

- **Location**: `components/RM/Release-1.1.0/`
- **Format**: JSON Schema (draft-07)
- **Generated by**: Archie (Nedap's openEHR implementation)
- **Structure**:
  - Individual type files (e.g., `DV_QUANTITY.json`, `DV_SCALE.json`)
  - Package directories (Common, Composition, Data_types, etc.)
  - Aggregate file: `main.json` containing all types

**Key advantages:**
- No need to implement ODIN parser
- JSON Schema is well-supported by existing tools (e.g., `datamodel-code-generator`)
- Already structured for code generation
- Maintained by the openEHR community alongside BMM files

### Backward Compatibility Considerations

RM 1.1.0 is **backward compatible** with 1.0.4:
- All 1.0.4 types remain unchanged
- New types and fields are additive only
- No breaking changes to existing structures

This means:
- Code written against 1.0.4 types will work with 1.1.0
- Only consumers who need the new features (DV_SCALE, preferred_term) need to explicitly use them
- Compositions created with 1.1.0 SDK can work with 1.0.4-compliant CDRs (as long as new 1.1.0-specific features aren't used)

### Version Selection Question

Should users be able to specify which RM version they want to use at runtime (e.g., `openehr_sdk.rm.v1_0_4.DV_QUANTITY` vs `openehr_sdk.rm.v1_1_0.DV_QUANTITY`)?

**Arguments against multi-version support:**
- Significant complexity in code generation and package structure
- RM 1.1.0 is backward compatible, so 1.0.4 code works with 1.1.0 classes
- CDRs (like EHRBase) are moving to support 1.1.0
- Violates YAGNI (You Aren't Gonna Need It) principle
- Users can choose which features to use, not which version to import

**Arguments for multi-version support:**
- Some legacy systems may strictly validate against 1.0.4
- Testing and research scenarios
- Gradual migration path

## Decision

We will:

1. **Use JSON Schema files from specifications-ITS-JSON** for RM 1.1.0
   - Source: `github.com/openEHR/specifications-ITS-JSON/components/RM/Release-1.1.0/`
   - No ODIN parser needed (postponed to future project - see PRD-0001)
   - Leverage existing JSON parsing infrastructure

2. **Evaluate two approaches for code generation**:

   **Option A: JSON Schema → Pydantic (via datamodel-code-generator)**
   - Use industry-standard tool `datamodel-code-generator`
   - Pros: Fast implementation, well-maintained
   - Cons: Less control over output, may need post-processing

   **Option B: Custom JSON Schema parser (similar to existing BMM JSON parser)**
   - Extend existing `bmm_parser.py` to handle JSON Schema format
   - Pros: Full control, consistent with existing approach
   - Cons: More initial work, need to maintain parser

   **Initial direction**: Try Option A first, fall back to Option B if needed

3. **Generate RM classes from 1.1.0 by default**
   - The generated package will use RM 1.1.0 as the default and only version
   - All classes will be available at `openehr_sdk.rm.*` (no version namespacing)

4. **Make the generator version-agnostic**
   - The generator will accept a `--rm-version` parameter (e.g., `1.0.4`, `1.1.0`, `latest`)
   - This allows developers to regenerate against different versions if needed
   - Default generator behavior: use RM 1.1.0

5. **Do NOT expose version selection to end users**
   - No runtime version switching
   - No parallel imports like `from openehr_sdk.rm.v1_0_4 import DV_QUANTITY`
   - Users get RM 1.1.0 classes, period

6. **Document compatibility and migration**
   - Clearly document that the SDK uses RM 1.1.0
   - Provide guidance on which features are 1.1.0-specific
   - Note that most 1.1.0 features are backward compatible with 1.0.4 systems

## Consequences

### Positive

- **Future-proof**: Can support RM 1.2.0, 1.3.0, etc. as they are released
- **Latest features**: Users get DV_SCALE, preferred_term, and other improvements immediately
- **Simpler codebase**: Single version reduces complexity
- **Aligns with ecosystem**: EHRBase and other CDRs are moving to 1.1.0 support
- **Better developer experience**: No confusion about which version to import

### Negative

- **Potential breaking change**: Users on strict 1.0.4-only systems may face validation issues
  - *Mitigation*: Document 1.1.0-specific features clearly
  - *Mitigation*: Provide migration guide from 1.0.4 to 1.1.0

- **Different source format**: JSON Schema vs BMM JSON
  - BMM JSON is structural metadata, JSON Schema is for validation
  - May need different parsing logic or use `datamodel-code-generator`
  - *Mitigation*: Evaluate both approaches and choose the simpler one

- **Dependency on Archie-generated schemas**: JSON Schema files are generated by Archie
  - Not official openEHR specification format (BMM is canonical)
  - *Mitigation*: JSON Schema files are maintained in official openEHR repositories
  - *Mitigation*: Can fall back to BMM ODIN if JSON Schema becomes unavailable (future ODIN parser project)

### Implementation Notes

1. **Source Files Acquisition**
   - Clone or download from `github.com/openEHR/specifications-ITS-JSON`
   - Use `components/RM/Release-1.1.0/` directory
   - Can use individual type files or aggregate `main.json`

2. **Code Generation Approach**

   **Phase 1: Evaluate datamodel-code-generator**
   ```bash
   # Install tool
   pip install datamodel-code-generator

   # Test generation from JSON Schema
   datamodel-codegen --input components/RM/Release-1.1.0/Data_types/DV_SCALE.json \
                     --output test_dv_scale.py \
                     --output-model-type pydantic_v2.BaseModel
   ```

   **Phase 2: Custom parser if needed**
   - Extend `generator/bmm_parser.py` to parse JSON Schema format
   - Map JSON Schema types to Python types
   - Generate Pydantic models with proper inheritance

3. **Generator Updates**
   ```bash
   # Default: Generate from RM 1.1.0 JSON Schema
   python -m generator.pydantic_generator

   # Explicit version selection (for development/testing)
   python -m generator.pydantic_generator --rm-version 1.1.0
   python -m generator.pydantic_generator --rm-version 1.0.4  # Uses BMM JSON
   ```

4. **Documentation Updates**
   - README: Update to state RM 1.1.0 support
   - Migration guide: Document changes from 1.0.4 to 1.1.0
   - API docs: Mark 1.1.0-specific features (DV_SCALE, preferred_term)

5. **Testing**
   - Verify all 1.0.4 tests still pass with 1.1.0 classes
   - Add tests for new 1.1.0 features (DV_SCALE, preferred_term)
   - Test compatibility with EHRBase RM 1.1.0 support

### Migration Path for Users

For users currently on 1.0.4:

```python
# Before (implied 1.0.4)
from openehr_sdk.rm import DV_QUANTITY, DV_CODED_TEXT

# After (explicit 1.1.0, but same imports work)
from openehr_sdk.rm import DV_QUANTITY, DV_CODED_TEXT

# New 1.1.0 features (optional)
from openehr_sdk.rm import DV_SCALE  # New in 1.1.0

# DV_CODED_TEXT now has preferred_term field
coded_text = DV_CODED_TEXT(
    value="Hypertension",
    defining_code=CODE_PHRASE(...),
    preferred_term="High blood pressure"  # New in 1.1.0, optional
)
```

## Alternatives Considered

### Alternative 1: Stay on RM 1.0.4

**Rejected** because:
- Misses valuable improvements (DV_SCALE, preferred_term)
- Falls behind the ecosystem
- Will eventually need to upgrade anyway

### Alternative 2: Manual JSON Conversion

Convert ODIN files to JSON manually for 1.1.0.

**Rejected** because:
- Not scalable for future versions
- Error-prone manual process
- Doesn't solve the fundamental problem

### Alternative 3: Support Multiple Versions at Runtime

Generate classes for both 1.0.4 and 1.1.0, allowing users to choose.

**Rejected** because:
- Significant complexity in code generation and package structure
- Backward compatibility makes this unnecessary
- Violates YAGNI principle
- Can revisit if real-world usage demands it

### Alternative 4: Use ODIN Parsing for BMM Files

Parse the ODIN (.bmm) files from specifications-ITS-BMM directly.

**Rejected** (for now) because:
- JSON Schema files already available for RM 1.1.0
- ODIN parser is significant additional complexity
- JSON Schema is more suitable for code generation
- **Note**: ODIN parser project documented in PRD-0001 for future consideration

### Alternative 5: Use JSON Schema from specifications-ITS-JSON

**ACCEPTED** - Use JSON Schema files from specifications-ITS-JSON repository.

**Reasons for acceptance:**
- JSON Schema files already available for RM 1.1.0
- Well-suited for code generation (either via tools or custom parser)
- Maintained by openEHR community (generated by Archie)
- No need to implement ODIN parser immediately
- Can leverage existing tools like `datamodel-code-generator`

## References

- [openEHR RM 1.1.0 Release Announcement](https://discourse.openehr.org/t/openehr-reference-model-rm-release-1-1-0-published/997)
- [openEHR RM 1.1.0 Specifications](https://specifications.openehr.org/releases/RM/Release-1.1.0)
- [specifications-ITS-JSON Repository](https://github.com/openEHR/specifications-ITS-JSON) - **Primary source for RM 1.1.0**
- [specifications-ITS-BMM Repository](https://github.com/openEHR/specifications-ITS-BMM)
- [ODIN Specification](https://specifications.openehr.org/releases/LANG/latest/odin.html)
- [Archie - openEHR Java Implementation](https://github.com/openEHR/archie) - Generates JSON Schema files
- [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) - Tool for generating Pydantic from JSON Schema
- [PRD-0000: Python openEHR SDK](../prd/PRD-0000-python-openehr-sdk.md)
- [PRD-0001: ODIN Parser for openEHR](../prd/PRD-0001-odin-parser.md) - Future project
