/** * Decision-blocks domain hooks. * * The 12-block decision content lives in the `decision_blocks` table and was * previously only reachable via DOCX export. These hooks back the interactive * block viewer/editor on the case page: * GET /api/cases/{n}/decision-blocks → all 12 blocks (empty included) * PUT /api/cases/{n}/decision-blocks/{block} → save inline-edited content * * The endpoints aren't declared with response models on the FastAPI side, so * we maintain local types here (same convention as cases.ts). */ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { apiRequest } from "./client"; export type BlockStatus = "empty" | "draft" | "review" | "final"; export type DecisionBlock = { block_id: string; block_index: number; title: string; content: string; word_count: number; status: BlockStatus; generation_type: string; model_used: string; /** ISO timestamp; null when the block was never written */ updated_at: string | null; }; export type DecisionBlocksResponse = { case_number: string; has_decision: boolean; decision_id: string | null; active_draft_path: string | null; source_of_truth: "docx" | "blocks"; blocks: DecisionBlock[]; }; export type SaveBlockResponse = { block: DecisionBlock; active_draft_warning: boolean; }; export const decisionBlocksKeys = { all: ["decision-blocks"] as const, case: (caseNumber: string) => [...decisionBlocksKeys.all, caseNumber] as const, }; export function useDecisionBlocks(caseNumber: string) { return useQuery({ queryKey: decisionBlocksKeys.case(caseNumber), queryFn: ({ signal }) => apiRequest( `/api/cases/${caseNumber}/decision-blocks`, { signal }, ), }); } export function useSaveBlock(caseNumber: string) { const qc = useQueryClient(); return useMutation({ mutationFn: ({ blockId, content }: { blockId: string; content: string }) => apiRequest( `/api/cases/${caseNumber}/decision-blocks/${blockId}`, { method: "PUT", body: { content } }, ), onSuccess: () => { qc.invalidateQueries({ queryKey: decisionBlocksKeys.case(caseNumber) }); }, }); }