feat(integrator): generate battery templates per category - #237
Open
LKSNDRTMLKV wants to merge 2 commits into
Open
feat(integrator): generate battery templates per category#237LKSNDRTMLKV wants to merge 2 commits into
LKSNDRTMLKV wants to merge 2 commits into
Conversation
The shipped battery template had fifteen columns and its own example rows imported cleanly then failed publish on around forty missing mandatory data points, because what a battery owes is decided per category and one file cannot carry three obligations; the templates are now generated from the same rules table the publish gate reads, the importer fills the thirty-odd fields it used to hardcode as None, and a round-trip test drives template to import to content gate for all three categories. Three and not five because Art. 77(1) gives a passport only to LMT, industrial above 2 kWh and electric-vehicle batteries.
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 84 |
| Duplication | -2 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on
fix/scope-gate-and-webhook-pinning— review that first, or read this diff alone (one commit).The gap
GET /integrator/api/v1/templates/batteryserved a fifteen-column CSV. Its owntwo example rows imported cleanly and then failed publish on ~40 missing
mandatory data points, none of which the template had a column for. The
bulk-import path — the documented way to onboard at volume, and the only one
with a first-party template — could therefore only ever produce records that
were dead on arrival.
The publish gate was right; the template was the gap, and so was the importer:
it hardcoded ~30
BatteryDatafields toNoneunder a comment reading "LeftNone until the template gains columns for them." The template never did.
Three templates, not one — and not five
batteryis gone. What a battery owes is decided per category: 46 mandatorydata points for EV, 45 for LMT, 38 for industrial. The clearest case is
StateOfHealth, which is a sum type because Annex VII Part A is two disjointlists — an EV battery reports state of certified energy alone, stationary and
LMT batteries report five parameters. One file would have to offer both and
accept a combination the annex does not permit.
Three rather than five because Art. 77(1) gives a passport only to "each LMT
battery, each industrial battery with a capacity greater than 2 kWh and each
electric vehicle battery". Portable and SLI bear no passport obligation, which
is also why the rules table answers
Unknownfor them rather than guessing.The bare
batterykey now 404s with that explanation rather than a bare list.Generated, not committed
A committed CSV drifts the moment a data point moves, and nothing notices —
which is exactly how a fifteen-column template survived the arrival of the
content gate.
domain::battery_templateis a column contract; the templates arerendered from it, and tests assert:
mandatory_fieldsdemands for a category has a column(
permits_presence, soConditionalis allowed andNotApplicableis not)The test that defines this as closed
every_battery_template_row_satisfies_the_publish_content_gatedrives the wholeoperator path: render the template, import its own example row, and ask the
publish gate's own question of the result. Verified live as well — for all three
categories, template → import →
POST /publish→ 200, with the rightper-category shape in the stored record (EV gets
electricVehiclestate ofhealth and a dynamic-performance block; industrial gets
stationaryOrLmtand nodynamic-performance block, which is correct — it is
Conditionalthere).Flat-file conventions
Four, all following the
material_N_*convention the bill of materials alreadyused: repeating groups (
cathode_1_name, …), nested blocks(
dynamicPerformance_ratedCapacityAh, …), a two-column range, and asemicolon-delimited list. Absence is never zero — a blank column parses to
None, because an invented0.0for recycled cobalt content is a falsedeclaration rather than a placeholder.
Two things found on the way
battery-evbefore the dispatch that understood it was ever reached. Both nowgo through one predicate, so an operator can post
battery-evback to thename they downloaded.
TemperatureRangeandHazardousSubstanceare#[non_exhaustive]indpp-domainwith neither a constructor norDefault, so this crate cannotbuild one with a struct expression. Constructed through their own
Deserializefor now — the sanctioned path the attribute leaves open —rather than blocking this behind a core release and a repin. Constructors in
core are the better fix.
just checkgreen (964 tests),just openapi-checkgreen.