# iphonegalaxy/acerto-de-contas architecture

> Architecture diagram of the GitHub repository iphonegalaxy/acerto-de-contas, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/iphonegalaxy/acerto-de-contas
- Repository: https://github.com/iphonegalaxy/acerto-de-contas

## Overview

1. **High-level shape**
   - This repository is a **client-side single-page web app** for shared expense tracking.
   - There is no separate backend in the repo; the app relies on **Firebase** for authentication and data persistence, and is deployed as a **static site** on **GitHub Pages**.

2. **Primary application surface**
   - `index.html` is the core application entry point and, per the README, contains the full **React + Firebase** app.
   - The rest of the repo mostly supports that app: configuration, security rules, PWA assets, deployment, and smoke tests.

3. **Identity and session boundary**
   - Users authenticate through **Firebase Authentication** using **Google** or **email/password**.
   - Anonymous auth is explicitly not used.
   - Each user account is later linked to a single household/family context, which is the main tenancy boundary for the app.

4. **Multi-tenant data model**
   - The app is organized around a **householdId** that isolates one couple/family’s data from another.
   - Access is membership-based: data visibility is governed by whether the signed-in user belongs to that household.
   - The README also makes clear that a user can belong to **one family at a time**, and the family creator can delete the family and all associated data.

5. **Realtime data layer**
   - The app uses **Firestore** as the live datastore, which gives **real-time synchronization** between devices.
   - This is the main source of truth for shared financial records, so changes made by one person appear immediately to the other.
   - Firestore is also where the app stores household-scoped entities such as members, cards, transactions, and related monthly history.

6. **Core business rules**
   - The business logic is not generic splitting; it has fixed rules:
     - **Pessoa 1** pays 100% of card bills in payment calculations.
     - **Pessoa 2** has exclusive access to the **Ajuste** type.
     - Cards marked **Ambos** are split half-and-half in totals.
     - **Dividido** means 50/50.
   - These rules are part of the domain layer inside the client app and affect how totals and obligations are computed.

7. **Statement import pipeline**
   - A major workflow is importing credit-card statements from bank files.
   - The user selects a bank and uploads **CSV or XLSX** files; the app detects cards from the statement and persists them into the household.
   - The README currently highlights **C6 Bank** as supported, with other banks listed as future support.
   - This import path is a separate ingestion flow from manual entry, but both end up writing into the same Firestore-backed household data.

8. **Monthly navigation and card views**
   - The UI supports **monthly history browsing**, so the app is not just a current-state dashboard; it can reconstruct and navigate prior months.
   - There is also a **bank filter** in the card tab, which indicates the UI can slice the household’s card data by institution or show all cards.

9. **PWA/browser layer**
   - The app is packaged as a **PWA** using `manifest.json` and `sw.js`.
   - That means the browser layer provides installability and some offline-capable shell behavior, even though the shared data still depends on Firebase connectivity for realtime sync.
   - `.nojekyll` is present to make GitHub Pages serve the site without Jekyll processing.

10. **Configuration and deployment**
   - `firebase-config.example.js` is the local template for Firebase client configuration; the real config is expected to be injected/created from environment or secrets.
   - `.github/workflows/pages.yml` handles **automated deployment** to GitHub Pages when `main` changes.
   - The README indicates Firebase credentials are supplied as **GitHub Secrets**, so the deployed site is static but configured at build time to talk to the correct Firebase project.

11. **Security boundary**
   - `firestore.rules` is a key architectural file because it enforces the tenant boundary in Firestore.
   - The app’s security model depends on Firestore rules matching the application’s household membership model, preventing cross-family reads/writes even though all users share the same backend project.

12. **Verification and operational checks**
   - `docs/smoke/` contains smoke-test scripts, including a family-join flow and a generic post-deploy check.
   - This suggests the repo treats deploy-time verification as part of the architecture: after publishing to Pages, the app is validated against the live environment and Firebase-backed flows.

13. **Mental model for a diagram**
   - The cleanest diagram is: **browser/PWA client** in the center, with arrows to **Firebase Auth** for login, **Firestore** for shared household data, **GitHub Pages** for static hosting, and **file import sources** for statement ingestion.
   - The most important internal boundary is the **household/family tenant boundary**, enforced both in app logic and in Firestore rules.

Main entry points: [`index.html`](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html) (App entry), [`docs/smoke/run-smoke.mjs`](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/docs/smoke/run-smoke.mjs) (Smoke checks), [`manifest.json`](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/manifest.json) (Browser shell), [`.github/workflows/pages.yml`](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/.github/workflows/pages.yml) (GitHub Pages)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client App"]
  node_entry["App entry<br/>SPA shell<br/>[index.html]"]
  node_auth(("Sign-in<br/>auth flow<br/>[index.html]"))
  node_tenant{{"Household<br/>tenant boundary<br/>[index.html]"}}
  node_ledger["Expense ledger<br/>domain model<br/>[index.html]"]
  node_rules["Split rules<br/>business logic<br/>[index.html]"]
  node_importer["Statement import<br/>ingestion flow<br/>[index.html]"]
  node_history["Monthly views<br/>navigation<br/>[index.html]"]
  node_bankfilter["Bank filter<br/>view filter<br/>[index.html]"]
  node_bankfiles["Bank files<br/>upload input"]
end

subgraph group_firebase["Firebase"]
  node_authsvc(("Auth service<br/>Firebase Auth"))
  node_store[("Firestore<br/>live datastore")]
  node_security["Firestore rules<br/>security rules<br/>[firestore.rules]"]
end

subgraph group_delivery["Delivery"]
  node_browser["Browser shell<br/>PWA shell<br/>[manifest.json]"]
  node_service["Service worker<br/>offline cache<br/>[sw.js]"]
  node_pages["GitHub Pages<br/>static hosting<br/>[pages.yml]"]
  node_firebasecfg["Firebase config<br/>client config"]
  node_secrets["Secrets<br/>deploy config<br/>[pages.yml]"]
end

subgraph group_ops["Verification"]
  node_smoketests["Smoke checks<br/>post-deploy tests<br/>[run-smoke.mjs]"]
end

node_browser -->|"hosts UI"| node_entry
node_service -->|"caches"| node_browser
node_pages -->|"deploys"| node_browser
node_secrets -->|"configures"| node_pages
node_firebasecfg -->|"initializes"| node_entry
node_entry -->|"sign in"| node_auth
node_auth -->|"verify identity"| node_authsvc
node_entry -->|"bind session"| node_tenant
node_tenant -->|"scope"| node_ledger
node_tenant -->|"govern"| node_rules
node_rules -->|"apply splits"| node_ledger
node_entry -->|"read/write"| node_ledger
node_ledger -->|"browse months"| node_history
node_ledger -->|"filter cards"| node_bankfilter
node_entry -->|"import statements"| node_importer
node_importer -->|"upload"| node_bankfiles
node_ledger -->|"persist"| node_store
node_store -->|"protected by"| node_security
node_smoketests -->|"validates"| node_pages
node_smoketests -->|"join flow"| node_authsvc
node_smoketests -->|"live check"| node_store

click node_entry "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_auth "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_tenant "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_ledger "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_rules "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_importer "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_history "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_bankfilter "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html"
click node_browser "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/manifest.json"
click node_service "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/sw.js"
click node_pages "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/.github/workflows/pages.yml"
click node_firebasecfg "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/firebase-config.example.js"
click node_secrets "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/.github/workflows/pages.yml"
click node_security "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/firestore.rules"
click node_smoketests "https://github.com/iphonegalaxy/acerto-de-contas/blob/main/docs/smoke/run-smoke.mjs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_auth,node_tenant,node_ledger,node_rules,node_importer,node_history,node_bankfilter,node_bankfiles toneBlue
class node_authsvc,node_store,node_security toneAmber
class node_browser,node_service,node_pages,node_firebasecfg,node_secrets toneMint
class node_smoketests toneRose
```

## Components

### Client App

Browser-based single-page app and domain logic

- [App entry](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): SPA shell · Single-page app bootstrap and main UI surface · `index.html`
- [Sign-in](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): auth flow · Firebase Authentication using Google or email/password · `index.html`
- [Household](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): tenant boundary · Single-family context centered on householdId and membership · `index.html`
- [Expense ledger](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): domain model · Shared members, cards, transactions, and monthly history · `index.html`
- [Split rules](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): business logic · Pessoa 1, Pessoa 2, Ambos, and Dividido payment logic · `index.html`
- [Statement import](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): ingestion flow · Bank statement upload and card detection from CSV/XLSX files · `index.html`
- [Monthly views](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): navigation · Browse prior months and reconstruct household history · `index.html`
- [Bank filter](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/index.html): view filter · Slices card views by institution or shows all cards · `index.html`
- **Bank files**: upload input · CSV and XLSX statement uploads from supported banks

### Firebase

Authentication, realtime datastore, and security boundary

- **Auth service**: Firebase Auth · Identity provider for signed-in users
- **Firestore**: live datastore · Realtime household-scoped source of truth
- [Firestore rules](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/firestore.rules): security rules · Enforces household membership and tenant isolation · `firestore.rules`

### Delivery

Static hosting and PWA packaging

- [Browser shell](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/manifest.json): PWA shell · Installable static client shell · `manifest.json`
- [Service worker](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/sw.js): offline cache · Service worker for offline-capable shell behavior · `sw.js`
- [GitHub Pages](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/.github/workflows/pages.yml): static hosting · Automated deployment target for the published site · `.github/workflows/pages.yml`
- [Firebase config](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/firebase-config.example.js): client config · Template for injected Firebase project settings · `firebase-config.example.js`
- [Secrets](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/.github/workflows/pages.yml): deploy config · Build-time Firebase credentials supplied to deployment · `.github/workflows/pages.yml`

### Verification

Deployment checks and smoke tests

- [Smoke checks](https://github.com/iphonegalaxy/acerto-de-contas/blob/main/docs/smoke/run-smoke.mjs): post-deploy tests · Family-join and live post-deploy verification scripts · `docs/smoke/run-smoke.mjs`

## Connections

- Browser shell → App entry: hosts UI · The browser loads the static SPA shell
- Service worker → Browser shell: caches · Service worker supports offline-capable shell behavior
- GitHub Pages → Browser shell: deploys · GitHub Pages serves the static site
- Secrets → GitHub Pages: configures · Deployment injects Firebase credentials at build time
- Firebase config → App entry: initializes · Client config connects the app to the chosen Firebase project
- App entry → Sign-in: sign in · Users authenticate before accessing household data
- Sign-in → Auth service: verify identity · Firebase Authentication handles user sign-in
- App entry → Household: bind session · App binds the session to a single household context
- Household → Expense ledger: scope · All shared expense data is household-scoped
- Household → Split rules: govern · Tenant-aware business rules shape obligations and balances
- Split rules → Expense ledger: apply splits · Calculated obligations and allocations are written into shared data
- App entry → Expense ledger: read/write · Realtime shared data is stored in Firestore
- Expense ledger → Monthly views: browse months · Past periods are reconstructed from stored monthly state
- Expense ledger → Bank filter: filter cards · Card views can be sliced by institution
- App entry → Statement import: import statements · Users ingest bank statements into the shared ledger
- Statement import → Bank files: upload · CSV/XLSX statement files are the input source
- Expense ledger → Firestore: persist · Household data lives in Firestore
- Firestore → Firestore rules: protected by · Rules gate reads and writes by household membership
- Smoke checks → GitHub Pages: validates · Post-deploy checks exercise the live published app
- Smoke checks → Auth service: join flow · Smoke tests cover authentication and family join
- Smoke checks → Firestore: live check · Smoke tests verify Firebase-backed behavior
