|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +OpenESPI-GreenButton-Java is a monorepo implementation of the NAESB Energy Services Provider Interface (ESPI) 4.0 specification for Green Button energy data standards. The project has been migrated to Java 21, Jakarta EE 9+, and Spring Boot 3.5. |
| 8 | + |
| 9 | +## Build and Test Commands |
| 10 | + |
| 11 | +### Build All Modules |
| 12 | +```bash |
| 13 | +# From repository root |
| 14 | +mvn clean install |
| 15 | + |
| 16 | +# Build only fully-migrated Spring Boot 3.5 modules (excludes thirdparty) |
| 17 | +mvn clean install -Pspring-boot-only |
| 18 | +``` |
| 19 | + |
| 20 | +### Run Tests |
| 21 | +```bash |
| 22 | +# Test all modules |
| 23 | +mvn test |
| 24 | + |
| 25 | +# Test specific module with dependencies |
| 26 | +mvn test -pl openespi-datacustodian -am |
| 27 | + |
| 28 | +# Test specific module only |
| 29 | +cd openespi-common && mvn test |
| 30 | + |
| 31 | +# Integration tests with TestContainers (requires Docker) |
| 32 | +mvn verify -pl openespi-common -Pintegration-tests |
| 33 | +``` |
| 34 | + |
| 35 | +### Run Applications |
| 36 | +```bash |
| 37 | +# Data Custodian (default: dev-mysql profile) |
| 38 | +cd openespi-datacustodian && mvn spring-boot:run |
| 39 | + |
| 40 | +# With specific profile |
| 41 | +cd openespi-datacustodian && mvn spring-boot:run -Dspring-boot.run.profiles=dev-postgresql |
| 42 | + |
| 43 | +# Authorization Server |
| 44 | +cd openespi-authserver && mvn spring-boot:run |
| 45 | + |
| 46 | +# Third Party (when migration complete) |
| 47 | +cd openespi-thirdparty && mvn spring-boot:run |
| 48 | +``` |
| 49 | + |
| 50 | +### Run Single Test |
| 51 | +```bash |
| 52 | +# Run specific test class |
| 53 | +mvn test -Dtest=UsagePointRepositoryTest |
| 54 | + |
| 55 | +# Run specific test method |
| 56 | +mvn test -Dtest=UsagePointRepositoryTest#testFindById |
| 57 | + |
| 58 | +# Run test in specific module |
| 59 | +mvn test -pl openespi-common -Dtest=UsagePointRepositoryTest |
| 60 | +``` |
| 61 | + |
| 62 | +## Architecture |
| 63 | + |
| 64 | +### Module Dependencies |
| 65 | +The monorepo follows a layered architecture with these dependencies: |
| 66 | +- **openespi-common** → Foundation library (no dependencies on other modules) |
| 67 | +- **openespi-datacustodian** → Depends on openespi-common |
| 68 | +- **openespi-authserver** → Independent module (NO dependency on openespi-common) |
| 69 | +- **openespi-thirdparty** → Depends on openespi-common |
| 70 | + |
| 71 | +IMPORTANT: The Authorization Server (openespi-authserver) is completely independent and does NOT depend on openespi-common. It has its own entity definitions, repositories, and services for OAuth2 authorization. |
| 72 | + |
| 73 | +### Domain Model Structure |
| 74 | +The domain model is organized in `openespi-common/src/main/java/org/greenbuttonalliance/espi/common/domain/`: |
| 75 | +- **domain/common/** - Shared base entities (IdentifiedObject, LinkType, etc.) |
| 76 | +- **domain/usage/** - ESPI energy usage entities (UsagePoint, MeterReading, IntervalBlock, ReadingType, RetailCustomer, etc.) |
| 77 | +- **domain/customer/** - Customer entities from customer.xsd schema (CustomerAccount, CustomerAgreement, ServiceSupplier, Meter, etc.) |
| 78 | + |
| 79 | +All ESPI domain entities extend `IdentifiedObject` which provides: |
| 80 | +- UUID primary key (`id`) |
| 81 | +- Self-reference URI (`selfLink`) |
| 82 | +- Up-reference URI (`upLink`) |
| 83 | +- XML marshalling support |
| 84 | + |
| 85 | +### Service Layer Pattern |
| 86 | +Services follow a consistent interface-implementation pattern: |
| 87 | +- **Interfaces**: `openespi-common/src/main/java/org/greenbuttonalliance/espi/common/service/` |
| 88 | +- **Implementations**: `openespi-common/src/main/java/org/greenbuttonalliance/espi/common/service/impl/` |
| 89 | + |
| 90 | +Services are organized by domain: |
| 91 | + |
| 92 | +**Usage Domain Services** (energy data from usage.xsd): |
| 93 | +- `UsagePointService` - Energy usage point management |
| 94 | +- `MeterReadingService` - Meter reading data |
| 95 | +- `IntervalBlockService` - Time-series interval data |
| 96 | +- `ReadingTypeService` - Reading type metadata |
| 97 | +- `UsageSummaryService` - Usage aggregation summaries |
| 98 | +- `ElectricPowerQualitySummaryService` - Power quality metrics |
| 99 | +- `TimeConfigurationService` - Timezone and time parameters |
| 100 | +- `RetailCustomerService` - Retail customer management (part of usage.xsd) |
| 101 | + |
| 102 | +**Customer Domain Services** (from customer.xsd, in `service/customer/`): |
| 103 | +- `CustomerAccountService` - Customer account management |
| 104 | +- `CustomerService` - Customer information |
| 105 | +- `MeterService` - Meter device information |
| 106 | +- `ServiceLocationService` - Service location data |
| 107 | +- `StatementService` - Billing statements |
| 108 | + |
| 109 | +Note: Entities exist for CustomerAgreement and ServiceSupplier but services have not been implemented yet. |
| 110 | + |
| 111 | +**Cross-Cutting Services**: |
| 112 | +- `AuthorizationService` - OAuth2 authorization management |
| 113 | +- `SubscriptionService` - Third-party subscriptions |
| 114 | +- `ApplicationInformationService` - Application registration |
| 115 | +- `NotificationService` - Event notifications |
| 116 | +- `BatchListService` - Batch operations |
| 117 | +- `DtoExportService` - Entity to DTO mapping and XML export |
| 118 | + |
| 119 | +### REST API Structure |
| 120 | +REST controllers are in `openespi-datacustodian/src/main/java/org/greenbuttonalliance/espi/datacustodian/web/`: |
| 121 | +- **web/api/** - ESPI RESTful API endpoints (many currently `.disabled` during migration) |
| 122 | +- **web/custodian/** - Data custodian-specific endpoints |
| 123 | +- **web/customer/** - Retail customer portal endpoints |
| 124 | + |
| 125 | +Note: Many REST controllers have `.disabled` extension during the Spring Boot 3.5 migration. They need to be re-enabled and tested after core functionality is validated. |
| 126 | + |
| 127 | +### DTO and Mapping Layer |
| 128 | +The project uses MapStruct for entity-to-DTO mappings: |
| 129 | +- **DTOs**: `openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/` |
| 130 | +- **Mappers**: `openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/` |
| 131 | + |
| 132 | +DTOs mirror ESPI XML schema structure and are used exclusively for XML representations. JSON is only used by openespi-authserver for OAuth2 operations. |
| 133 | + |
| 134 | +## Database Management |
| 135 | + |
| 136 | +### Supported Databases |
| 137 | +- **MySQL 8.0+** (primary development database) |
| 138 | +- **PostgreSQL 15+** (production recommended) |
| 139 | +- **H2** (testing only via TestContainers) |
| 140 | + |
| 141 | +### Spring Profiles |
| 142 | +Application behavior is controlled via Spring profiles: |
| 143 | +- `dev-mysql` - MySQL development (default) |
| 144 | +- `dev-postgresql` - PostgreSQL development |
| 145 | +- `local` - Local development settings |
| 146 | +- `docker` - Docker container deployment |
| 147 | +- `prod` - Production settings |
| 148 | +- `test` - Test configuration with H2 |
| 149 | +- `testcontainers` - Integration tests with TestContainers |
| 150 | + |
| 151 | +### Database Migrations |
| 152 | +Flyway manages database schema migrations: |
| 153 | +- **Location**: `openespi-common/src/main/resources/db/migration/` |
| 154 | +- **MySQL scripts**: `V1__Create_Base_Tables.sql`, `V3__Create_additiional_Base_Tables.sql` |
| 155 | +- **Run migrations**: Automatically on application startup with `spring.flyway.enabled=true` |
| 156 | + |
| 157 | +IMPORTANT: When adding/modifying entities, ensure Flyway migration scripts are updated to match JPA entity definitions. |
| 158 | + |
| 159 | +## Key Technologies |
| 160 | + |
| 161 | +### Spring Boot 3.5 Stack |
| 162 | +- **Spring Boot**: 3.5.0 |
| 163 | +- **Spring Security**: 6.x (OAuth2 Resource Server and Client) |
| 164 | +- **Spring Data JPA**: 3.x with Hibernate 6.x |
| 165 | +- **Spring Authorization Server**: Latest (for openespi-authserver only) |
| 166 | + |
| 167 | +### Persistence |
| 168 | +- **JPA/Hibernate**: 6.x with Jakarta Persistence API |
| 169 | +- **UUID Primary Keys**: All entities use UUID instead of Long IDs |
| 170 | +- **Flyway**: Database migration management |
| 171 | +- **HikariCP**: Connection pooling |
| 172 | + |
| 173 | +### Testing |
| 174 | +- **JUnit 5**: Test framework |
| 175 | +- **Mockito**: Mocking framework |
| 176 | +- **TestContainers**: Docker-based integration testing for MySQL and PostgreSQL |
| 177 | +- **Spring Boot Test**: Auto-configuration for testing |
| 178 | + |
| 179 | +### Build Tools |
| 180 | +- **Maven**: 3.9+ |
| 181 | +- **MapStruct**: 1.6.0 for DTO mapping |
| 182 | +- **Lombok**: 1.18.34 for reducing boilerplate |
| 183 | + |
| 184 | +## ESPI 4.0 Compliance |
| 185 | + |
| 186 | +This codebase implements the NAESB ESPI 4.0 specification for Green Button data exchange. |
| 187 | + |
| 188 | +### XML Schema Files |
| 189 | +- **Location**: `openespi-common/src/main/resources/schema/ESPI_4.0/` |
| 190 | +- **Files**: `espi.xsd` (usage data), `customer.xsd` (customer data) |
| 191 | + |
| 192 | +### Atom Feed Format |
| 193 | +ESPI uses Atom XML feeds for data exchange. Key patterns: |
| 194 | +- Each resource has both feed (collection) and entry (single item) representations |
| 195 | +- Feed and Entry self-links use pattern: `https://{host}/DataCustodian/espi/1_1/resource/{resource}/{id}` (where {resource} is the entity being received or sent) |
| 196 | +- Entry links include `rel="self"` (resource URL), `rel="up"` (parent collection), `rel="related"` (related resources) |
| 197 | +- All IDs are Type 5 UUIDs in format: `urn:uuid:xxxxxxxx-xxxx-5xxx-xxxx-xxxxxxxxxxxx` |
| 198 | +- Link type attributes use `espi-entry/{resource}` or `espi-feed/{resource}` format |
| 199 | + |
| 200 | +### Core ESPI Resources |
| 201 | + |
| 202 | +**Usage Domain Resources** (from usage.xsd): |
| 203 | +- **UsagePoint**: Represents a metering point (e.g., electric meter) |
| 204 | +- **MeterReading**: Collection of interval blocks for a usage point |
| 205 | +- **IntervalBlock**: Time-series data with individual reading intervals |
| 206 | +- **ReadingType**: Metadata describing measurement characteristics |
| 207 | +- **ElectricPowerQualitySummary**: Power quality metrics |
| 208 | +- **UsageSummary**: Aggregated usage statistics |
| 209 | +- **LocalTimeParameters**: Timezone configuration |
| 210 | +- **RetailCustomer**: Retail customer information |
| 211 | + |
| 212 | +**Customer Domain Resources** (from customer.xsd): |
| 213 | +- **CustomerAccount**: Customer billing account |
| 214 | +- **CustomerAgreement**: Agreement between customer and supplier |
| 215 | +- **ServiceSupplier**: Utility or energy service provider |
| 216 | +- **Meter**: Physical meter device information |
| 217 | +- **ServiceLocation**: Physical location of service delivery |
| 218 | +- **Statement**: Billing statement information |
| 219 | + |
| 220 | +## Development Workflow |
| 221 | + |
| 222 | +### Branch Strategy |
| 223 | +- **Main branch**: `main` (production-ready code) |
| 224 | +- **Feature branches**: `feature/description` for new features |
| 225 | +- **Bug fixes**: `fix/description` for bug fixes |
| 226 | +- **Always create feature branch before making changes** - never commit directly to main |
| 227 | +- See BRANCH_STRATEGY.md for detailed workflow |
| 228 | + |
| 229 | +### Testing Requirements |
| 230 | +- All tests must pass before committing: `mvn test` |
| 231 | +- Run tests for affected module and its dependents: `mvn test -pl <module> -am` |
| 232 | +- Integration tests should pass before PR merge: `mvn verify -Pfull-integration` |
| 233 | + |
| 234 | +### Common Development Patterns |
| 235 | + |
| 236 | +#### Adding New ESPI Entity |
| 237 | +1. Create entity in `openespi-common/src/main/java/org/greenbuttonalliance/espi/common/domain/usage/` (or `/customer/`) |
| 238 | +2. Extend `IdentifiedObject` base class |
| 239 | +3. Add JPA annotations (`@Entity`, `@Table`, `@Column`) |
| 240 | +4. Create repository interface in `repositories/` |
| 241 | +5. Create service interface and implementation in `service/` and `service/impl/` |
| 242 | +6. Create DTO in `dto/` package |
| 243 | +7. Create MapStruct mapper interface in `mapper/` |
| 244 | +8. Add Flyway migration script in `db/migration/` |
| 245 | +9. Write unit tests and integration tests |
| 246 | + |
| 247 | +#### JPA Mapping Guidelines |
| 248 | +- All entities use `@Id` with `UUID` type, not `Long` |
| 249 | +- Use `@JoinColumn` for foreign keys with explicit `name` attribute |
| 250 | +- Avoid `@Where` annotation conflicts with `@JoinColumn` on the same field |
| 251 | +- Be careful with `@ElementCollection` and `@CollectionTable` for embedded collections |
| 252 | +- Phone numbers and addresses are embedded collections using `@ElementCollection` |
| 253 | + |
| 254 | +#### REST Controller Development |
| 255 | +- Controllers in `openespi-datacustodian` implement ESPI REST API |
| 256 | +- Use `@RestController` and `@RequestMapping` annotations |
| 257 | +- Follow existing patterns in enabled controllers (e.g., `UsagePointController`, `MeterReadingController`) |
| 258 | +- Many controllers currently disabled (`.disabled` extension) - re-enable after testing core functionality |
| 259 | + |
| 260 | +## Migration Status |
| 261 | + |
| 262 | +The codebase is actively being migrated to Spring Boot 3.5. Key migration achievements: |
| 263 | +- Java 21 upgrade complete across all modules |
| 264 | +- Jakarta EE 9+ migration complete (javax → jakarta namespace) |
| 265 | +- Spring Boot 3.5 migration complete for common, datacustodian, authserver |
| 266 | +- UUID primary keys migrated from Long IDs |
| 267 | +- OAuth2 modernized with Spring Security 6.x patterns |
| 268 | +- RestTemplate replaced with WebClient |
| 269 | + |
| 270 | +### Known Issues |
| 271 | +Check migration status documents for current issues: |
| 272 | +- `2025-07-15_Claude_Code_Spring_Boot_3.5_Migration_Plan.md` - Overall migration plan |
| 273 | +- `openespi-common/SPRING_BOOT_3.5_MIGRATION_STATUS.md` - Common module status |
| 274 | +- `openespi-authserver/MIGRATION_ROADMAP.md` - Auth server status |
| 275 | + |
| 276 | +## Future Updates |
| 277 | + |
| 278 | +Planned technology upgrades: |
| 279 | +- **Java 25**: Upgrade from Java 21 to Java 25 LTS when released |
| 280 | +- **Spring Boot 4.0**: Migrate from Spring Boot 3.5 to Spring Boot 4.0 |
| 281 | + |
| 282 | +## OAuth2 Security |
| 283 | + |
| 284 | +### Authorization Flow |
| 285 | +The system implements OAuth2 authorization code flow: |
| 286 | +1. Third-party application requests authorization |
| 287 | +2. Retail customer authenticates with openespi-authserver |
| 288 | +3. Authorization server issues authorization code |
| 289 | +4. Third-party exchanges code for access token |
| 290 | +5. Third-party accesses data custodian resources with token |
| 291 | + |
| 292 | +### Security Configuration |
| 293 | +- **Authorization Server**: `openespi-authserver` - Spring Authorization Server (independent module) |
| 294 | +- **Resource Server**: `openespi-datacustodian` - Validates OAuth2 tokens |
| 295 | +- **OAuth2 Client**: `openespi-thirdparty` - Third-party application using WebClient with OAuth2 |
| 296 | + |
| 297 | +## Troubleshooting |
| 298 | + |
| 299 | +### Build Failures |
| 300 | +- Ensure Java 21 is installed: `java -version` |
| 301 | +- Clean build: `mvn clean install` |
| 302 | +- Check for profile-specific issues: review active Spring profile |
| 303 | + |
| 304 | +### Test Failures |
| 305 | +- Ensure Docker is running for TestContainers tests |
| 306 | +- Check database connection settings in application-test.yml |
| 307 | +- Review test logs in `target/surefire-reports/` |
| 308 | + |
| 309 | +### Application Startup Issues |
| 310 | +- Check Spring profile is correctly set: `SPRING_PROFILES_ACTIVE` |
| 311 | +- Verify database is accessible and schema is current |
| 312 | +- Review application logs for JPA mapping errors |
| 313 | +- Check for duplicate column mappings in entities |
| 314 | + |
| 315 | +### JPA Mapping Errors |
| 316 | +- Look for duplicate `@Column` or `@JoinColumn` definitions |
| 317 | +- Check for conflicts between `@Where` and relationship mappings |
| 318 | +- Verify Flyway migration scripts match entity definitions |
| 319 | +- Review entity inheritance structure for mapping conflicts |
| 320 | + |
| 321 | +## Additional Documentation |
| 322 | + |
| 323 | +- **README.md** - Project overview and quick start |
| 324 | +- **BRANCH_STRATEGY.md** - Git workflow and branching strategy |
| 325 | +- **2025-07-15_Claude_Code_Spring_Boot_3.5_Migration_Plan.md** - Migration status |
| 326 | +- **openespi-common/CONTRIBUTING.md** - Contribution guidelines |
| 327 | +- **openespi-authserver/DEPLOYMENT_GUIDE.md** - Production deployment |
| 328 | +- **openespi-authserver/CERTIFICATE_AUTHENTICATION.md** - Client certificate auth |
0 commit comments