Skip to content

Commit 1261d79

Browse files
committed
feat(overview): surface premium in the Stack-by-coin-type table
Extend the EnrichedLot TS type with premium_usd, accumulate premium per bought/found source in the stack rollup, and render it as a component of the basis figure ("bought 3 ($3,497, incl. $137 prem)"), suppressed when zero. Deliberately not added to any melt/qty/fineOz total — premium is a memo. Refs: om-0pqe
1 parent aa5ffb0 commit 1261d79

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

web/app/src/lib/components/StackByType.svelte

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
let { report }: { report: Report } = $props()
1212
const r = $derived(report)
1313
14-
type Src = { qty: number; basis: number }
14+
// premium is a component of basis (paid over melt at acquisition), tracked as a
15+
// display memo alongside it — NEVER summed into melt/qty/fineOz.
16+
type Src = { qty: number; basis: number; premium: number }
1517
type Group = {
1618
key: string
1719
product: string
@@ -33,7 +35,7 @@
3335
g = {
3436
key, product: l.product, metal: l.metal, fineness: l.fineness,
3537
qty: 0, fineOz: 0, melt: 0,
36-
bought: { qty: 0, basis: 0 }, found: { qty: 0, basis: 0 },
38+
bought: { qty: 0, basis: 0, premium: 0 }, found: { qty: 0, basis: 0, premium: 0 },
3739
}
3840
m.set(key, g)
3941
}
@@ -43,6 +45,7 @@
4345
const src = l.activity === 'crh' ? g.found : g.bought
4446
src.qty += l.qty
4547
src.basis += l.basis_usd
48+
src.premium += l.premium_usd ?? 0 // memo only — deliberately NOT added to melt/qty/fineOz
4649
}
4750
return [...m.values()].sort((a, b) => b.melt - a.melt)
4851
})
@@ -55,6 +58,11 @@
5558
5659
// sourced from both bought + found — the case that "felt wrong", now unified
5760
const mixed = (g: Group) => g.bought.qty > 0 && g.found.qty > 0
61+
62+
// "bought 3 ($4,621, incl. $225 prem)" — premium surfaced AS A COMPONENT of the
63+
// basis figure, never as its own total. Suppressed when there's no premium.
64+
const srcLabel = (verb: string, s: Src) =>
65+
`${verb} ${num(s.qty)} (${money(s.basis)}${s.premium > 0 ? `, incl. ${money(s.premium)} prem` : ''})`
5866
</script>
5967

6068
<section class="space-y-2">
@@ -85,7 +93,7 @@
8593
{g.metal}{g.fineness ? ` · ${g.fineness}` : ''}
8694
{#if g.bought.qty > 0 || g.found.qty > 0}
8795
<span class={mixed(g) ? 'font-medium text-foreground' : ''}>
88-
&nbsp;·&nbsp;{#if g.bought.qty > 0}bought {num(g.bought.qty)} ({money(g.bought.basis)}){/if}{#if mixed(g)} · {/if}{#if g.found.qty > 0}found {num(g.found.qty)} ({money(g.found.basis)}){/if}
96+
&nbsp;·&nbsp;{#if g.bought.qty > 0}{srcLabel('bought', g.bought)}{/if}{#if mixed(g)} · {/if}{#if g.found.qty > 0}{srcLabel('found', g.found)}{/if}
8997
</span>
9098
{/if}
9199
</div>

web/app/src/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export interface EnrichedLot {
116116
face_value_usd: number
117117
acquired: string
118118
source: string
119+
premium_usd?: number // paid over melt at acquisition; a component of basis, display-only (omitted when 0)
119120
// CRH find taxonomy (ADR-006) — present on activity='crh' lots (omitted when empty/false).
120121
category?: string
121122
subcategory?: string

0 commit comments

Comments
 (0)