Per-user auth via Nextcloud Login Flow v2, Tailwind UI rewrite
- auth.py/auth_routes.py: Login Flow v2 (verified against real NC source/docs) - no OAuth2 client registration needed, backend polls server-side so no CORS issues. Sessions are hashed-token cookies; NC app passwords encrypted at rest (Fernet). Every /api/* route guarded by a blueprint-wide before_request, not per-route decorators, so future routes are protected by default. - receipts/groups scoped per owner_nc_user_id; cross-user access 404s. - nc_client/cospend_client take (username, app_password) per call instead of one shared global credential - each user's uploads/shares/ bills now happen as themselves. - Frontend: LoginGate component drives the login flow (open NC login in a new tab, poll our backend, done). - Merged the old separate review step into the split screen, redesigned with Tailwind (was unstyled/broken), default-excluded-per-item splitting with one-click "include everyone" fixed, DD.MM.YYYY date field, receipt-icon branding. - Dropped LLM bounding-box highlighting - unreliable on real receipts, plain photo upload instead. - Only mention who a bill is split with in its title when there's more than one bill off the same receipt to disambiguate.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""Receipt -> [{id, label, price, bbox}] via any OpenAI-compatible chat
|
||||
"""Receipt -> [{id, label, price}] via any OpenAI-compatible chat
|
||||
completions endpoint (works unmodified with OpenAI; point LLM_BASE_URL at
|
||||
Gemini's OpenAI-compat layer to use that instead, no code change needed).
|
||||
"""
|
||||
@@ -23,16 +23,12 @@ Respond with ONLY a JSON object, no prose, no markdown fences, shaped like:
|
||||
"store_name": "<store/shop name as printed, or null if unreadable>",
|
||||
"date": "<receipt date as YYYY-MM-DD, or null if unreadable>",
|
||||
"items": [
|
||||
{"label": "<item name as printed>", "price": <number>, \
|
||||
"bbox": [x, y, w, h]}
|
||||
{"label": "<item name as printed>", "price": <number>}
|
||||
]
|
||||
}
|
||||
|
||||
- price is the item's price in the receipt's currency, as a plain number \
|
||||
(no currency symbol).
|
||||
- bbox is the item's approximate bounding box on the image, normalized to \
|
||||
0-1 (x, y = top-left corner; w, h = width/height as a fraction of the \
|
||||
image). Best effort is fine.
|
||||
- Skip subtotal/tax/total lines, only real purchased items.
|
||||
- If a line item's price is unclear, make your best guess rather than \
|
||||
omitting it.
|
||||
@@ -79,7 +75,6 @@ def extract_receipt(image_bytes: bytes, mime_type: str = "image/jpeg") -> dict:
|
||||
"id": str(uuid.uuid4()),
|
||||
"label": str(entry.get("label", "")).strip(),
|
||||
"price": float(entry.get("price", 0) or 0),
|
||||
"bbox": entry.get("bbox") or None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user