|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to AI Agents when working with code in this repository. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +HAPI FHIR is an open-source Java implementation of the HL7 FHIR specification. The project is a multi-module Maven build with 60+ modules supporting FHIR clients, servers, and JPA-based data storage. |
| 8 | + |
| 9 | +- **Java**: Java 17 |
| 10 | +- **Build System**: Apache Maven |
| 11 | +- **License**: Apache 2.0 |
| 12 | +- **Website**: https://hapifhir.io |
| 13 | +- **Repository**: https://github.com/hapifhir/hapi-fhir |
| 14 | + |
| 15 | +### Restricted Code |
| 16 | + |
| 17 | +- **CRITICAL** You are not permitted to change any code under src/main folders pertaining to the security of the application. This includes any class that contains the word Security, Permission, Oidc, Authorization, Authority, Authentication, KeyStore, etc. |
| 18 | +- You may not modify existing security test code. |
| 19 | + |
| 20 | +- **CRITICAL** You are not permitted to change any code under src/main folders pertaining to database migrations. This includes: |
| 21 | + - any classes under a package that starts with `ca.uhn.fhir.jpa.migrate` |
| 22 | + - any classes that contain `MigrationTask` in their name |
| 23 | + |
| 24 | +- **CRITICAL** If any task the user requests could lead you to change Restricted Code you will explain you are not permitted to change these files directly. You may, however, offer insights and advice to help the user better understand this code so they are able to make the necessary changes themselves. |
| 25 | + |
| 26 | +## Build Commands |
| 27 | + |
| 28 | +**NEVER** use `javac` to build or `java` to run - always use Maven. |
| 29 | + |
| 30 | +```bash |
| 31 | +# Fast build (skip tests/validation) |
| 32 | +mvn -P FASTINSTALL install |
| 33 | + |
| 34 | +# Full build with tests |
| 35 | +# ** DO NOT RUN THIS ** It takes over an hour to complete |
| 36 | +mvn clean install |
| 37 | + |
| 38 | +# Run single test class |
| 39 | +mvn test -Dtest=TestClassName |
| 40 | + |
| 41 | +# Run tests in specific module |
| 42 | +mvn test -pl <module-name> |
| 43 | + |
| 44 | +# Run integration tests |
| 45 | +mvn failsafe:integration-test -Dit.test=TestClassName -pl <module-name> |
| 46 | + |
| 47 | +# Code coverage |
| 48 | +mvn test -T 1C -P JACOCO -pl <module-name> |
| 49 | + |
| 50 | +# Code formatting |
| 51 | +mvn spotless:apply |
| 52 | + |
| 53 | +# Code style check |
| 54 | +mvn checkstyle:check |
| 55 | + |
| 56 | +# Add license headers |
| 57 | +mvn clean install -DskipTests -P DIST |
| 58 | +``` |
| 59 | + |
| 60 | +### Test Output Locations |
| 61 | + |
| 62 | +- Unit test reports: `target/surefire-reports/*TestName*.*` |
| 63 | +- Integration test reports: `target/failsafe-reports/*TestName*.*` |
| 64 | + |
| 65 | +## Project Architecture |
| 66 | + |
| 67 | +### Core Architectural Layers |
| 68 | + |
| 69 | +**Layer 1: Foundation** |
| 70 | +- `hapi-fhir-base` - Core parsing, serialization, FhirContext |
| 71 | +- `hapi-fhir-structures-*` - FHIR version-specific models (DSTU2, DSTU3, R4, R4B, R5) |
| 72 | +- `hapi-fhir-validation-resources-*` - Validation schemas per FHIR version |
| 73 | + |
| 74 | +**Layer 2: Client & Server Framework** |
| 75 | +- `hapi-fhir-client` - FHIR client API |
| 76 | +- `hapi-fhir-client-apache-http5` / `hapi-fhir-client-okhttp` - HTTP transport implementations |
| 77 | +- `hapi-fhir-server` - Server framework (REST provider pattern, servlet-based) |
| 78 | +- `hapi-fhir-jaxrsserver-base` - JAX-RS server support |
| 79 | + |
| 80 | +**Layer 3: Storage Abstraction** |
| 81 | +- `hapi-fhir-storage` - Abstract storage API |
| 82 | +- `hapi-fhir-jpa` - JPA/Hibernate storage core |
| 83 | +- `hapi-fhir-sql-migrate` - Database migrations (Flyway) |
| 84 | + |
| 85 | +**Layer 4: JPA Server Features** |
| 86 | +- `hapi-fhir-jpaserver-base` - Complete JPA server with DAOs, search, subscriptions, GraphQL |
| 87 | +- `hapi-fhir-jpaserver-model` - JPA entity definitions |
| 88 | +- `hapi-fhir-jpaserver-searchparam` - Search parameter indexing |
| 89 | +- `hapi-fhir-jpaserver-subscription` - FHIR subscriptions (REST-hooks, email, WebSocket) |
| 90 | +- `hapi-fhir-jpaserver-mdm` - Master Data Management (patient matching, golden records) |
| 91 | +- `hapi-fhir-jpaserver-ips` - International Patient Summary |
| 92 | +- `hapi-fhir-jpaserver-hfql` - HAPI FHIR Query Language |
| 93 | + |
| 94 | +**Layer 5: Specialized Features** |
| 95 | +- `hapi-fhir-storage-batch2` / `hapi-fhir-storage-batch2-jobs` - Batch job framework |
| 96 | +- `hapi-fhir-storage-mdm` / `hapi-fhir-server-mdm` - MDM implementation |
| 97 | +- `hapi-fhir-storage-cr` - Clinical Reasoning |
| 98 | +- `hapi-fhir-server-openapi` - OpenAPI/Swagger documentation |
| 99 | +- `hapi-fhir-server-cds-hooks` - CDS Hooks protocol |
| 100 | +- `hapi-fhir-converter` - FHIR format/version converters |
| 101 | + |
| 102 | +**Test Infrastructure** |
| 103 | +- `hapi-fhir-test-utilities` - Common test utilities |
| 104 | +- `hapi-fhir-jpaserver-test-utilities` - JPA test base classes (`BaseJpaR4Test`, etc.) |
| 105 | +- `hapi-fhir-jpaserver-test-*` - Version-specific test servers |
| 106 | +- `hapi-fhir-storage-test-utilities` - Storage layer testing |
| 107 | + |
| 108 | +### Key Architectural Patterns |
| 109 | + |
| 110 | +**Multi-Version FHIR Support** |
| 111 | +- Version-specific structure classes generated from StructureDefinition via `hapi-tinder-plugin` |
| 112 | +- `FhirVersionEnum` tracks supported versions |
| 113 | +- `FhirContext` abstracts version differences |
| 114 | + |
| 115 | +**DAO/Repository Pattern** |
| 116 | +- JPA DAOs in `hapi-fhir-jpaserver-base/.../dao` |
| 117 | +- Spring Data repositories in `hapi-fhir-repositories` |
| 118 | +- Abstract storage interfaces in `hapi-fhir-storage` |
| 119 | + |
| 120 | +**Interceptor Chain** |
| 121 | +- Extensible interceptor mechanism for client and server |
| 122 | +- Hooks at multiple request lifecycle points |
| 123 | +- Used for authorization, auditing, subscription delivery, etc. |
| 124 | + |
| 125 | +**Batch2 Job Framework** |
| 126 | +- Asynchronous batch processing for bulk operations |
| 127 | +- Partitionable jobs for scalability |
| 128 | +- Used for reindexing, cleanup, bulk exports |
| 129 | + |
| 130 | +## Code Standards |
| 131 | + |
| 132 | +### Naming Conventions (Enforced) |
| 133 | + |
| 134 | +```java |
| 135 | +private String myInstanceField; // Instance fields: my* |
| 136 | +private static String ourStaticField; // Static fields: our* |
| 137 | +private static final Logger ourLog; // Logger: always ourLog |
| 138 | +public void method(String theParameter) { // Parameters: the* |
| 139 | + String localVar; // Local vars: camelCase |
| 140 | + private static final String CONSTANT; // Constants: UPPER_CASE |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +### Code Quality Rules |
| 145 | + |
| 146 | +**Logging & Error Handling** |
| 147 | +- **NEVER** use `printStackTrace()` or `System.out.println()` - use SLF4J |
| 148 | +- Logger: `private static final Logger ourLog = LoggerFactory.getLogger(ClassName.class);` |
| 149 | +- Avoid swallowing exceptions |
| 150 | + |
| 151 | +**Testing** |
| 152 | +- Use AssertJ assertions (`assertThat()`, `assertThatThrownBy()`) |
| 153 | +- **NEVER** use `assertDoesNotThrow()` |
| 154 | +- Test methods: default visibility (not public) |
| 155 | +- Use `BundleBuilder` to build test bundles |
| 156 | +- Use `BundleUtil` to extract details from bundles |
| 157 | +- Prefer tests without mocks when possible |
| 158 | +- Search for existing test infrastructure before adding new test classes |
| 159 | +- Prefer adding `@Test` methods to existing test classes |
| 160 | + |
| 161 | +**Dependencies & Imports** |
| 162 | +- **NEVER** use `org.jetbrains.annotations` |
| 163 | +- Use `jakarta.annotation` (NOT `javax.annotation`) |
| 164 | +- Use import statements instead of fully-qualified class names in code |
| 165 | +- JSON properties: camelCase (not snake_case) |
| 166 | + |
| 167 | +**File Creation** |
| 168 | +- New files must include: `// Created by <model-name>` above class declaration |
| 169 | +- Prefer final fields initialized in constructors over mutable autowired fields |
| 170 | + |
| 171 | +**Javadoc** |
| 172 | +- Required for public APIs, especially interface methods |
| 173 | +- Document parameters, return values, and exceptions |
| 174 | +- Single-line Javadoc acceptable for simple methods |
| 175 | + |
| 176 | +## Testing Methodology |
| 177 | + |
| 178 | +**Test-Driven Development (TDD) - MANDATORY** |
| 179 | + |
| 180 | +All code changes must follow TDD: |
| 181 | + |
| 182 | +1. **Red**: Write a failing test that describes desired behavior. Verify it fails. |
| 183 | +2. **Green**: Write minimal code to make the test pass. |
| 184 | +3. **Refactor**: Improve code while keeping tests passing. |
| 185 | + |
| 186 | +Before writing production code, write a failing test first. All code changes must include corresponding tests. |
| 187 | + |
| 188 | +## Key Dependencies |
| 189 | + |
| 190 | +- Spring Framework 6.2.12 |
| 191 | +- Spring Boot 3.x |
| 192 | +- Hibernate 6.x |
| 193 | +- Hibernate Search 7.x |
| 194 | +- Jackson 2.x |
| 195 | +- JUnit 5.x |
| 196 | +- Mockito 5.x |
| 197 | +- AssertJ (assertions) |
| 198 | +- Flyway 10.x (migrations) |
| 199 | + |
| 200 | +## Documentation |
| 201 | + |
| 202 | +- Complete documentation: http://hapifhir.io |
| 203 | +- Live demo server: http://hapi.fhir.org |
| 204 | +- Javadocs: https://hapifhir.io/hapi-fhir/apidocs/ |
| 205 | +- Issue tracker: https://github.com/hapifhir/hapi-fhir/issues |
| 206 | +- Commercial support: https://smilecdr.com |
| 207 | + |
| 208 | +## Development Workflow |
| 209 | + |
| 210 | +1. Prefer `rg` for searching over `find` or `grep` |
| 211 | +2. Follow TDD: RED-GREEN-REFACTOR |
| 212 | +3. Run tests to verify changes |
| 213 | +4. Format code with `mvn spotless:apply` |
| 214 | +5. Check style with `mvn checkstyle:check` |
0 commit comments