diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1c002f5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,141 @@ +# SampleXChange - AI Agent Guidelines + +This document provides guidelines for AI agents working on the SampleXChange codebase, a Spring Boot application for FHIR resource conversion between BBMRI and MII KDS profiles. + +## Project Overview + +- **Technology Stack**: Java 17, Spring Boot 3.4.0, HAPI FHIR 6.8.8, Maven +- **Purpose**: Convert FHIR resources between BBMRI Profiles and MII KDS Profiles for biobank data interchange +- **Architecture**: Component-based Spring application with FHIR mapping layers + +## Build and Development Commands + +```bash +# Build the project +mvn clean install + +# Build without tests +mvn clean package -DskipTests + +# Run the application +mvn spring-boot:run + +# Run with specific profile +mvn spring-boot:run -Dspring-boot.run.arguments="--profile=BBMRI2MII" + +# Run tests (when implemented) +mvn test + +# Run single test class (when implemented) +mvn test -Dtest=ClassName + +# Run single test method (when implemented) +mvn test -Dtest=ClassName#methodName + +# Docker operations +docker build -t samplexchange . +docker-compose up +``` + +## Code Style Guidelines + +### Package Structure +``` +de.samply.samplexchange/ +├── configuration/ # Spring configuration classes +├── converters/ # Data conversion utilities +├── enums/ # Enumerations for fixed values +├── exceptions/ # Custom exception classes +├── mapper/fhir/ # FHIR mapping logic (bbmri/, mii/ subpackages) +├── models/ # Data model classes +├── readers/ # FHIR resource readers +├── resources/ # Resource mapping classes +├── repository/ # Repository layer +├── utils/fhir/ # FHIR utility classes +└── writers/fhir/ # FHIR writer classes +``` + +### Naming Conventions +- **Classes**: PascalCase (e.g., `SpecimenMapping`, `TemperatureConverter`) +- **Methods**: camelCase with descriptive names (e.g., `fromBbrmiToMii`, `toMii`) +- **Variables**: camelCase (e.g., `bbmriId`, `miiSubject`) +- **Constants**: UPPER_SNAKE_CASE (e.g., `URL`, `DEFAULT_TIMEOUT`) +- **Packages**: lowercase with dots (e.g., `de.samply.samplexchange.converters`) + +### Import Organization +1. Standard Java imports (`java.*`) +2. Third-party imports (`org.springframework.*`, `ca.uhn.fhir.model.*`) +3. Local imports (`de.samply.samplexchange.*`) + +### Code Patterns +- **Lombok Usage**: Heavy use of `@Slf4j`, `@Data`, `@Getter`, `@Setter` +- **Spring Annotations**: `@Component`, `@Value`, `@Service`, `@Repository` +- **Documentation**: JavaDoc required for all public classes and methods +- **Access Modifiers**: Public for API, private for internal utilities + +## Type Safety and Generics +- Use generic types in template classes: `ConvertClass` +- Strong typing with FHIR model classes from HAPI FHIR +- Enum usage for fixed value sets (`ProfileFormats`) +- Avoid raw types where possible + +## Error Handling +- Custom exceptions extend `Exception` (not `RuntimeException`) +- Use proper exception chaining with descriptive messages +- Checked exceptions for expected error conditions +- Log errors appropriately using `@Slf4j` + +## FHIR-Specific Guidelines +- Use HAPI FHIR R4 structures exclusively +- Separate mappers for BBMRI↔MII conversions +- Handle extensions properly for custom data fields +- Follow FHIR resource structure conventions +- Validate resources before conversion + +## Configuration Management +- Environment variables: `PROFILE`, `DISABLESSL`, `SOURCE_URL`, `TARGET_URL`, etc. +- Configuration in `application.yml` +- Support for both BBMRI2MII and MII2BBMRI profiles +- Proper binding of environment-specific properties + +## Testing Guidelines (When Implemented) +- Use JUnit 4.13.2 with Spring Boot Test framework +- Mockito for mocking dependencies +- Testcontainers for integration tests +- Follow AAA pattern (Arrange, Act, Assert) +- Test both successful conversions and error scenarios + +## Architecture Patterns +- **Template Method**: Use `ConvertClass` as base class +- **Strategy Pattern**: Different mappers for profile conversions +- **Factory Pattern**: Resource creation in readers/writers +- **Dependency Injection**: Spring component management + +## Development Best Practices +- Maintain separation of concerns between layers +- Use Spring's dependency injection properly +- Follow FHIR best practices for resource handling +- Ensure thread safety for component classes +- Add appropriate logging at INFO/DEBUG/ERROR levels +- Validate inputs at service boundaries + +## Environment Setup +- Java 17 required +- Maven 3.6+ for building +- Docker for containerization +- Environment variables for configuration (see application.yml) + +## When Making Changes +1. Understand the FHIR profile differences (BBMRI vs MII KDS) +2. Check for existing mapper patterns before creating new ones +3. Ensure proper exception handling for FHIR parsing errors +4. Add appropriate logging for debugging conversion issues +5. Test with both source and target profiles when applicable +6. Verify resource validity after conversion + +## Common Pitfalls to Avoid +- Don't mix FHIR versions (use R4 consistently) +- Avoid hardcoded URLs or credentials +- Don't ignore SSL certificate validation in production +- Ensure proper resource ID handling during conversion +- Don't break existing mapper contracts when extending functionality \ No newline at end of file diff --git a/pom.xml b/pom.xml index 330a6ea..2de39e1 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.0 + 4.0.2 de.samply @@ -14,17 +14,12 @@ SampleXChange SampleXChange - 17 - 6.8.8 - 1.18.3 + 25 + 8.6.5 + 1.21.4 - - org.projectlombok - lombok - provided - - + javax.annotation javax.annotation-api 1.3.2 @@ -54,18 +49,18 @@ org.mockito mockito-core - 5.4.0 + 5.21.0 org.fhir ucum - 1.0.3 + 1.0.10 com.opencsv opencsv - 5.7.1 + 5.12.0 com.googlecode.json-simple @@ -86,12 +81,12 @@ jakarta.xml.ws jakarta.xml.ws-api - 4.0.0 + 4.0.2 org.glassfish.hk2 osgi-resource-locator - 2.5.0-b42 + 3.0.0 org.testcontainers @@ -106,8 +101,13 @@ ${testcontainers.version} test + + org.projectlombok + lombok + provided + - + @@ -119,9 +119,69 @@ org.apache.maven.plugins maven-compiler-plugin - 16 - 16 + ${java.version} + ${java.version} + + + org.projectlombok + lombok + 1.18.42 + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.21.0 + + .*-M.*,.*\.M\d+,.*-rc.*,.*-RC.*,.*-SNAPSHOT,.*-alpha.*,.*-beta.* + + + + org.openrewrite.maven + rewrite-maven-plugin + 6.28.1 + + + org.openrewrite.staticanalysis.CommonStaticAnalysis + org.openrewrite.staticanalysis.CodeCleanup + org.openrewrite.java.migrate.UpgradeToJava17 + org.openrewrite.java.RemoveUnusedImports + org.openrewrite.java.OrderImports + org.openrewrite.java.migrate.guava.NoGuava + org.openrewrite.java.migrate.guava.NoGuavaRefasterRecipes + org.openrewrite.java.migrate.RemoveIllegalSemicolons + org.openrewrite.java.testing.junit.JUnit6BestPractices + org.openrewrite.java.testing.mockito.MockitoBestPractices + org.openrewrite.java.testing.assertj.Assertj + + + **/java-gen/** + + + + org.openrewrite.recipe + rewrite-testing-frameworks + 3.26.0 + + + org.openrewrite.recipe + rewrite-migrate-java + 3.26.0 + + + org.openrewrite.recipe + rewrite-logging-frameworks + 3.22.0 + + + org.openrewrite.recipe + rewrite-static-analysis + 2.26.0 + + diff --git a/qodana.yaml b/qodana.yaml new file mode 100644 index 0000000..4cfb240 --- /dev/null +++ b/qodana.yaml @@ -0,0 +1,48 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# + +################################################################################# +# WARNING: Do not store sensitive information in this file, # +# as its contents will be included in the Qodana report. # +################################################################################# +version: "1.0" + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +projectJDK: "25" #(Applied in CI/CD pipeline) + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) + +# Quality gate. Will fail the CI/CD pipeline if any condition is not met +# severityThresholds - configures maximum thresholds for different problem severities +# testCoverageThresholds - configures minimum code coverage on a whole project and newly added code +# Code Coverage is available in Ultimate and Ultimate Plus plans +#failureConditions: +# severityThresholds: +# any: 15 +# critical: 5 +# testCoverageThresholds: +# fresh: 70 +# total: 50 + +#Specify Qodana linter for analysis (Applied in CI/CD pipeline) +linter: jetbrains/qodana-jvm:2025.3 diff --git a/src/main/java/de/samply/samplexchange/SampleXChangeApplication.java b/src/main/java/de/samply/samplexchange/SampleXChangeApplication.java index 52e507c..cc02b20 100644 --- a/src/main/java/de/samply/samplexchange/SampleXChangeApplication.java +++ b/src/main/java/de/samply/samplexchange/SampleXChangeApplication.java @@ -28,7 +28,7 @@ public static void main(String[] args) { SpringApplication.run(SampleXChangeApplication.class, args); long endTime = System.currentTimeMillis() - startTime; - log.info("Finished SampleXChang in " + endTime + " mil sec"); + log.info("Finished SampleXChang in {} mil sec", endTime); } @Override