Skip to content

Commit 9f52830

Browse files
fix: uniqness od scenarios in Comapre tab
1 parent c14b0b1 commit 9f52830

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

src/lib/shared/db-schema.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,4 +1078,28 @@ function runDataMigrations(db: DatabaseConnection): void {
10781078
db.prepare("ALTER TABLE pool_tiers ADD COLUMN pool_size_basis TEXT NOT NULL DEFAULT 'absolute'").run();
10791079
db.prepare("DELETE FROM scenario_results WHERE scenario_id IN (SELECT id FROM scenarios WHERE pool_tier_id IS NOT NULL)").run();
10801080
}
1081+
1082+
// Migration 24: scenario_results never had a uniqueness constraint on scenario_id, and
1083+
// saveResults() always generates a fresh row id, so every recalculation left the previous
1084+
// cached row orphaned instead of replacing it. Duplicate rows made a single scenario appear
1085+
// multiple times anywhere that LEFT JOINs scenario_results (e.g. scenariosRepository.getAll(),
1086+
// used by the scenarios list and Compare pages). Dedup down to the most recent row per
1087+
// scenario, then add a UNIQUE index so INSERT OR REPLACE correctly upserts on scenario_id.
1088+
const scenarioResultsIndex24 = db.prepare(
1089+
`SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'idx_scenario_results_scenario_id'`
1090+
).get();
1091+
if (!scenarioResultsIndex24) {
1092+
db.prepare(`
1093+
DELETE FROM scenario_results
1094+
WHERE rowid NOT IN (
1095+
SELECT MAX(r.rowid)
1096+
FROM scenario_results r
1097+
WHERE r.calculated_at = (
1098+
SELECT MAX(r2.calculated_at) FROM scenario_results r2 WHERE r2.scenario_id = r.scenario_id
1099+
)
1100+
GROUP BY r.scenario_id
1101+
)
1102+
`).run();
1103+
db.prepare(`CREATE UNIQUE INDEX idx_scenario_results_scenario_id ON scenario_results(scenario_id)`).run();
1104+
}
10811105
}

src/routes/scenarios/[id]/+page.svelte

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import Edit2 from '@lucide/svelte/icons/edit-2';
2626
import DollarSign from '@lucide/svelte/icons/dollar-sign';
2727
import AlertTriangle from '@lucide/svelte/icons/alert-triangle';
28+
import Route from '@lucide/svelte/icons/route';
2829
import ExportButton from '$lib/components/dashboard/ExportButton.svelte';
2930
import DiagnosticsBanner from '$lib/components/dashboard/DiagnosticsBanner.svelte';
3031
@@ -38,6 +39,15 @@
3839
const scopeSummary = $derived(data.scopeSummary);
3940
const resolvedConfigs = $derived(data.resolvedConfigs || []);
4041
42+
const modelingTypeLabel = $derived.by(() => {
43+
switch (scenario.modeling_type) {
44+
case 'incremental': return 'Incremental';
45+
case 'gtm': return 'GTM';
46+
case 'appraisal': return 'Appraisal';
47+
default: return 'Appraisal';
48+
}
49+
});
50+
4151
const diagnostics = $derived(data.diagnostics ?? []);
4252
4353
// ADR 0009 — per-archetype stream economics (mix signal)
@@ -1370,6 +1380,12 @@
13701380

13711381
{#if scopeSummary}
13721382
<div class="glass border border-border px-4 py-2.5 rounded-lg flex items-center space-x-2 text-xs select-none">
1383+
<Route class="h-4 w-4 text-primary shrink-0" />
1384+
<span class="text-muted-foreground font-semibold">Type:</span>
1385+
<Badge variant="outline" class="glass-inset py-0.5 px-2 font-semibold">
1386+
{modelingTypeLabel}
1387+
</Badge>
1388+
<span class="text-muted-foreground/60">•</span>
13731389
<Users2 class="h-4 w-4 text-primary shrink-0" />
13741390
<span class="text-muted-foreground font-semibold">Scope Targeting:</span>
13751391
<Badge variant="outline" class="glass-inset py-0.5 px-2 capitalize font-semibold">

0 commit comments

Comments
 (0)