Every metric result must retain:
market_definition_version_id
metric_definition_version
data_release_ids
classification_vintages
crosswalk_version_ids
geography_vintage
deflator_series_id
calculation_timestamp
calculation_run_id
A market is defined as:
Market =
Product Scope
× Buyer Scope
× Geography Scope
× Supplier Scope
× Channel Scope
× Serviceability Scope
× Time Scope
× Price Basis
The canonical market cell is:
market_definition_version
× period
× geography
× NAPCS product leaf
× NAICS industry leaf
× demographic segment
× channel
Not every source will populate every dimension. Missing dimensions must be represented as unknown, not_applicable, or not_available, never silently omitted.
Consumer TAM =
Eligible consumer units
× Estimated annual category expenditure per eligible unit
× Product-fit allocation
Required inputs:
ACS or other population source
CEX UCC spending estimate
UCC → NAPCS crosswalk
Market demographic segment
Market geography definition
Price adjustment method
Required output fields:
estimated_households
estimated_consumer_units
nominal_tam
real_tam
confidence_grade
coverage_ratio
source_period
price_base_period
Industry Revenue TAM =
Sum of relevant Economic Census product receipts
or related supplier-market revenue
Required output fields:
economic_layer
selected_naics_scope
selected_napcs_scope
receipts_measure
geography
suppression_adjustment_method
nominal_tam
real_tam
Consumer TAM and industry-revenue TAM must remain separate until reconciliation.
reconciliation_ratio =
consumer_demand_tam / industry_revenue_tam
If the ratio is outside the approved tolerance range, the output must display:
reconciliation_status = 'investigate'
Potential explanations include:
business purchasing
tourism
online sales outside geography
intermediary sales
product-scope mismatch
industry-scope mismatch
timing mismatch
price-basis mismatch
crosswalk coverage gap
SAM =
TAM
× serviceability factor
× channel eligibility factor
× product-fit factor
× customer eligibility factor
Every factor must identify:
factor_name
value
evidence_type
rationale
owner
approval_status
SOM =
minimum(
SAM × attainable_share,
operational_capacity × revenue_per_served_unit
)
SOM must be published in scenario form:
conservative
base
upside
No single SOM figure may be shown without its scenario assumptions.
create table analytics.metric_price_basis (
metric_price_basis_id uuid primary key,
metric_name text not null,
source_series_id text,
source_series_name text,
index_type text not null check (
index_type in (
'cpi',
'ppi',
'pce_price_index',
'gdp_deflator',
'custom'
)
),
base_period text not null,
adjustment_method text not null,
product_match_confidence numeric(5,4),
notes text
);
Consumer spending:
Use matched CPI or PCE price index when available.
Producer revenue or input cost:
Use matched PPI series when available.
Broad economy comparison:
Use GDP deflator only when no more specific series is available.
Nominal-only source:
Retain nominal values even when a real-dollar estimate is also produced.
Nominal dollars
Real 2025 dollars
Deflated using CPI series [series_id]
Product-match confidence: medium
eligible households
consumer units
CEX spending estimates
PCE trends
Economic Census receipts
population growth
income growth
consumer-price movement
CBP establishments
NES nonemployer establishments
QCEW employment
QCEW payroll
OEWS occupation availability
OEWS wage levels
Economic Census industry receipts
Demand Intensity =
Estimated annual category demand
/
Eligible households
Supplier Density =
Relevant establishments
/
Eligible households
Labor Cost Pressure =
Relevant occupational wage index
/
National occupational wage index
Market Pressure Score =
z(Demand Intensity)
- z(Supplier Density)
- z(Labor Cost Pressure)
The dashboard label must read:
Market-pressure proxy
Not a direct measure of excess demand or economic equilibrium.
The platform must not label a result “price elasticity” unless it has observed quantity and price variation at a sufficiently granular level.
Minimum required fields:
market_id
product_id or NAPCS leaf
period
units_sold
net_price
promotion_flag
inventory_available
stockout_flag
channel
competitor_price when available
ln(quantity) =
market fixed effect
+ product fixed effect
+ period fixed effect
+ beta × ln(net price)
+ promotion controls
+ inventory controls
+ seasonality controls
+ error
Where:
beta = own-price elasticity
Without transaction-level quantity data, use:
price–spending association
price sensitivity proxy
consumer-price trend
real-spending trend
Do not use:
elasticity
demand curve
supply curve
causal price response
unless the model meets approved minimum-data requirements.
create table analytics.metric_calculation_run (
calculation_run_id uuid primary key,
market_definition_version_id uuid not null
references analytics.market_definition_version,
metric_definition_key text not null,
metric_definition_version text not null,
source_snapshot_ids jsonb not null,
crosswalk_ids jsonb not null,
parameter_set jsonb not null,
started_at timestamptz not null,
completed_at timestamptz,
run_status text not null check (
run_status in ('started', 'completed', 'failed', 'superseded')
),
initiated_by text not null,
calculation_hash text not null
);
The calculation_hash must change when any source release, crosswalk, market definition, model parameter, or transformation logic changes.
Every approved market definition must pass the following checks.
All NAICS codes exist in their declared vintage.
All NAPCS codes exist in their declared vintage.
No included parent and child taxonomy combination causes double counting.
All selected codes resolve to at least one active leaf.
All excluded codes are applied after inclusion expansion.
All required mappings have approved status.
Weights sum correctly.
Unmapped residual is visible.
No crosswalk member has expired before the metric period.
Proxy mappings are flagged.
Equal allocations are flagged.
All GEOIDs exist in the declared boundary vintage.
No geography is duplicated across inclusion roles without a documented reason.
Geographic weights sum correctly where partial geography is used.
Customer market and service area remain separately queryable.
TAM is non-negative.
SAM does not exceed TAM.
SOM does not exceed SAM.
Real-dollar outputs identify a deflator and base period.
All output values include source release metadata.
Suppressed source values are not exposed as fabricated point estimates.
Each computed metric receives a confidence grade.
A = direct measurement with official source alignment
B = strong source data with approved weighted crosswalk
C = modeled estimate with documented assumptions
D = proxy estimate with material coverage limitations
F = insufficient evidence; do not publish as a decision metric
Suggested scoring inputs:
taxonomy match quality
crosswalk coverage
crosswalk confidence
geographic granularity
demographic granularity
source recency
suppression level
price-series match quality
assumption burden
Example output:
Consumer TAM: $18.4M
Confidence: B
Coverage: 92%
Primary limitation: local demand estimated from national expenditure behavior.
Market:
Family-oriented physical game, puzzle, and activity rentals.
Customer market:
Households within the defined Hampton Roads service area.
Target segment:
Households with children under 18 and household income above the selected minimum threshold.
Product scope:
NAPCS codes representing relevant physical games, puzzles, and family activity products.
Supplier scope:
Relevant specialty retail, rental, entertainment, and event-service NAICS industries.
Channels:
Direct rental, local delivery, event-based rental, and online reservation.
Time basis:
Calendar year.
Price basis:
Nominal dollars and real 2025 dollars.
Serviceability:
Within 30 minutes of approved operating locations or within approved delivery zones.
Eligible households
× annual spending on relevant categories
× rental-addressable share
= consumer-demand TAM
Consumer-demand TAM
× households inside service area
× households reachable through approved channels
× households compatible with rental model
= SAM
minimum(
SAM × attainable capture rate,
annual rental capacity × revenue per rental
)
= SOM
Retail purchase spending is not automatically equivalent to rental-market demand.
The rental-addressable share must be modeled, tested, or supported by customer research.
GET /api/analytics/markets/{market_key}/versions/{version}
Response:
{
"market_key": "family_play_rentals_hampton_roads",
"version": 1,
"status": "approved",
"product_scope": {
"taxonomy": "NAPCS",
"vintage": "2022",
"resolved_leaf_count": 14
},
"industry_scope": {
"taxonomy": "NAICS",
"vintage": "2022",
"resolved_leaf_count": 9
},
"geography_scope": {
"customer_market": ["..."],
"service_area": ["..."]
},
"price_basis": {
"nominal": true,
"real": true,
"base_period": "2025"
},
"confidence_policy": "standard"
}
POST /api/analytics/metric-runs
{
"market_definition_version_id": "uuid",
"metric_definition_key": "consumer_tam",
"period_start": "2025-01-01",
"period_end": "2025-12-31",
"scenario": "base",
"parameters": {
"normalize_to_mapped_coverage": false,
"deflator_preference": "matched_product_series"
}
}
GET /api/analytics/metric-runs/{calculation_run_id}
Required response fields:
{
"metric_name": "Consumer TAM",
"value_nominal": 18400000,
"value_real": 17600000,
"real_dollar_base_period": "2025",
"confidence_grade": "B",
"coverage_ratio": 0.92,
"market_definition_version_id": "uuid",
"crosswalk_versions": ["uuid"],
"source_releases": ["uuid"],
"calculation_hash": "sha256"
}