Backend: receipt upload -> LLM vision extraction (OpenAI-compatible, provider-agnostic), item review/edit, per-group splitting against Cospend projects/members, highlight+upload via WebDAV, public share link, bill creation via Cospend's OCS API (verified against real source, not just doc summaries). Frontend: capture -> review -> group -> summary flow as an installable PWA. install.sh / run.sh (venv + npm, tmux session) instead of Docker, per the ~/Projects/gain pattern.
57 lines
1.1 KiB
TypeScript
57 lines
1.1 KiB
TypeScript
export type BBox = [number, number, number, number] // x, y, w, h, normalized 0-1
|
|
|
|
export interface Item {
|
|
id: string
|
|
label: string
|
|
price: number
|
|
bbox: BBox | null
|
|
}
|
|
|
|
export interface Receipt {
|
|
id: string
|
|
items: Item[]
|
|
store_name: string | null
|
|
date: string // YYYY-MM-DD; extracted, falls back to today, user-editable
|
|
status: 'extracted' | 'grouped' | 'done'
|
|
created_at: string
|
|
}
|
|
|
|
export interface Member {
|
|
id: string
|
|
name: string
|
|
}
|
|
|
|
export interface CospendProject {
|
|
id: string
|
|
name: string
|
|
}
|
|
|
|
export interface Group {
|
|
id: string
|
|
receipt_id: string
|
|
name: string
|
|
cospend_project_id: string
|
|
payer_member_id: string
|
|
member_ids: string[]
|
|
item_ids: string[]
|
|
status: 'pending' | 'submitted' | 'failed'
|
|
share_url: string | null
|
|
cospend_bill_id: string | null
|
|
error: string | null
|
|
}
|
|
|
|
export interface SubmitResult {
|
|
share_url: string
|
|
amount: number
|
|
bill_id: number
|
|
}
|
|
|
|
/** A group draft in progress client-side, before it's persisted via POST /groups. */
|
|
export interface GroupDraft {
|
|
localId: string
|
|
name: string
|
|
payerMemberId: string | null
|
|
memberIds: string[]
|
|
itemIds: string[]
|
|
}
|