← back to index

U17 — Per-template attribute extra-price override + multi-select reworkPROD

Notion test-run #3 doc item #15 — three intertwined complaints on the per-product attribute editor: (1) only show values added to THIS template; (2) replace pill-chip-row picker with multi-select dropdown; (3) per-template extra-price override so editing FRAPPE=+$1.99 on Café Latte stops bleeding to every other template using "Drink Type". Karou picked bundled — all three in one slice. Narong's locked design (in the Notion note): "The extra price is always configured in Product Template › Variant/Modifier › Configure. Configuration › Attributes can be used to change the Name of the attribute or the Default Extra Price, but it's global whereas the change in each Product stays local."

Summary

Status
11/11 prod · 51/51 regression = 62/62 · shipped
Commit
nix-cafe acedcb7 · nix-outdoor-sales-backend be268ed
Files
6 modified + 2 new · 1 migration · ~640 LOC net
Migration
cafe.product_template_attribute_line_value_rel.price_extra_usd_override NUMERIC(12,2) NULL

Two-layer data model

LayerColumnEditor
Global default
cafe.product_attribute_value.price_extra_usd (existing)
/cafe/settings/attributes (U15-C admin)
Per-template override
NEW cafe.product_template_attribute_line_value_rel.price_extra_usd_override
NEW /cafe/products/[id]/attributes/[lineId]

Effective extra price in every read path: COALESCE(rel.price_extra_usd_override, av.price_extra_usd). Null override = use global default.

What ships

11/11 prod checks

Pre-flight: seed 2 throwaway templates sharing 1 attribute + 1 value (global default $1.00) on lumiere via raw SQL
SSO login
Product detail (/cafe/products/[A]): multi-select picker rendered · summary chip for the seeded value visible · Configure link to /products/[A]/attributes/[lineA] visible
Configure page: table + Extra Price input visible · placeholder shows 1.00 (default)
Type override 2.50 → Save → "Override saved · global default $1.00" flag appears
Reload Configure page → input pre-populated with 2.50
Load-bearing cross-template isolation: DB probe confirms template A override = 2.50, template B override = NULL (template B still resolves to the global default)
Clear override → blank input → Save → "Override saved" flag gone
DB: template A override now NULL after clear → effective price reverts to global default
No HTTP 5xx during the U17 flow
Cleanup: delete seeded templates + attribute + value

Screenshots (click to enlarge)

Mid-Gate finds

Architectural notes

Regression sweep — 51/51

11/11 + 51/51 = 62/62 prod tests green on the karouna-dev branch.
test-phase1-prod.mjs11/11
test-phase2-sso-outdoor-prod.mjs6/6
test-m1-prod.mjs10/10
test-r7-prod.mjs14/14
test-r8-prod.mjs4/4
test-phase2-cafe-multishop-prod.mjs6/6
23rd validation of feedback_phase2_cafe_multishop_solo_retry.