Add AI receipt parsing with provider API key settings
- Settings → AI: configure Anthropic or OpenAI provider with encrypted API key - Sparkle button on each attachment in transaction drawer sends image/PDF to AI - AI extracts merchant, amount, date, description, category hint - "Apply to transaction" button patches the transaction with parsed fields - Anthropic supports images and PDFs; OpenAI supports images only - API key stored AES-256-GCM encrypted in users table (migration 0003) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fe4e69b9ad
commit
22fc1ce2f1
8 changed files with 507 additions and 31 deletions
34
frontend/src/api/settings.ts
Normal file
34
frontend/src/api/settings.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { api } from "./client";
|
||||
|
||||
export interface AiSettings {
|
||||
provider: string | null;
|
||||
has_api_key: boolean;
|
||||
}
|
||||
|
||||
export interface ParsedReceipt {
|
||||
merchant: string | null;
|
||||
amount: number | null;
|
||||
currency: string | null;
|
||||
date: string | null;
|
||||
description: string | null;
|
||||
category: string | null;
|
||||
}
|
||||
|
||||
export async function getAiSettings(): Promise<AiSettings> {
|
||||
const { data } = await api.get("/settings/ai");
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function saveAiSettings(provider: string, api_key: string): Promise<AiSettings> {
|
||||
const { data } = await api.put("/settings/ai", { provider, api_key });
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function clearAiSettings(): Promise<void> {
|
||||
await api.delete("/settings/ai");
|
||||
}
|
||||
|
||||
export async function parseReceipt(txnId: string, attachmentId: string): Promise<ParsedReceipt> {
|
||||
const { data } = await api.post(`/transactions/${txnId}/attachments/${attachmentId}/parse`);
|
||||
return data;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue