import { keepPreviousData, useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { cursorPage, Decision, type DecisionKind, type DecisionResolveInput, type DecisionStatus, DecisionSummary, } from "@umt/contracts"; import { api } from "~/lib/api.ts"; import { getParsed, parseOrThrow } from "./library.ts"; // 待处理:按作品与问题类型聚合(summary),条目带证据/建议/影响范围,resolve 选项来自 decision.options。 export const decisionKeys = { all: ["decisions"] as const, list: (f: DecisionFilters) => ["decisions", "list", f] as const, summary: (status?: DecisionStatus) => ["decisions", "summary", status ?? "open"] as const, }; export type DecisionFilters = { status?: DecisionStatus; kind?: DecisionKind }; /** /decisions/summary(合同 DecisionSummary) */ export { DecisionSummary }; const Page = cursorPage(Decision); export function useDecisions(filters: DecisionFilters, enabled = true) { return useInfiniteQuery({ enabled, queryKey: decisionKeys.list(filters), initialPageParam: undefined as string | undefined, queryFn: ({ pageParam, signal }) => getParsed(Page, "/decisions", { ...filters, cursor: pageParam, limit: 100 }, signal), getNextPageParam: (last) => last.nextCursor ?? undefined, placeholderData: keepPreviousData, }); } export function useDecisionSummary(status?: DecisionStatus) { return useQuery({ queryKey: decisionKeys.summary(status), queryFn: ({ signal }) => getParsed(DecisionSummary, "/decisions/summary", { status }, signal), }); } export function useResolveDecision() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, ...body }: DecisionResolveInput & { id: string }) => api.post(`/decisions/${id}/resolve`, body).then((d) => parseOrThrow(Decision, d, "/decisions")), onSuccess: () => { void qc.invalidateQueries({ queryKey: decisionKeys.all }); void qc.invalidateQueries({ queryKey: ["identity"] }); }, }); }