Initial scaffold: Flask/SQLite backend, React/Vite PWA frontend

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.
This commit is contained in:
2026-08-30 15:02:18 +02:00
commit d97aac0e17
42 changed files with 8274 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
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[]
}