fix: stable claims paging and a deep link that does not lose its date window
- claims paging ordered by claim_id (unique) instead of service_date: each page is a separate Spark query, and with thousands of ties the engine repeated rows across pages - the case's anchor date comes from the review's own ceiling or the lakehouse stats view, not from the briefing, which loads seconds later; an expiring-appeals link with no anchor is now suppressed rather than opening every unfiled denial Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1c81912b17
commit
75483f347e
@ -27,7 +27,10 @@ export function claimsHref(q: ClaimsQuery): string {
|
||||
/** The rows behind "claims denied" / "affected". */
|
||||
export function affectedClaimsHref(kind: string, slice: Slice | null, anchor: string | null): string | null {
|
||||
if (kind === 'expiring_appeals') {
|
||||
return claimsHref({ status: 'denied', appeal: 'not_filed', dl_from: anchor ?? undefined, dl_to: anchor ? addDays(anchor, 14) : undefined });
|
||||
// Without the anchor the 14-day window cannot be expressed, and the link
|
||||
// would open every unfiled denial ever. Show no link instead.
|
||||
if (!anchor) return null;
|
||||
return claimsHref({ status: 'denied', appeal: 'not_filed', dl_from: anchor, dl_to: addDays(anchor, 14) });
|
||||
}
|
||||
if (kind === 'slow_payer') {
|
||||
return slice?.payer ? claimsHref({ payer: slice.payer, status: 'pending' }) : null;
|
||||
|
||||
@ -17,7 +17,7 @@ import { ActivityForm } from '../components/ActivityForm';
|
||||
import { AvaLive } from '../components/AvaLive';
|
||||
import { Disclosure, FullStory, Recheck, Recommendations, SqlEvidence, Verdict } from '../components/Findings';
|
||||
import { Briefing, BriefingSkeleton } from '../components/Briefing';
|
||||
import { anchorDate, loadBriefing, sliceOf } from '../api/charts';
|
||||
import { loadBriefing, sliceOf } from '../api/charts';
|
||||
import type { Action } from '../api/config';
|
||||
import { dateTime, num, str } from '../format';
|
||||
|
||||
@ -67,7 +67,14 @@ export function CaseScreen() {
|
||||
// Chart rows come from six Databricks views through the record-view API. Loaded
|
||||
// once there are findings to picture; the slice keys decide which weekly line
|
||||
// and which recovery breakdown are drawn.
|
||||
const asOf = str(row?.review_as_of).slice(0, 10) || null;
|
||||
const asOf = str(row?.review_to || row?.review_as_of).slice(0, 10) || null;
|
||||
// The anchor behind "expiring within 14 days". It is the review's own
|
||||
// ceiling date when the reviewer set one, otherwise the lakehouse's latest
|
||||
// service date — read from the stats view, NOT from the briefing: the charts
|
||||
// take seconds to load and a link rendered without the anchor would silently
|
||||
// drop the deadline window and open thousands of rows instead of hundreds.
|
||||
const lake = useQuery(() => client.rows('dni-rv-lakehouse-tables', { limit: 10 }), [], !asOf && hasFindings);
|
||||
const anchor = asOf ?? str(lake.data?.find((r) => str(r.table_name) === 'claims')?.to_date).slice(0, 10) ?? null;
|
||||
const briefing = useQuery(
|
||||
() => loadBriefing(client, slice, { kind, asOf }),
|
||||
[id, slice?.payer, slice?.department, slice?.code, kind, asOf],
|
||||
@ -171,7 +178,7 @@ export function CaseScreen() {
|
||||
{/* ---------- The findings: what happened, how much, what to approve ---------- */}
|
||||
{hasFindings && (
|
||||
<>
|
||||
<Verdict row={row} slice={slice} kind={kind} anchor={anchorDate(briefing.data)} />
|
||||
<Verdict row={row} slice={slice} kind={kind} anchor={anchor || null} />
|
||||
{briefing.data ? (
|
||||
<Briefing data={briefing.data} slice={slice} kind={kind} />
|
||||
) : (
|
||||
|
||||
@ -69,8 +69,13 @@ export function ClaimsScreen() {
|
||||
const filtered = filters.length > 0 || !!search;
|
||||
|
||||
const key = params.toString();
|
||||
// ORDER BY A UNIQUE COLUMN. Each page is its own query against Spark, and
|
||||
// `service_date` has thousands of ties — with a non-unique sort key the
|
||||
// engine is free to order tied rows differently per execution, so page 2
|
||||
// repeated rows from page 1. `claim_id` is unique and is assigned in date
|
||||
// order, so descending is still newest-first, and every page is disjoint.
|
||||
const q = useQuery(
|
||||
() => client.recordView('dni-rv-claims', { page, limit: PAGE, filters, search, sortBy: 'service_date', sortDir: 'desc' }),
|
||||
() => client.recordView('dni-rv-claims', { page, limit: PAGE, filters, search, sortBy: 'claim_id', sortDir: 'desc' }),
|
||||
[key],
|
||||
);
|
||||
// The platform caps its count at 10,000; the stats view has the exact
|
||||
|
||||
Loading…
Reference in New Issue
Block a user