Aakalan architecture
A phone app that holds the ledger on the device and syncs it to Firebase. There is no server of our own. The one metered cost named in the repo is the SMS that sends a sign-in code.
last verified 2026-10-30
Known cost a month
₹0 of its own
The ₹31 a month on this account is AskCal's scans, paid from ₹383.78 of prepaid credit by choice. RevenueCat, EAS and store fees are not read.
What makes cost grow
Sign-in SMS
Phone auth bills real codes, but no SMS line is on the October bill. The per-SMS price is not recorded.
Accounts today
9
Firestore count on 2026-10-25, owner and test accounts included.
How it fits together
Pick something a user does to see its path and what it costs.
One SMS, price not read
India numbers only; test numbers cost nothing
- The user enters a phone number.
- Firebase checks the app, then sends a code by SMS. Other countries are blocked.
- The user enters the code and is signed in.
- The app starts its Firestore listeners. Nothing is shown until the groups listener has reported.
Cost
Every number says where it came from.
| Service | Pays for | Today | Grows with | Basis |
|---|---|---|---|---|
| Aakalan app | Expo, iOS and Android; also runs on web | $0 | Nothing | StatedCLAUDE.md |
| Local ledger and photo queue | Zustand store, AsyncStorage, pending receipts on disk | $0 | Nothing | In codesrc/data/store.ts; src/services/receipt-queue.ts |
| Firebase Auth | Phone sign-in by SMS code · India only | ₹0: no line on the October bill | Each real SMS code. Test numbers send none. | MeasuredCloud Billing report, Oct 1-30, read 2026-10-30 |
| Firestore | Groups, expenses, settlements, live listeners | ₹0: no line on the October bill | Reads and writes, plus live listeners per signed-in user | MeasuredCloud Billing report, Oct 1-30, read 2026-10-30 |
| Firebase Storage | Receipt photos, JPEG, 1600 px, under 5 MB | ₹0: no line on the October bill | Receipt photos, a Pro feature | MeasuredCloud Billing report, Oct 1-30, read 2026-10-30 |
| RevenueCat | Is this user on Pro? | Not read | Subscription revenue | Not known |
| EAS | Builds and over-the-air updates | Not read | Builds, app updates | Not known |
| App Store · Google Play | Installs and Pro payments | Not read | Developer fees and a cut of Pro sales | Not known |
| Gemini API (for AskCal) | This account's credit pays for AskCal's scans | ₹30.84 in Oct; ₹67.64 in Sep | AskCal photo scans | MeasuredCloud Billing and AI Studio, 2026-10-30; owner's choice, see askcal ops/gemini-credits.md |
What breaks when something fails
| If this fails | The user sees | Their data | Basis |
|---|---|---|---|
| Local ledger and photo queue | Not applicable: this is the app's own memory. Every write lands here first, so screens have no loading state. | A queued photo is kept until it uploads. Nothing is dropped after failed tries. | In codesrc/services/receipt-queue.ts drain() |
| Firebase Auth | A new sign-in fails. Someone already signed in should keep working. | Safe, on the phone | AssumedNo test or runbook covers this |
| Firestore | Offline writes queue and send later. A refused write or unreadable list shows a banner. | Local copy stays. A refused write can be overwritten by the next snapshot. | In codesrc/services/sync.ts push(); wiki/concepts/sync-gates.md |
| Firebase Storage | The expense is saved. The photo waits in the queue. | Photo stays on the phone until it lands | In codesrc/services/receipt-queue.ts; storage.rules |
| RevenueCat | Shown as not Pro, and the paywall can show no price. Adding, splitting, settling and export stay free. | Safe | Statedwiki/concepts/revenuecat-rules.md; wiki/concepts/pro-never-gates-the-core-loop.md |
Where the data goes
| Expenses, groups, settlements, profile | Phone, and Firestore |
| Phone number | Firebase Auth |
| Receipt photos | Phone, then Firebase Storage. Readable by the expense's members only. |
| Solo expenses | Firestore, readable by the owner alone (rules) |
| Contacts | Read on the phone when the user allows it. No upload is recorded. |
| Invite and reminder texts | Built on the phone, sent by the user's own app |
What we do not know yet
- Gemini API on this account is AskCal's, by the owner's choice: it stops when the ₹383.78 balance runs out, and AskCal then moves to its own. Aakalan itself calls no Gemini.
- RevenueCat, EAS and store fees are not read.
- Price of one sign-in SMS and how many were sent: phone auth needs a billing account, but no usage or price is written down.
- Firestore and Storage free-tier headroom: not recorded. The app has no backend functions, so there are no request logs.
- The counts (9 users, 7 groups, 12 expenses, 9 settlements) include owner and test accounts, so real use is smaller.
- Apple and Google developer fees and store cut: not recorded in this repo.
- ops/setup.md says the Auth console still shows a stale 10 SMS a day quota. The real limit is not recorded.
- firestore.rules and storage.rules must deploy together (storage reads Firestore membership); nothing records that they did.