recon_gen.common.l2.coverage
coverage_for() — per-L2-primitive presence in <prefix>_transactions.
The Studio diagram’s coverage-tint chrome (X.4.c.5) needs a per-entity
“do you have data” answer keyed off the same node IDs the topology
emit produces. This module is the data fetcher: three GROUP BY queries
on <prefix>_transactions plus a derived chain-edge map, all keyed
to the topology IDs role__X / rail__X / tmpl__X /
chain__<parent>__<child>.
Why a separate module:
The query shape is the same across all four apps (it doesn’t ride on any one app’s dataset SQL); coupling it to either
apps/orcommon/html/would force one consumer to import the other.Studio’s diagram chrome (
common/html/_studio_routes.py) is the initial consumer, but the same fetcher is what the eventual ETL-engineeruncovered_railsscope (X.4.h) will reuse to decide what to fill — keeping it incommon/l2/matches that future symmetry.
Severability: this module imports only common/db.py (async pool
protocol), common/l2/primitives.py (the L2 model), and
common/l2/topology.py (the node-id helpers). It does NOT import
common/html/ — the coverage data flows the other way.
Functions
|
Stable ID for a chain edge in the topology coverage map. |
|
Compute per-L2-primitive row presence in |
|
For each TransferTemplate, count rows landing its required metadata keys. |
Classes
|
One L2 primitive's data presence + row count. |
|
Per-topology-element coverage from a single demo-DB snapshot. |
|
Per-template required-metadata-key landing tally. |
- class recon_gen.common.l2.coverage.CoverageEntry(present, count)[source]
Bases:
objectOne L2 primitive’s data presence + row count.
countis the absolute row count behindpresentso the chrome’s hover tooltip can say “12,304 rows” instead of just “yes”.- Parameters:
present (bool)
count (int)
- count: int
- present: bool
- class recon_gen.common.l2.coverage.CoverageMap(by_node_id, by_chain_edge_id)[source]
Bases:
objectPer-topology-element coverage from a single demo-DB snapshot.
Two maps:
by_node_id— keyed by the topology node IDs thattopology.py’s_role_id/_rail_id/_template_idhelpers emit. One entry per L2-declared role / rail / template — even an empty entity gets apresent=False, count=0record so the chrome can render absence as well as presence.by_chain_edge_id— keyed bychain__<parent>__<child>(the discriminator scheme matches the node-id prefix convention). A chain edge is “covered” when both endpoints (rail or template) have at least one transaction. Derived; no extra DB query.
- Parameters:
by_node_id (Mapping[str, CoverageEntry])
by_chain_edge_id (Mapping[str, CoverageEntry])
- by_chain_edge_id: Mapping[str, CoverageEntry]
- by_node_id: Mapping[str, CoverageEntry]
- class recon_gen.common.l2.coverage.TemplateMetadataCoverage(template_name, row_count, per_key)[source]
Bases:
objectPer-template required-metadata-key landing tally.
For one TransferTemplate,
row_countis the total rows tagged with that template_name;per_keymaps each required key (fromTransferTemplate.transfer_key+ each leg-rail’smetadata_keys) to the count of rows whose metadata JSON contains the key. BT.3’s coverage card readsper_key[k] == row_countto paint ✓-all-rows-have-it,per_key[k] == 0for ✗-missing, partial counts for the “12/14 rows have it” middle.- Parameters:
template_name (str)
row_count (int)
per_key (Mapping[str, int])
- per_key: Mapping[str, int]
- row_count: int
- template_name: str
- recon_gen.common.l2.coverage.chain_edge_id(parent, child)[source]
Stable ID for a chain edge in the topology coverage map.
Matches the
role__/rail__/tmpl__discriminator scheme so the SVG post-processor can key off the prefix in the chrome’s coverage paint.- Return type:
str- Parameters:
parent (str)
child (str)
- async recon_gen.common.l2.coverage.coverage_for(pool, prefix, instance, *, dialect)[source]
Compute per-L2-primitive row presence in
<prefix>_transactions.Three GROUP BY queries hit the DB once per call:
account_role→ role coveragerail_name→ rail coveragetemplate_name→ template coverage (NULL filtered, since most transfers are standalone-rail and carry NULLtemplate_name)
Chain edge coverage is derived: an edge is “covered” iff both parent + child names appear in either rail or template counts.
Iteration is over the L2-declared primitives (not the DB result set) so an L2-declared-but-unfed entity returns
present=False, count=0instead of being absent from the map entirely. The chrome surface needs to render absence too — that’s the integrator’s “is my ETL hooked up” signal.Computed on-demand (no caching). Studio’s audience is one user iterating, not a hot path; a 50-rail L2 against the demo DB returns in single-digit ms.
- Parameters:
pool (
AsyncConnectionPool) – AsyncConnectionPool against the demo DB.prefix (
str) – L2 instance prefix (e.g."sasquatch_pr"); used as the<prefix>_transactionsschema prefix.instance (
L2Instance) – The L2 model whose declared primitives drive the iteration set (so absence =present=False, count=0).dialect (
Dialect) – SQL dialect; drives column-name case-folding viacolumn_name(...).
- Return type:
- Returns:
A
CoverageMapwithby_node_idcovering every declared role / rail / template +by_chain_edge_idcovering every declared chain entry.
- async recon_gen.common.l2.coverage.metadata_coverage_per_template(pool, prefix, instance, *, dialect)[source]
For each TransferTemplate, count rows landing its required metadata keys.
The required-keys set unions the template’s own
transfer_keyplus each leg-rail’smetadata_keys. Counts use the same JSON-text quoted-key heuristicprobe.evaluate_predicateuses ("key"substring scan) — robust enough for the BT.3 coverage card; BT.4’s Triage will do proper JSON_VALUE / JSONPath extraction when the gap shape needs it.Iteration is over the L2’s declared templates so an empty-data instance still gets a complete result (every template returns a
row_count=0entry,per_keyempty for each required key).One query per template (per-template + per-key count is folded into a single SELECT with N conditional SUMs); studio’s audience is one user iterating, so the per-call cost is negligible.
- Return type:
Mapping[str,TemplateMetadataCoverage]- Parameters:
pool (AsyncConnectionPool)
prefix (str)
instance (L2Instance)
dialect (Dialect)