[object Object]

← back to Lifestyle Asset Intel

yolo tick #16: exotic / special-edition badges + audit-test race fix

447537f7bb7ff8a6bde38c1e62b1ec25b90cbf40 · 2026-05-10 07:55:57 -0700 · Steve Abrams

Surface canonical_assets.attrs.exotic and attrs.special_edition on the
console grid, family pages, and asset detail h1 — quick visual signal
for the 14 Sotheby's-sourced exotic configs added in tick #13. Pure
EJS conditional + CSS, no schema changes.

  .exotic-badge   — accent-tinted pill (e.g., "EXOTIC" on Niloticus
                    Himalaya, Crocodile, Alligator, Lizard configs)
  .edition-badge  — warn-tinted pill (e.g., "FAUBOURG", "RAINY DAYS",
                    "MIDAS" on the Sotheby's special-edition lots)

lib/valuation.listAssets now returns ca.attrs in the SELECT so the
templates can read attrs.exotic and attrs.special_edition without a
second query. valueAsset() already returned attrs as part of the
asset block.

Audit test fix: tests/audit.test.js "GET /api/health is NOT logged"
was racing against parallel test files (node --test runs files
concurrently) — other tests' audit rows landed during the 200ms
sleep, inflating the unfiltered COUNT(*). Tightened the assertion
to filter `WHERE route = '/api/health'` so the test only counts
its own writes. Caught a real flake, not a regression.

44/44 tests green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 447537f7bb7ff8a6bde38c1e62b1ec25b90cbf40
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sun May 10 07:55:57 2026 -0700

    yolo tick #16: exotic / special-edition badges + audit-test race fix
    
    Surface canonical_assets.attrs.exotic and attrs.special_edition on the
    console grid, family pages, and asset detail h1 — quick visual signal
    for the 14 Sotheby's-sourced exotic configs added in tick #13. Pure
    EJS conditional + CSS, no schema changes.
    
      .exotic-badge   — accent-tinted pill (e.g., "EXOTIC" on Niloticus
                        Himalaya, Crocodile, Alligator, Lizard configs)
      .edition-badge  — warn-tinted pill (e.g., "FAUBOURG", "RAINY DAYS",
                        "MIDAS" on the Sotheby's special-edition lots)
    
    lib/valuation.listAssets now returns ca.attrs in the SELECT so the
    templates can read attrs.exotic and attrs.special_edition without a
    second query. valueAsset() already returned attrs as part of the
    asset block.
    
    Audit test fix: tests/audit.test.js "GET /api/health is NOT logged"
    was racing against parallel test files (node --test runs files
    concurrently) — other tests' audit rows landed during the 200ms
    sleep, inflating the unfiltered COUNT(*). Tightened the assertion
    to filter `WHERE route = '/api/health'` so the test only counts
    its own writes. Caught a real flake, not a regression.
    
    44/44 tests green.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 lib/valuation.js    |  2 +-
 public/css/app.css  | 15 +++++++++++++++
 tests/audit.test.js | 11 +++++++++--
 views/asset.ejs     |  2 ++
 views/family.ejs    |  2 +-
 views/index.ejs     |  2 +-
 6 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/lib/valuation.js b/lib/valuation.js
index d3f607a..bee13f8 100644
--- a/lib/valuation.js
+++ b/lib/valuation.js
@@ -320,7 +320,7 @@ async function listAssets(opts) {
     `SELECT ca.id, ca.slug,
             mf.name AS family_name, mf.slug AS family_slug,
             b.name  AS brand_name,  b.slug  AS brand_slug,
-            ca.size, ca.material, ca.color, ca.hardware, ca.region,
+            ca.size, ca.material, ca.color, ca.hardware, ca.region, ca.attrs,
             vs.q10, vs.q50, vs.q90, vs.liquidity_score AS seed_liquidity_score,
             vs.confidence, vs.expected_dts AS seed_expected_dts,
             vs.comp_count, vs.as_of,
diff --git a/public/css/app.css b/public/css/app.css
index 8396e1e..80b12b6 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -178,6 +178,21 @@ tfoot tr.totals th, tfoot tr.totals td {
   font-weight: 600; color: var(--fg);
 }
 
+/* exotic + special-edition badges (v0.2) */
+.exotic-badge, .edition-badge {
+  display: inline-block;
+  font-size: 0.62em;
+  font-weight: 700;
+  letter-spacing: 0.06em;
+  padding: 0.12rem 0.45rem;
+  border-radius: 999px;
+  vertical-align: 0.15em;
+  margin-left: 0.35rem;
+  font-family: var(--mono);
+}
+.exotic-badge { background: color-mix(in srgb, var(--accent) 22%, var(--card)); color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 50%, var(--line)); }
+.edition-badge { background: color-mix(in srgb, var(--warn) 22%, var(--card)); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 50%, var(--line)); }
+
 /* MSRP / premium-to-retail block (v0.2) */
 .msrp-block .premium-cell { background: color-mix(in srgb, var(--accent) 14%, var(--card)); border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
 .msrp-block .premium-val { color: var(--accent); font-size: 1.05em; }
diff --git a/tests/audit.test.js b/tests/audit.test.js
index 049706c..7fb4d88 100644
--- a/tests/audit.test.js
+++ b/tests/audit.test.js
@@ -90,11 +90,18 @@ test('GET /api/valuation/:slug records a row in valuation_calls', async () => {
 });
 
 test('GET /api/health is NOT logged (skipped per SKIP_PATHS)', async () => {
-  const before = await pool.query(`SELECT COUNT(*)::int AS n FROM valuation_calls`);
+  // Filter on route='/api/health' so we don't race against other parallel
+  // test files writing audit rows for OTHER routes during the await.
+  const HEALTH_FILTER = `route = '/api/health'`;
+  const before = await pool.query(
+    `SELECT COUNT(*)::int AS n FROM valuation_calls WHERE ${HEALTH_FILTER}`
+  );
   const r = await getJson('/api/health');
   assert.equal(r.status, 200);
   await new Promise((res) => setTimeout(res, 200));
-  const after = await pool.query(`SELECT COUNT(*)::int AS n FROM valuation_calls`);
+  const after = await pool.query(
+    `SELECT COUNT(*)::int AS n FROM valuation_calls WHERE ${HEALTH_FILTER}`
+  );
   assert.equal(after.rows[0].n, before.rows[0].n, 'health probe should not be audited');
 });
 
diff --git a/views/asset.ejs b/views/asset.ejs
index dc56fbd..5e5bfb6 100644
--- a/views/asset.ejs
+++ b/views/asset.ejs
@@ -5,6 +5,8 @@
     <%= data.asset.brand %>
     <a href="/family/<%= (data.asset.family || '').toLowerCase() %>"><%= data.asset.family %></a>
     <%= data.asset.size || '' %>
+    <% if (data.asset.attrs && data.asset.attrs.exotic) { %><span class="exotic-badge" title="Exotic skin or special edition">EXOTIC</span><% } %>
+    <% if (data.asset.attrs && data.asset.attrs.special_edition) { %><span class="edition-badge" title="Special edition: <%= data.asset.attrs.special_edition %>"><%= String(data.asset.attrs.special_edition).toUpperCase() %></span><% } %>
   </h1>
   <p class="muted">
     <%= data.asset.material || '—' %> · <%= data.asset.color || '—' %> · <%= data.asset.hardware || '—' %>
diff --git a/views/family.ejs b/views/family.ejs
index c779fad..1178a23 100644
--- a/views/family.ejs
+++ b/views/family.ejs
@@ -39,7 +39,7 @@
           <a class="card" href="/asset/<%= a.slug %>">
             <div class="card-head">
               <span class="brand-tag"><%= a.brand_name %></span>
-              <span class="family-tag"><%= a.family_name %> <%= a.size || '' %></span>
+              <span class="family-tag"><%= a.family_name %> <%= a.size || '' %><% if (a.attrs && a.attrs.exotic) { %> <span class="exotic-badge" title="Exotic skin or special edition">EXOTIC</span><% } %></span>
             </div>
             <div class="card-body">
               <div class="material"><%= a.material || '—' %><% if (a.color) { %> · <%= a.color %><% } %><% if (a.hardware) { %> · <%= a.hardware %><% } %></div>
diff --git a/views/index.ejs b/views/index.ejs
index 05e9947..e709cda 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -42,7 +42,7 @@
          data-asof="<%= a.as_of || '' %>">
         <div class="card-head">
           <span class="brand-tag"><%= a.brand_name %></span>
-          <span class="family-tag"><%= a.family_name %> <%= a.size || '' %></span>
+          <span class="family-tag"><%= a.family_name %> <%= a.size || '' %><% if (a.attrs && a.attrs.exotic) { %> <span class="exotic-badge" title="Exotic skin or special edition">EXOTIC</span><% } %></span>
         </div>
         <div class="card-body">
           <div class="material"><%= a.material || '—' %><% if (a.color) { %> · <%= a.color %><% } %><% if (a.hardware) { %> · <%= a.hardware %><% } %></div>

← db84b94 yolo tick #15: launchd-driven overnight autonomous loop  ·  back to Lifestyle Asset Intel  ·  snapshot: 6 file(s) changed, ~6 modified 06d377f →