Skip to content

Conversation

@dfcoffin
Copy link
Contributor

Summary

  • Implements Phase 25: EndDevice entity with full ESPI 4.0 XSD compliance
  • Completes DTO cleanup across ALL customer and usage domain DTOs (13 total)
  • Adds integration tests backfill for Phases 18, 23, 24, 25 (8 new test files)
  • Fixes NotificationMethodKind enum to match customer.xsd specification
  • Resolves JAXB OffsetDateTime marshalling issues

Phase 25: EndDevice Implementation

New Components

✅ EndDeviceMapper.java - Entity-to-DTO mapping with LifecycleDateMapper and AcceptanceTestMapper
✅ EndDeviceRepository.java - JPA repository
✅ EndDeviceService.java + EndDeviceServiceImpl.java - Service layer
✅ EndDeviceDtoTest.java - XML marshalling tests
✅ EndDeviceRepositoryTest.java - Repository tests

EndDeviceDto Structure

  • Rewritten to match ESPI 4.0 customer.xsd structure (lines 539-881)
  • Added 16 XSD-compliant fields (12 Asset + 4 EndDevice)
  • Removed Atom protocol fields (id, published, updated, links)
  • Proper namespace: http://naesb.org/espi/customer

ESPI 4.0 DTO Cleanup (Breaking Change)

Affected DTOs (13 files)

Customer Domain (4 DTOs):

  • CustomerDto
  • CustomerAccountDto
  • CustomerAgreementDto
  • ServiceLocationDto

Usage Domain (9 DTOs):

  • UsagePointDto
  • MeterReadingDto
  • IntervalBlockDto
  • ReadingTypeDto
  • TimeConfigurationDto
  • UsageSummaryDto
  • ElectricPowerQualitySummaryDto
  • ApplicationInformationDto
  • AuthorizationDto

Changes Applied

  • ❌ Removed id field (Long) from all DTOs
  • ❌ Removed uuid field (String) from all DTOs
  • ✅ Resource DTOs now contain ONLY XSD-defined fields
  • ✅ AtomEntryDto handles all Atom protocol metadata (id, published, updated, links)
  • ✅ MapStruct: @Mapping(target = "id", ignore = true) in toEntity methods only
  • ✅ Service layer maps: entity.id ↔ AtomEntryDto.id

Integration Tests Backfill (8 new files)

Phase 18 Backfill: CustomerAccount

  • CustomerAccountMySQLIntegrationTest.java (17KB)
  • CustomerAccountPostgreSQLIntegrationTest.java (17KB)

Phase 23 Backfill: ServiceLocation

  • ServiceLocationMySQLIntegrationTest.java (18KB)
  • ServiceLocationPostgreSQLIntegrationTest.java (18KB)

Phase 24 Backfill: CustomerAgreement

  • CustomerAgreementMySQLIntegrationTest.java (15KB)
  • CustomerAgreementPostgreSQLIntegrationTest.java (15KB)

Phase 25: EndDevice

  • EndDeviceMySQLIntegrationTest.java (17KB)
  • EndDevicePostgreSQLIntegrationTest.java (17KB)

Each integration test follows consistent pattern:

  • 3 @nested classes: CRUD Operations, Bulk Operations, Embedded Objects Persistence
  • Tests with MySQL and PostgreSQL via TestContainers
  • Enhanced TestDataBuilders with 4 new helper methods

Bug Fixes

NotificationMethodKind Enum Alignment

Issue: Java enum values didn't match customer.xsd enumeration

Before:

  • EMAIL, PHONE, SMS, LETTER, IN_PERSON, OTHER

After (matches XSD):

  • CALL, EMAIL, LETTER, OTHER, IVR

XSD Reference: customer.xsd lines 1961-1996

JAXB OffsetDateTime Marshalling

Issue: OffsetDateTime fields serializing as empty elements

Fix: Added @XmlJavaTypeAdapter(OffsetDateTimeAdapter.class) to:

  • LifecycleDateDto: manufacturedDate, installationDate
  • AcceptanceTestDto: dateTime

Result: Proper ISO-8601 timestamp serialization in XML

Test Constructor Signature Updates

Fixed 46 constructor calls across 16 test files:

  • UsageExportServiceTest.java (4 calls)
  • CustomerExportServiceTest.java (4 calls)
  • TimeConfigurationDtoTest.java (13 calls)
  • SubscriptionMapperTest.java (1 call)
  • CustomerDtoTest.java, CustomerDtoMarshallingTest.java, CustomerXmlDebugTest.java (8 calls)
  • JaxbXmlMarshallingTest.java, UsageXmlDebugTest.java, MigrationVerificationTest.java (12 calls)
  • SubscriptionDtoTest.java (3 calls)
  • CustomerAgreementDtoTest.java (2 calls)
  • ServiceLocationDtoTest.java (2 calls)

Pattern Applied:

// BEFORE
new CustomerDto("uuid", organisation, kind, ...)

// AFTER
new CustomerDto(organisation, kind, ...)

ElectronicAddressDto Import Fixes

Issue: Tests referencing CustomerDto.ElectronicAddressDto (nested class)

Fix: Updated 5 files:

  • Added import: import org.greenbuttonalliance.espi.common.dto.customer.ElectronicAddressDto;
  • Changed references: CustomerDto.ElectronicAddressDtoElectronicAddressDto

Test Results

Unit Tests

Tests run: 654, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

Integration Tests

Tests run: 99, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

Coverage

  • EndDevice entity: 18 tests passing
  • CustomerAccount: 8 tests passing
  • ServiceLocation: 8 tests passing
  • CustomerAgreement: 8 tests passing
  • All DTO marshalling: passing
  • All repository operations: passing

Database Migration

✅ Verified end_devices table in V3__Create_additiional_Base_Tables.sql

  • All 16 EndDevice XSD fields properly mapped
  • Status field correctly references status embedded object
  • LifecycleDate and AcceptanceTest embedded objects configured
  • ElectronicAddress collection table created

ESPI 4.0 Compliance Achievement

Customer Domain DTOs - All strictly XSD-compliant
Usage Domain DTOs - All strictly XSD-compliant
Resource DTOs - Contain ONLY XSD fields (no Atom metadata)
AtomEntryDto - Handles id, published, updated, links
MapStruct Mappings - Proper ignore patterns
Service Layer - Correct entity.id ↔ AtomEntryDto.id mapping
NotificationMethodKind - Matches customer.xsd enumeration
JAXB Marshalling - OffsetDateTime fields serialize correctly

Breaking Changes

⚠️ DTO Constructor Signatures Changed
All DTO constructors no longer accept id or uuid parameters. Code using these constructors must be updated:

// OLD
CustomerDto customer = new CustomerDto("uuid-123", org, kind, ...);

// NEW
CustomerDto customer = new CustomerDto(org, kind, ...);

⚠️ NotificationMethodKind Enum Values Changed

  • PHONECALL
  • SMS → removed (not in XSD)
  • IN_PERSON → removed (not in XSD)
  • IVR → added (from XSD)

Migration Guide

For Developers

  1. Update DTO constructor calls - remove first id/uuid parameter
  2. Update NotificationMethodKind references: PHONECALL
  3. Ensure ElectronicAddressDto imports are correct (top-level class)
  4. Run full test suite to verify: mvn test

For API Consumers

  • XML structure unchanged - DTOs still serialize correctly
  • Atom protocol metadata now exclusively in AtomEntryDto wrapper
  • No changes to REST API endpoints required

Files Changed

  • 60 files changed
  • 4,310 insertions(+), 406 deletions(-)
  • 16 new files created

Checklist

  • Phase 25: EndDevice entity, mapper, repository, service implemented
  • All 13 DTOs cleaned (id/uuid fields removed)
  • JAXB OffsetDateTime marshalling fixed
  • NotificationMethodKind enum aligned with XSD
  • 8 integration test files created (Phases 18, 23, 24, 25)
  • All 46 test constructor calls fixed
  • ElectronicAddressDto import issues resolved
  • Unit tests: 654 passing
  • Integration tests: 99 passing
  • Database migration verified
  • Flyway scripts validated

🤖 Generated with Claude Code

dfcoffin and others added 5 commits January 27, 2026 23:51
…t backfill

- Complete EndDevice ESPI 4.0 schema compliance plan
- Backfill missing integration tests for Phases 18, 23, 24
- 17 files total: 2 modified, 15 created
- Expected 756+ tests (660 unit + 96 integration)

Related to #28 Phase 25
- Extract ElectronicAddressDto from CustomerDto nested class
- Extract LifecycleDateDto from EndDeviceDto nested class
- Extract AcceptanceTestDto from EndDeviceDto nested class
- Update all references across DTOs and mappers
- Remove duplicate equals/hashCode from MeterEntity (inherited from EndDeviceEntity)

Benefits:
- No artificial dependencies (EndDevice no longer depends on CustomerDto)
- Better reusability (Meter will use LifecycleDateDto and AcceptanceTestDto)
- Consistent pattern (matches StatusDto being separate)
- Easier testing and maintenance

Related to #28 Phase 25

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Resource DTOs must ONLY contain fields defined in customer.xsd.
- Removed id field (not in XSD)
- Removed uuid/@XmlAttribute mRID (not in XSD)

Per ESPI 4.0 Atom protocol pattern:
- AtomEntryDto handles resource identification (<id> element)
- Resource DTOs contain ONLY XSD-defined fields
- Service layer maps between entity.id and AtomEntryDto.id

This ensures:
✅ Strict XSD schema compliance
✅ No mRID attribute on resource elements
✅ Clean separation: Atom wrapper vs resource content

Related to #28 Phase 25

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
…88)

## Phase 25: EndDevice Implementation

### New Files
- EndDeviceMapper.java - Entity-to-DTO mapping with LifecycleDateMapper and AcceptanceTestMapper
- EndDeviceRepository.java - JPA repository for EndDevice persistence
- EndDeviceService.java + EndDeviceServiceImpl.java - Service layer for EndDevice operations
- EndDeviceDtoTest.java - Unit tests for EndDevice DTO XML marshalling
- EndDeviceRepositoryTest.java - Unit tests for EndDevice repository operations

### EndDeviceDto Enhancements
- Rewritten to match ESPI 4.0 customer.xsd structure
- Added 16 XSD-compliant fields (12 Asset + 4 EndDevice)
- Removed Atom protocol fields (id, published, updated, links)
- Proper namespace: http://naesb.org/espi/customer

## ESPI 4.0 DTO Cleanup (All DTOs)

### Customer Domain DTOs (4 files)
- CustomerDto, CustomerAccountDto, CustomerAgreementDto, ServiceLocationDto
- Removed uuid field for strict XSD compliance
- AtomEntryDto now handles all Atom protocol metadata

### Usage Domain DTOs (9 files)
- UsagePointDto, MeterReadingDto, IntervalBlockDto, ReadingTypeDto
- TimeConfigurationDto, UsageSummaryDto, ElectricPowerQualitySummaryDto
- ApplicationInformationDto, AuthorizationDto
- Removed id and uuid fields for strict ESPI 4.0 compliance
- Resource DTOs contain ONLY XSD-defined fields

### JAXB Marshalling Fixes
- Added @XmlJavaTypeAdapter(OffsetDateTimeAdapter.class) to:
  - LifecycleDateDto: manufacturedDate, installationDate
  - AcceptanceTestDto: dateTime
- Ensures proper ISO-8601 timestamp serialization in XML

### NotificationMethodKind Enum Fix
- Updated to match customer.xsd enumeration exactly
- XSD values: CALL, EMAIL, LETTER, OTHER, IVR
- Fixed: PHONE → CALL, removed SMS and IN_PERSON (not in XSD)

## Integration Tests (8 new files)

### Phase 18 Backfill
- CustomerAccountMySQLIntegrationTest.java
- CustomerAccountPostgreSQLIntegrationTest.java

### Phase 23 Backfill
- ServiceLocationMySQLIntegrationTest.java
- ServiceLocationPostgreSQLIntegrationTest.java

### Phase 24 Backfill
- CustomerAgreementMySQLIntegrationTest.java
- CustomerAgreementPostgreSQLIntegrationTest.java

### Phase 25
- EndDeviceMySQLIntegrationTest.java
- EndDevicePostgreSQLIntegrationTest.java

### TestDataBuilders Enhancement
- Added 4 helper methods: createValidCustomerAccount, createValidServiceLocation
  createValidCustomerAgreement, createValidEndDevice

## Test Fixes (16 files)

### DTO Constructor Signature Updates
- Fixed 46 constructor calls across 16 test files
- Removed first uuid/id parameter to match cleaned DTO signatures
- Pattern: new CustomerDto(uuid, ...) → new CustomerDto(...)

### ElectronicAddressDto Import Fixes
- Updated imports in 5 files to reference standalone class
- Changed CustomerDto.ElectronicAddressDto → ElectronicAddressDto

## Database Migration
- Verified end_devices table in V3__Create_additiional_Base_Tables.sql
- All 16 EndDevice XSD fields properly mapped to database columns

## Test Results
- Unit Tests: 654 tests, 0 failures, 0 errors
- Integration Tests: 99 tests, 0 failures, 0 errors
- BUILD SUCCESS

## ESPI 4.0 Compliance Achievement
✅ All customer domain DTOs strictly XSD-compliant
✅ All usage domain DTOs strictly XSD-compliant
✅ Resource DTOs contain ONLY XSD fields (no Atom metadata)
✅ AtomEntryDto handles id, published, updated, links
✅ MapStruct: @mapping(target = "id", ignore = true) in toEntity methods only
✅ Service layer maps entity.id ↔ AtomEntryDto.id

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@dfcoffin dfcoffin merged commit ccac8e5 into main Jan 29, 2026
5 checks passed
@dfcoffin dfcoffin deleted the feature/schema-compliance-phase-25-end-device branch January 29, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants