Skip to content

Commit 9362c69

Browse files
committed
feat: establish architecture decision record process and enhance existing openEHR and FastAPI ADRs.
1 parent 612dd36 commit 9362c69

File tree

5 files changed

+54
-69
lines changed

5 files changed

+54
-69
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# 0. Record architecture decisions
2+
3+
Date: 2026-01-04
4+
5+
## Status
6+
7+
Accepted
8+
9+
## Context
10+
11+
We need to record the architectural decisions made on this project.
12+
13+
## Decision
14+
15+
We will use Architecture Decision Records, as [described by Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
16+
17+
## Consequences
18+
19+
See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools).

docs/adr/0001-use-openehr.md

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,27 @@
1-
# ADR 0001: Use openEHR for Clinical Data
1+
# 1. Use openEHR for Clinical Data
2+
3+
Date: 2026-01-02
24

35
## Status
46

57
Accepted
68

79
## Context
810

9-
We need a data model and storage solution for clinical data (observations, diagnoses, medications, encounters). Options considered:
11+
We need a data model and storage solution for clinical data including observations, diagnoses, medications, and encounters. Three approaches were considered: designing a custom relational schema with our own tables for each clinical concept, adopting HL7 FHIR resources with a FHIR server, or using openEHR archetypes with EHRBase as the clinical data repository.
1012

11-
1. **Custom relational schema** - Design our own tables for each clinical concept
12-
2. **HL7 FHIR** - Use FHIR resources and a FHIR server
13-
3. **openEHR** - Use openEHR archetypes and EHRBase
13+
A custom relational schema would give us complete control over the data model and allow rapid initial development, but we would need to design and maintain schemas for every clinical concept ourselves. HL7 FHIR offers a mature, widely-adopted standard with extensive tooling and community support, but FHIR servers can be complex to deploy and the resource-based model may not align perfectly with our learning goals. openEHR provides archetype-based modeling where clinical concepts are defined in reusable, version-controlled archetypes maintained by the international openEHR community, separating the clinical data model from the software implementation.
1414

1515
## Decision
1616

17-
We will use **openEHR** with **EHRBase** as the clinical data repository.
18-
19-
## Rationale
17+
We will use openEHR with EHRBase as the clinical data repository.
2018

21-
- **Archetype-based modeling**: Clinical concepts are defined in reusable, version-controlled archetypes maintained by the openEHR community
22-
- **Separation of concerns**: Data model (archetypes) is separate from software implementation
23-
- **Query language**: AQL (Archetype Query Language) provides powerful querying across clinical structures
24-
- **EHRBase maturity**: Open-source, actively maintained, good REST API
25-
- **Learning opportunity**: Explore openEHR ecosystem for clinical data management
19+
EHRBase is an open-source, actively maintained openEHR server that provides a well-documented REST API. Clinical data will be stored as compositions following openEHR templates, while application-specific data like user accounts and audit logs will remain in a separate PostgreSQL database. We will link patient medical record numbers to openEHR EHR IDs through a PatientRegistry table in our application database.
2620

2721
## Consequences
2822

29-
### Positive
30-
- Rich clinical modeling with community-maintained archetypes
31-
- Standardized data that could interoperate with other openEHR systems
32-
- AQL for complex clinical queries
23+
This decision means we gain access to rich clinical modeling capabilities with community-maintained archetypes, producing standardized data that could potentially interoperate with other openEHR systems. The Archetype Query Language (AQL) will enable us to perform complex queries across clinical structures in ways that would be difficult with traditional SQL.
3324

34-
### Negative
35-
- Learning curve for openEHR concepts (compositions, archetypes, templates)
36-
- Need to manage two databases (EHRBase + app DB)
37-
- Template creation/management adds complexity
25+
However, we accept a steeper learning curve as the team must understand openEHR concepts including compositions, archetypes, and templates. We will need to manage two separate databases: EHRBase for clinical data and PostgreSQL for application data. Template creation and management adds operational complexity compared to a simple relational schema.
3826

39-
### Mitigations
40-
- Start with simple templates
41-
- Keep app-specific data (users, audit) in separate PostgreSQL database
42-
- Use PatientRegistry to link MRN to EHR ID
27+
To mitigate these challenges, we will start with simple templates focusing on basic vital signs before expanding to more complex clinical scenarios. Keeping application-specific concerns in the PostgreSQL database allows us to use familiar tools and patterns where openEHR semantics are unnecessary.

docs/adr/0002-fastapi-backend.md

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,29 @@
1-
# ADR 0002: Use FastAPI for Backend
1+
# 2. Use FastAPI for Backend
2+
3+
Date: 2026-01-02
24

35
## Status
46

57
Accepted
68

79
## Context
810

9-
We need a backend framework to:
10-
- Serve REST API endpoints
11-
- Integrate with EHRBase (HTTP client)
12-
- Integrate with PostgreSQL (Prisma)
13-
- Handle async operations efficiently
11+
We need a backend framework to serve REST API endpoints, integrate with EHRBase via HTTP, integrate with PostgreSQL through Prisma, and handle async operations efficiently.
1412

15-
Options considered:
16-
1. **FastAPI** (Python) - Modern async Python framework
17-
2. **Express/Fastify** (Node.js) - JavaScript/TypeScript backend
18-
3. **Django** (Python) - Full-featured Python framework
19-
4. **Go** - High-performance compiled language
13+
Four approaches were considered. FastAPI is a modern Python framework with first-class async/await support and automatic OpenAPI documentation. Express or Fastify on Node.js would provide JavaScript/TypeScript consistency with the frontend and excellent async patterns. Django offers a full-featured Python framework with an extensive ecosystem and built-in admin interface. Go would provide high performance and strong typing through a compiled language.
2014

21-
## Decision
15+
The backend will primarily perform I/O-bound operations: making HTTP requests to EHRBase, executing database queries, and serving JSON responses. These operations benefit more from efficient async handling than raw CPU performance. The team values type safety for catching errors early, automatic API documentation for development velocity, and a gentle learning curve that allows focus on openEHR concepts rather than framework complexity.
2216

23-
We will use **FastAPI** with **Python 3.11+**.
17+
## Decision
2418

25-
## Rationale
19+
We will use FastAPI with Python 3.11 or later as the backend framework.
2620

27-
- **Async-first**: Native async/await support, important for I/O-bound operations (HTTP to EHRBase, database queries)
28-
- **Type hints**: First-class Pydantic integration for request/response validation
29-
- **OpenAPI**: Automatic API documentation generation
30-
- **Learning curve**: Python is accessible, FastAPI is well-documented
31-
- **Ecosystem**: Good libraries for HTTP (httpx), database (Prisma), testing (pytest)
21+
We will use httpx as the async HTTP client for communicating with EHRBase, prisma-client-py for database access, pydantic-settings for configuration management, and pytest-asyncio for testing. All application code will use Python's native async/await syntax, and we will leverage Pydantic models throughout the service and API layers for consistent type validation.
3222

3323
## Consequences
3424

35-
### Positive
36-
- Clean async code with httpx for EHRBase communication
37-
- Automatic request validation and documentation
38-
- Pydantic models shared between API and service layers
39-
40-
### Negative
41-
- Python type system less strict than TypeScript or Go
42-
- Need virtual environment management
43-
- Slightly more complex deployment than Node.js
44-
45-
### Technical Decisions
46-
- Use `httpx` for async HTTP client (EHRBase)
47-
- Use `prisma-client-py` for database access
48-
- Use `pydantic-settings` for configuration
49-
- Use `pytest-asyncio` for testing
25+
FastAPI's async-first architecture allows us to write clean, readable code for concurrent I/O operations without blocking threads or managing callback chains. The automatic request validation and OpenAPI documentation generation means we spend less time writing boilerplate validation code and manually maintaining API specifications. Pydantic models can be shared between API endpoints and service layers, ensuring type consistency throughout the application.
26+
27+
However, Python's type system is less strict than TypeScript or Go, relying on optional static analysis with mypy rather than compile-time guarantees. We will need to manage Python virtual environments for dependency isolation, adding a step to the development setup compared to Node.js or Go. Deployment is slightly more complex than Node.js containerized applications, as we must ensure the correct Python runtime and activate virtual environments appropriately.
28+
29+
The learning curve for FastAPI and async Python is accessible enough that developers can become productive quickly, allowing the team to focus energy on understanding openEHR rather than fighting the framework.

docs/adr/0001-openehr-template-management.md renamed to docs/adr/0003-openehr-template-management.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
# ADR-0001: openEHR Template Management
1+
# 3. openEHR Template Management
2+
3+
Date: 2026-01-03
24

35
## Status
6+
47
Accepted
58

69
## Context
@@ -9,16 +12,11 @@ Open CIS uses EHRBase as its openEHR Clinical Data Repository. EHRBase requires
912

1013
Templates define the structure of clinical data by constraining openEHR archetypes. For example, a "Vital Signs" template combines observation archetypes for blood pressure and pulse within an encounter composition archetype.
1114

12-
### Problem
13-
14-
1. Templates must be uploaded to EHRBase before the application can store clinical data
15-
2. Developers may forget to upload templates when setting up a new environment
16-
3. Different environments (dev, staging, prod) need consistent template configurations
17-
4. Creating proper OPT files from scratch requires specialized tooling and expertise
15+
Templates must be uploaded to EHRBase before the application can store clinical data, but developers may forget this step when setting up a new environment. Different environments like development, staging, and production need consistent template configurations to ensure the same clinical data structures work everywhere. Creating proper OPT files from scratch requires specialized tooling and expertise that would slow down development and introduce a barrier to entry for new contributors.
1816

1917
## Decision
2018

21-
We will implement automatic template registration on API startup, using pre-built templates from the openEHR community:
19+
We will implement automatic template registration on API startup, using pre-built templates from the openEHR community.
2220

2321
1. **Template Storage**: OPT files are stored in `api/templates/` directory, named `{template_id}.opt`
2422

docs/adr/0003-direct-httpx-openehr-integration.md renamed to docs/adr/0004-direct-httpx-openehr-integration.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
# ADR-0003: Direct httpx Integration for openEHR API
1+
# 4. Direct httpx Integration for openEHR API
2+
3+
Date: 2026-01-04
24

35
## Status
6+
47
Accepted
58

69
## Context
710

8-
Open CIS needs to interact with EHRBase (an openEHR Clinical Data Repository) to create, retrieve, and query clinical compositions. We must decide how to implement this integration: use an existing SDK/library or build a custom client using a low-level HTTP library.
11+
Open CIS needs to interact with EHRBase, an openEHR Clinical Data Repository, to create, retrieve, and query clinical compositions. We must decide how to implement this integration: use an existing SDK or library, or build a custom client using a low-level HTTP library.
912

1013
### Problem
1114

0 commit comments

Comments
 (0)