Module: Hecks::Adapters::PostgresEra::LineageManager::CoverageCheck
- Included in:
- Hecks::Adapters::PostgresEra::LineageManager
- Defined in:
- lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb
Overview
What a mint must prove before it may happen: the edge covers the whole diff, no identity path was re-keyed, and the audit's first two layers pass over the LIVE compiled chain.
Instance Method Summary collapse
-
#audit!(bluebook, lineage, chain, ordinal, edge) ⇒ Object
Layers 1 and 2 of the audit, over the LIVE compiled chain — before anything is minted, so a refusal leaves no half-born era.
-
#check_coverage!(registry, bluebook, held_bluebook, edge) ⇒ Object
Layer 1 against THIS edge specifically: every vanished or retyped path in the held→current diff must be explained, and every held aggregate must still be claimed.
-
#check_identity_unchanged!(bluebook, aggregate, held_aggregate, rules) ⇒ Object
An identity-path change is a RE-KEYING, not an ordinary translation — stored ids were fixed at write time under the old key, so this refuses UNLESS the edge declares a
rekeyfor this aggregate covering exactly that.
Instance Method Details
#audit!(bluebook, lineage, chain, ordinal, edge) ⇒ Object
Layers 1 and 2 of the audit, over the LIVE compiled chain — before anything is minted, so a refusal leaves no half-born era. (A convert meeting an unmapped value raises inside the preview query itself: same rollback-shaped outcome.)
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb', line 63 def audit!(bluebook, lineage, chain, ordinal, edge) violations = [] bluebook.aggregates.each do |aggregate| declared = edge.for_aggregate(aggregate.name) after = begin lineage.translated_latest(aggregate, ordinal, chain) rescue PG::Error => error raise Runtime::WiringError, "cannot mint era #{ordinal} of #{bluebook.name}: #{error..strip}" end before = if chain.size > 1 lineage.translated_latest(aggregate, ordinal, chain[0..-2]) else lineage.ancestor_latest(aggregate, ordinal, chain) end verdict = Translation::Audit.check(aggregate: aggregate, declared: declared, before: before, after: after) violations.concat(verdict.violations) end return if violations.empty? raise Runtime::WiringError, "cannot mint era #{ordinal} of #{bluebook.name}: the audit refused —\n - #{violations.join("\n - ")}" end |
#check_coverage!(registry, bluebook, held_bluebook, edge) ⇒ Object
Layer 1 against THIS edge specifically: every vanished or retyped path in the held→current diff must be explained, and every held aggregate must still be claimed. The refusal is EraGuard's own, byte for byte.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb', line 19 def check_coverage!(registry, bluebook, held_bluebook, edge) bluebook.aggregates.each do |aggregate| rules = Ports::Persistence::Lineage.from_declared(edge.for_aggregate(aggregate.name), aggregate.name) held_aggregate = held_bluebook.aggregate(rules&.ancestor_name || aggregate.name) next unless held_aggregate check_identity_unchanged!(bluebook, aggregate, held_aggregate, rules) uncovered = Runtime::EraGuard.uncovered_attributes(aggregate, held_aggregate, rules) Runtime::EraGuard.refuse_uncovered!(bluebook, aggregate, uncovered) unless uncovered.empty? unsafe = Runtime::EraGuard.unsafe_additions(aggregate, held_aggregate, rules) Runtime::EraGuard.refuse_unsafe_addition!(bluebook, aggregate, unsafe) unless unsafe.empty? end Runtime::EraGuard.check_vanished_aggregates!(registry, bluebook, held_bluebook) end |
#check_identity_unchanged!(bluebook, aggregate, held_aggregate, rules) ⇒ Object
An identity-path change is a RE-KEYING, not an ordinary
translation — stored ids were fixed at write time under the old
key, so this refuses UNLESS the edge declares a rekey for
this aggregate covering exactly that. rules.rekey? (see
Ports::Persistence::Lineage's own comment) is the single
source of truth every consumer of this fact asks — this is not
a second, independent check of declared.rekeys.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb', line 42 def check_identity_unchanged!(bluebook, aggregate, held_aggregate, rules) # The FULL declared path lists, in declaration order — never the # single-head shortcut, which is nil for every composite identity # and so would let two different composites compare as unchanged. return if held_aggregate.identity_paths == aggregate.identity_paths return if rules&.rekey? held_identity = Runtime::Identity.reading(held_aggregate) current_identity = Runtime::Identity.reading(aggregate) raise Runtime::WiringError, "cannot mint an era for #{bluebook.name}::#{aggregate.name}: its identity path changed " \ "(#{held_identity} → #{current_identity}), and that is a re-keying, not a translation — " \ "stored ids were minted under #{held_identity}, and no rule declares rows the same " \ "entity under a new key. Keep the identity path, declare a rekey rule, or migrate the " \ "data explicitly" end |