mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
fix(client): bound the staged-attachment poll and list every client poll
The Coach polled a staged document every 2.5 s until its content index existed, which for a format that is never indexed meant for as long as the Coach stayed open. It now stops with the same upload processing window the documents list uses. Every client poll, its interval and its stop condition is listed beside the dashboard cadence constant.
This commit is contained in:
1 parent
9bc95713cb
commit
415da581f8
4 files changed
+120
-3
No files matched your search
@@ -22,6 +22,8 @@ import {
|
||||
resolveBulkShareDocuments,
|
||||
SHARE_LINK_MAX_DOCUMENTS,
|
||||
vaultFiltersToSearch,
|
||||
STAGED_ATTACHMENT_POLL_MS,
|
||||
stagedAttachmentPollInterval,
|
||||
} from "../vault-utils";
|
||||
|
||||
function doc(overrides: Partial<InboundDocumentDto> = {}): InboundDocumentDto {
|
||||
@@ -541,3 +543,36 @@ describe("buildProcedureChoices", () => {
|
||||
expect(buildProcedureChoices([], null, labels)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("stagedAttachmentPollInterval", () => {
|
||||
const now = Date.parse("2026-10-20T10:00:00Z");
|
||||
const at = (msAgo: number) => new Date(now - msAgo).toISOString();
|
||||
|
||||
it("polls a fresh upload until its index lands", () => {
|
||||
expect(
|
||||
stagedAttachmentPollInterval(
|
||||
{ createdAt: at(30_000), hasContentIndex: false },
|
||||
now,
|
||||
),
|
||||
).toBe(STAGED_ATTACHMENT_POLL_MS);
|
||||
expect(
|
||||
stagedAttachmentPollInterval(
|
||||
{ createdAt: at(30_000), hasContentIndex: true },
|
||||
now,
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("stops polling a document that is never indexed once the window passes", () => {
|
||||
expect(
|
||||
stagedAttachmentPollInterval(
|
||||
{ createdAt: at(RECENT_UPLOAD_WINDOW_MS + 1), hasContentIndex: false },
|
||||
now,
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("does not poll before the detail has loaded", () => {
|
||||
expect(stagedAttachmentPollInterval(undefined, now)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -167,6 +167,26 @@ export function isDocumentProcessing(
|
||||
return !doc.hasContentIndex && isRecentlyUploaded(doc.createdAt, now);
|
||||
}
|
||||
|
||||
/**
|
||||
* How often the Coach polls a staged attachment for its content index.
|
||||
*
|
||||
* The same "still processing" question the vault list asks, so the same
|
||||
* bounded window answers it: a document that will never be indexed (an
|
||||
* unsupported format, indexing disabled) used to be polled every 2.5 s for as
|
||||
* long as the Coach stayed open. `false` once the index exists or the window
|
||||
* has passed.
|
||||
*/
|
||||
export const STAGED_ATTACHMENT_POLL_MS = 2_500;
|
||||
|
||||
export function stagedAttachmentPollInterval(
|
||||
doc: Pick<InboundDocumentDto, "createdAt" | "hasContentIndex"> | undefined,
|
||||
now: number = Date.now(),
|
||||
): number | false {
|
||||
return doc && isDocumentProcessing(doc, now)
|
||||
? STAGED_ATTACHMENT_POLL_MS
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether ANY document in the list is still inside its processing window —
|
||||
* drives the vault list query's poll-while-indexing `refetchInterval`.
|
||||
|
||||
@@ -21,7 +21,10 @@ import type { CoachLaunchScope } from "@/lib/insights/coach-launch-context";
|
||||
import type { InboundDocumentDetailDto } from "@/lib/validations/inbound-documents";
|
||||
import { MAX_COACH_ATTACHMENTS } from "@/lib/validations/inbound-documents";
|
||||
import { useModuleEnabled } from "@/hooks/use-module-enabled";
|
||||
import { parseUploadResponse } from "@/components/documents/vault-utils";
|
||||
import {
|
||||
parseUploadResponse,
|
||||
stagedAttachmentPollInterval,
|
||||
} from "@/components/documents/vault-utils";
|
||||
import {
|
||||
metricScopeLabelFallback,
|
||||
scopeSourceMetricLabelKey,
|
||||
@@ -399,10 +402,11 @@ export function CoachConversation({
|
||||
queryFn: async () =>
|
||||
apiGet<InboundDocumentDetailDto>(`/api/documents/inbound/${id}`),
|
||||
staleTime: 15_000,
|
||||
// Bounded by the upload processing window, like the vault list: a
|
||||
// document that is never indexed stops being polled.
|
||||
refetchInterval: (query: {
|
||||
state: { data?: InboundDocumentDetailDto };
|
||||
}) =>
|
||||
query.state.data && !query.state.data.hasContentIndex ? 2500 : false,
|
||||
}) => stagedAttachmentPollInterval(query.state.data),
|
||||
})),
|
||||
});
|
||||
const stagedDetailById = new Map<
|
||||
|
||||
Reference in new issue
Block a user