# Triptalley — Initial Design Notes

## Platform Strategy
- **Core principle**: all business logic (splits, settlement math, currency handling) lives server-side. The client is a thin UI layer that talks to an API. This is what actually preserves cross-platform optionality — not the choice of UI framework.
- **Recommendation**: native SwiftUI for iOS first. Faster to build well, no cross-platform framework tax, best native feel. Add Android later (native or React Native) if/when it's actually needed — the backend won't need to change.
- Revisit only if you know Android users (travel companions) are coming soon — in that case, React Native from day one trades initial velocity for simultaneous platform coverage.

## Core Data Model (draft)
- **User**: id, name, login/account, home_currency
- **Group**: id, name, member_ids[] — a standing entity; users are invited in and can belong to multiple groups
- **Trip**: id, group_id, name, date range, settlement currency (optional, otherwise defaults to trip creator's home currency)
- **Expense**: id, trip_id, payer_id, amount, original_currency, date, gps_suggested_currency (+ whether the user accepted or overrode it), split_type (equal / custom / percentage), participant_ids[]
- **Settlement**: not stored — computed on demand from the trip's expenses at "final tally," converted per-member into each viewer's home_currency for display

## Currency Handling
- No per-expense FX lookups during the trip. Each expense just stores its original amount, currency, and date.
- At final tally, convert each expense to the settlement currency using the rate for *that expense's date* (historical rate) rather than one blanket end-of-trip rate — same storage cost (you're capturing the date anyway), more accurate, and keeps the "convert once, at the end" architecture intact.
- GPS is used only to **suggest** currency at entry time (reverse geocode → country → currency), always shown as an editable default. Never authoritative — handles edge cases (dual-currency countries, border crossings, no GPS signal) for free instead of needing special-case logic.

## Settlement
- Standard debt-simplification algorithm at tally time: minimize the number of payments needed to settle the group, not just raw pairwise balances.
- Output is a "who pays whom how much" list.

## Offline-First
- Expense entry works fully offline (local store), synced on reconnect.
- No FX calls needed mid-trip (conversion happens at tally) — removes an entire class of "no signal" failures, which pairs naturally with travel.

## Stack (draft)
- **Client**: SwiftUI (native iOS), thin — no local business logic, syncs with backend
- **Backend**: FastAPI on a public VPS, backed by SQLite
- **FX rates**: server-side call to a daily-rate API (e.g., Frankfurter, exchangerate-api) at tally time, cached by date+currency pair

## Auth & Invites
- Login: email-based (email/password or magic link — TBD)
- Group invites: shared link, not per-person email sends — lower friction, works even if you don't have everyone's email up front
- Decided: tapping the invite link lets a new user create an account on the spot and lands them straight in the group — invite flow and signup flow are coupled, not separate steps

## Open Questions
1. ~~**Sync model**~~ — Decided: periodic sync, not live/real-time. Simplifies backend considerably — no websocket/push infra needed, just sync-on-open or a lightweight poll.
2. ~~**Settlement currency**~~ — Decided: converts to each member's individual home currency for display. Means the tally needs a per-member home currency on the account, and conversion happens at display time in addition to at final tally.
3. ~~**Persistent vs. per-trip groups**~~ — Decided: users have individual logins (accounts, not ad hoc per-trip invites) and can be invited into groups. Groups are a standing entity, not disposable per trip.

## Naming
- **Decided: Triptalley**
- Other directions considered: Vaya, Fareshare, Kittybag, Wayfare, Tally Ho, Roamwise
