Part of a set of structural observations — see #1695 (index) for context.
Description
eCalc uses Pydantic to provide input validation and JSON schema generation "for free." The trouble is that this is one of several independent representations of the same domain concept as it flows through the system. Tracing "compressor" through the codebase surfaces, at minimum:
- the YAML schema type —
yaml_energy_usage_model_compressor.py
- the core physics/domain model —
compressor/core/*, compressor/core/train/*
- the result object —
results/compressor.py
- the JSON/export-facing result —
presentation/json_result/result/results.py, presentation/exporter/dto/dtos.py
A separate DTO layer and a dedicated per-type runtime consumer wrapper existed at one point and have since been removed in favor of a generic consumer component — a genuine consolidation, one fewer hand-glued layer than there used to be, and worth acknowledging as progress in this direction. What remains is still converted by a dedicated mapper module (presentation/yaml/mappers/component_mapper.py, still 724 lines at the time I last looked); the presentation/yaml/mappers/ package as a whole had grown to over 5,000 lines. That's the real cost of this pattern: the same information gets re-modeled by hand several times over, with hand-written glue between every pair of adjacent layers, which is what a schema/serialization layer (or code generation from one canonical model) would otherwise buy for free.
Examples
—
Business/User Value
Fewer hand-written mapper layers means less code that has to change in lockstep every time a field is added to a component, and fewer places for the representations to silently drift out of sync with each other.
Files
yaml_energy_usage_model_compressor.py
compressor/core/* (and compressor/core/train/*)
results/compressor.py
presentation/json_result/result/results.py
presentation/exporter/dto/dtos.py
presentation/yaml/mappers/component_mapper.py
Part of a set of structural observations — see #1695 (index) for context.
Description
eCalc uses Pydantic to provide input validation and JSON schema generation "for free." The trouble is that this is one of several independent representations of the same domain concept as it flows through the system. Tracing "compressor" through the codebase surfaces, at minimum:
yaml_energy_usage_model_compressor.pycompressor/core/*,compressor/core/train/*results/compressor.pypresentation/json_result/result/results.py,presentation/exporter/dto/dtos.pyA separate DTO layer and a dedicated per-type runtime consumer wrapper existed at one point and have since been removed in favor of a generic consumer component — a genuine consolidation, one fewer hand-glued layer than there used to be, and worth acknowledging as progress in this direction. What remains is still converted by a dedicated mapper module (
presentation/yaml/mappers/component_mapper.py, still 724 lines at the time I last looked); thepresentation/yaml/mappers/package as a whole had grown to over 5,000 lines. That's the real cost of this pattern: the same information gets re-modeled by hand several times over, with hand-written glue between every pair of adjacent layers, which is what a schema/serialization layer (or code generation from one canonical model) would otherwise buy for free.Examples
—
Business/User Value
Fewer hand-written mapper layers means less code that has to change in lockstep every time a field is added to a component, and fewer places for the representations to silently drift out of sync with each other.
Files
yaml_energy_usage_model_compressor.pycompressor/core/*(andcompressor/core/train/*)results/compressor.pypresentation/json_result/result/results.pypresentation/exporter/dto/dtos.pypresentation/yaml/mappers/component_mapper.py