fix(content): add price_tier to brand layer schema, import, and V-B06 (#828 blocker)
price_tier was documented in D-189 §5 and present in brands.toml but silently discarded on import — absent from schema, INSERT, and V-B06. - Add price_tier TEXT column to brand_products CREATE TABLE - Add COLUMN_MIGRATIONS entry for ALTER TABLE on existing DBs - Add VALID_PRICE_TIERS constant (mass/premium/luxury/flagship/institutional) - Include price_tier in product_rows tuple and INSERT OR REPLACE - Add price_tier to V-B06 enum checks; skip NULL (nullable column) - Backfill 4 pre-amendment anchor brands (8 entries): Calloway flagship/premium, VGV luxury/premium, thrds luxury/premium, Bífröst flagship/luxury V-B01..V-B06 all pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,7 @@ CREATE TABLE IF NOT EXISTS brand_products (
|
||||
shadow_viable INTEGER NOT NULL DEFAULT 0,
|
||||
brand_tier TEXT NOT NULL,
|
||||
halo_brand_id TEXT REFERENCES brand_products(brand_product_id),
|
||||
price_tier TEXT,
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
@@ -177,6 +178,7 @@ COLUMN_MIGRATIONS = [
|
||||
("corporations", "behavioral_archetype", "TEXT"),
|
||||
("corporations", "supply_chain_role", "TEXT"),
|
||||
("corporations", "shadow_economy_access", "INTEGER DEFAULT 0"),
|
||||
("brand_products", "price_tier", "TEXT"),
|
||||
]
|
||||
|
||||
|
||||
@@ -743,6 +745,7 @@ VALID_VALUE_TRAJECTORIES = {"appreciating", "depreciating", "timeless"}
|
||||
VALID_SCARCITY_CLASSES = {"capped", "constrained", "scalable", "unlimited"}
|
||||
VALID_BRAND_TIERS = {"halo", "volume"}
|
||||
VALID_CURRENCY_DENOMINATIONS = {"tractus", "mark", "mixed", "sol_adjacent"}
|
||||
VALID_PRICE_TIERS = {"mass", "premium", "luxury", "flagship", "institutional"}
|
||||
|
||||
|
||||
def import_brands(
|
||||
@@ -780,6 +783,7 @@ def import_brands(
|
||||
int(p.get("shadow_viable", False)),
|
||||
p["brand_tier"],
|
||||
p.get("halo_brand_id"),
|
||||
p.get("price_tier"),
|
||||
))
|
||||
|
||||
input_rows = []
|
||||
@@ -797,8 +801,8 @@ def import_brands(
|
||||
value_trajectory, scarcity_class, product_subcategory,
|
||||
base_premium_multiplier, premium_floor, origin_system,
|
||||
terroir_locked, currency_denomination, shadow_viable,
|
||||
brand_tier, halo_brand_id
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
||||
brand_tier, halo_brand_id, price_tier
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
||||
product_rows,
|
||||
)
|
||||
conn.executemany(
|
||||
@@ -947,12 +951,15 @@ def validate_brands(conn: sqlite3.Connection) -> list[str]:
|
||||
("scarcity_class", VALID_SCARCITY_CLASSES),
|
||||
("brand_tier", VALID_BRAND_TIERS),
|
||||
("currency_denomination", VALID_CURRENCY_DENOMINATIONS),
|
||||
("price_tier", VALID_PRICE_TIERS),
|
||||
]
|
||||
for column, valid_set in enum_checks:
|
||||
bad = conn.execute(
|
||||
f"SELECT brand_product_id, {column} FROM brand_products"
|
||||
).fetchall()
|
||||
for pid, value in bad:
|
||||
if value is None:
|
||||
continue # nullable columns (e.g. price_tier) may be unset
|
||||
if value not in valid_set:
|
||||
errors.append(
|
||||
f"V-B06: brand_product '{pid}' has {column}='{value}' — "
|
||||
|
||||
Reference in New Issue
Block a user