diff --git a/app/(shell)/focus/page.tsx b/app/(shell)/focus/page.tsx index 3af3704a..1982e7b0 100644 --- a/app/(shell)/focus/page.tsx +++ b/app/(shell)/focus/page.tsx @@ -370,14 +370,30 @@ export default async function FocusPage({ searchParams }: { searchParams: Search .eq("tenant_id", profile.tenant_id) .not("status", "in", '("approved","dismissed")') .order("created_at", { ascending: false }) - .limit(5); + .limit(20); if (localItems && localItems.length > 0) { notProvisioned = false; dataUpdatedAt = (localItems[0]?.created_at as string | undefined) ?? dataUpdatedAt; - actions = localItems - .map((row) => recoveryItemToFocusAction(row, verticalId)) - .filter((action): action is import("@/lib/pulse/remote-client").RecoveryOpportunity => Boolean(action)); + // A9: brief-prioritization — surface the highest-VALUE opportunities first (the + // Mautic segmentation pattern) instead of just the most-recently-created. Rank by + // the opportunity's estimated value weighted by confidence, recency as the + // tiebreaker, then take the top 5. Real data only — no fabricated figure. + const scored = localItems + .map((row) => { + const action = recoveryItemToFocusAction(row, verticalId); + if (!action) return null; + const confidence = ((row as { confidence_score?: number | null }).confidence_score ?? 50) / 100; + const createdAt = String((row as { created_at?: string }).created_at ?? ""); + return { action, score: (action.estimatedValueCents ?? 0) * confidence, createdAt }; + }) + .filter( + (x): x is { action: import("@/lib/pulse/remote-client").RecoveryOpportunity; score: number; createdAt: string } => + x !== null + ) + .sort((a, b) => b.score - a.score || b.createdAt.localeCompare(a.createdAt)) + .slice(0, 5); + actions = scored.map((x) => x.action); totalRecoverableCents = actions.reduce((sum, a) => sum + (a.estimatedValueCents ?? 0), 0); } else { const { data: opps } = await supabase