Files
app/src/admin/lib/queries/ai.ts
BOHA b7ebf04001 feat(odin): OdinChat orchestrator; render on /odin; remove DashAssistant
Wire OdinTabs/OdinThread/InvoiceReviewCard/OdinComposer into a single
OdinChat orchestrator; mount it on /odin (maxWidth 1100); delete the
old DashAssistant and its aiHistoryOptions query helper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:39:15 +02:00

62 lines
1.4 KiB
TypeScript

import { queryOptions } from "@tanstack/react-query";
import { jsonQuery } from "../apiAdapter";
export interface AiUsage {
configured: boolean;
month_spend_usd: number;
budget_usd: number;
remaining_usd: number;
}
export interface ExtractedInvoice {
supplier_name: string;
invoice_number: string | null;
amount: number;
currency: string;
vat_rate: number;
issue_date: string | null;
due_date: string | null;
description: string | null;
}
export interface StoredChatMessage {
role: "user" | "assistant";
content: string;
created_at: string;
}
export const aiUsageOptions = () =>
queryOptions({
queryKey: ["ai", "usage"],
queryFn: () => jsonQuery<AiUsage>("/api/admin/ai/usage"),
staleTime: 30_000,
});
export interface Conversation {
id: number;
title: string;
updated_at: string;
}
export const aiConversationsOptions = () =>
queryOptions({
queryKey: ["ai", "conversations"],
queryFn: () =>
jsonQuery<{ conversations: Conversation[] }>(
"/api/admin/ai/conversations",
),
staleTime: 30_000,
});
export const aiConversationMessagesOptions = (id: number) =>
queryOptions({
queryKey: ["ai", "conversation", id, "messages"],
queryFn: () =>
jsonQuery<{ messages: StoredChatMessage[] }>(
`/api/admin/ai/conversations/${id}/messages`,
),
// Re-read the DB on each mount/selection (no stale-cache resurrection).
staleTime: Infinity,
gcTime: 0,
});