# sarim2000/pennywiseai-tracker architecture

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

- Interactive diagram: https://gitdiagram.com/sarim2000/pennywiseai-tracker
- Repository: https://github.com/sarim2000/pennywiseai-tracker

## Overview

1. **Repository shape**
   - This is a multi-module Kotlin/Swift monorepo, not a single app.
   - The main products are: an Android app (`app`), a shared Kotlin Multiplatform library (`shared`), a bank/SMS parser engine (`parser-core`), a companion web/server project (`pennywise-web`), and an iOS app (`iosApp`).

2. **Primary product: Android expense tracker**
   - The Android app is the most complete runtime: it owns SMS ingestion, local persistence, analytics, widgets, billing, onboarding, and the on-device AI chat experience.
   - UI is Jetpack Compose with a screen/view-model structure and a bottom-navigation shell.

3. **Android presentation boundary**
   - `presentation/`, `ui/screens/`, `ui/components/`, and `navigation/` hold feature screens and shared composables.
   - Feature areas map cleanly to architecture diagram nodes: home, transactions, analytics, accounts, budgets, subscriptions, rules, settings, chat, statement import, paywall, and unrecognized SMS handling.
   - ViewModels sit between UI and repositories/use-cases; they are the main state boundary.

4. **Android data layer and persistence**
   - The app uses Room as its local source of truth via `PennyWiseDatabase`, DAOs, entities, and schema snapshots under `app/schemas`.
   - Repositories wrap DAOs and expose feature-specific data access for transactions, balances, budgets, cards, loans, subscriptions, exchange rates, merchant mappings, profiles, rules, chats, and unrecognized SMS.
   - Backup/export support is built into the data layer with CSV export and a structured backup/restore format.

5. **SMS ingestion pipeline**
   - Incoming bank messages enter through platform receivers/services such as `SmsBroadcastReceiver`, `BankNotificationListenerService`, and `NotificationActionReceiver`.
   - Background workers (`OptimizedSmsReaderWorker`, `BankNotificationRetryWorker`) and managers (`SmsScanManager`, `SmsTransactionProcessor`, `TransactionDeduplication`) turn raw messages into normalized transaction records.
   - This pipeline is the core data-flow into the local database and is one of the most important diagram paths.

6. **Parsing and normalization**
   - Bank-specific parsing is split out into `parser-core`, a large standalone Kotlin library with one parser per bank/service and a registry/factory layer.
   - The Android app also has statement-import parsing for PDFs (`PdfParserFactory`, `PdfStatementParser`, bank-specific PDF parsers, text extraction, and enrichment).
   - Parsed transactions are mapped into app entities, deduplicated, enriched, and then persisted.

7. **Rules, categorization, and enrichment**
   - Transaction automation is handled by a rules subsystem: `RuleEngine`, rule templates, repositories, and use cases for applying rules to past or new transactions.
   - Enrichment layers include merchant/contact lookup, currency conversion, category mapping, subscription detection, and account-balance tracking.
   - These are all local, deterministic transformations sitting between ingestion and storage.

8. **On-device AI chat**
   - The app has a local AI assistant (`ChatScreen`, `ChatViewModel`, `LlmRepository`, `LlmServiceImpl`) intended to answer questions over the user’s own data.
   - The README indicates the model runs fully on-device via MediaPipe/Qwen 2.5, which makes this a privacy-preserving local inference path rather than a cloud API flow.
   - `AiContextRepository` suggests the assistant builds context from local finance data before generating answers.

9. **Pro features and entitlement**
   - Free/pro gating is handled through `EntitlementGate`, `FreeTierLimits`, purchase launchers, and product definitions.
   - The app is variant-aware: standard builds use Play Billing (`PlayBillingGateway`), while F-Droid builds substitute a no-op/local billing implementation (`FdroidBillingGateway`).
   - This is a compile-time/runtime boundary that affects feature access rather than core data flow.

10. **Widgets and background presentation**
   - Home-screen widgets for budgets and recent transactions are backed by their own receivers, data stores, and update workers.
   - Widget data is derived from the same local repositories/database, but serialized into lightweight widget-specific models.
   - This is a read-only projection layer, distinct from the main Compose UI.

11. **Cross-platform shared module**
   - `shared` is the KMP layer that centralizes reusable data models, repositories, statement parsing, bootstrapping, and use cases across Android/iOS.
   - It includes its own Room-based shared database abstraction, shared entities/DAOs, and domain use cases for transactions, budgets, accounts, rules, subscriptions, exchange rates, splits, and unrecognized SMS.
   - This module is the natural architecture boundary for logic intended to survive platform differences.

12. **iOS app**
   - The iOS app is a separate SwiftUI client with its own screens, view models, and theme/components.
   - It mirrors the product surface of the Android app—home, accounts, analytics, budgets, transactions, settings, onboarding, subscriptions, and rules—but uses Apple-native UI and app lifecycle code.
   - In an architecture diagram, it should be shown as a platform-specific front end consuming the shared domain/data layer rather than reusing Android UI code.

13. **Companion web/server**
   - `pennywise-web` is a separate Kotlin server application with routing, templating, feedback handling, parsing documentation, and SMS report collection.
   - It appears to support community-facing flows such as feedback submission, parse reporting, and roadmap/docs publishing, not the main consumer app runtime.
   - It has its own deployment/runtime boundary and database migrations.

14. **Operational and tooling boundaries**
   - The repo includes release automation, Fastlane Play metadata, Gradle build logic, tests, and extensive parser regression coverage.
   - Database migration snapshots and parser tests are especially important because they stabilize the SMS parsing and local schema evolution that the app depends on.

Main entry points: [`app/src/main/java/com/pennywiseai/tracker/ui/viewmodel/MainViewModel.kt`](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/viewmodel/MainViewModel.kt) (ViewModels), [`app/src/main/java/com/pennywiseai/tracker/data/database/PennyWiseDatabase.kt`](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/database/PennyWiseDatabase.kt) (Data layer), [`iosApp/iosApp/ViewModels/HomeViewModel.swift`](https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/ViewModels/HomeViewModel.swift) (ViewModels), [`shared/src/commonMain/kotlin/com/pennywiseai/shared/data/local/SharedDatabase.kt`](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/local/SharedDatabase.kt) (Shared database)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_android["Android app"]
  node_android_app["Android app<br/>runtime<br/>[MainActivity.kt]"]
  node_android_ui["Compose UI<br/>presentation<br/>[MainScreen.kt]"]
  node_android_vm["ViewModels<br/>state boundary<br/>[MainViewModel.kt]"]
  node_android_data[("Data layer<br/>repositories")]
  node_android_sms["SMS ingestion<br/>ingestion flow"]
  node_android_stmt["Statement import<br/>pdf import"]
  node_android_rules{{"Rules engine<br/>automation<br/>[RuleEngine.kt]"}}
  node_android_ai{{"Local AI<br/>on-device llm<br/>[LlmServiceImpl.kt]"}}
  node_android_billing{{"Entitlements<br/>billing gate<br/>[EntitlementGate.kt]"}}
  node_android_widgets["Widgets<br/>[BudgetWidget.kt]"]
  node_android_settings["Settings<br/>preferences<br/>[SettingsScreen.kt]"]
end

subgraph group_shared["Shared KMP"]
  node_shared_facade["Shared facade<br/>entry facade"]
  node_shared_db[("Shared database<br/>KMP Room<br/>[SharedDatabase.kt]")]
  node_shared_repo["Shared repos<br/>repositories"]
  node_shared_usecases{{"Shared use-cases<br/>domain logic"}}
  node_shared_stmt["Shared parsing<br/>statement parser"]
  node_shared_bootstrap{{"Bootstrap<br/>initialization"}}
end

subgraph group_ios["iOS app"]
  node_ios_app["iOS app<br/>runtime<br/>[iosAppApp.swift]"]
  node_ios_ui["SwiftUI UI<br/>presentation<br/>[MainTabView.swift]"]
  node_ios_vm["ViewModels<br/>state boundary"]
end

subgraph group_parser["Parser core"]
  node_parser_registry{{"Parser registry<br/>factory/registry"}}
  node_parser_banks["Bank parsers<br/>parser set<br/>[BankParser.kt]"]
end

subgraph group_web["Web/server"]
  node_web_server["Web server<br/>runtime<br/>[Application.kt]"]
  node_web_feedback["Feedback<br/>[FeedbackService.kt]"]
  node_web_reports["SMS reports"]
end

node_android_app -->|"hosts"| node_android_ui
node_android_ui -->|"drives"| node_android_vm
node_android_vm -->|"reads/writes"| node_android_data
node_android_vm -->|"applies"| node_android_rules
node_android_vm -->|"queries"| node_android_ai
node_android_sms -->|"parses via"| node_parser_registry
node_parser_registry -->|"selects"| node_parser_banks
node_android_sms -->|"persists"| node_android_data
node_android_stmt -.->|"reuses logic"| node_parser_registry
node_android_stmt -->|"imports to"| node_android_data
node_android_data -->|"feeds"| node_android_widgets
node_android_billing -->|"gates"| node_android_vm
node_android_billing -.->|"variants"| node_android_app
node_shared_facade -->|"bootstraps"| node_shared_db
node_shared_db -->|"backs"| node_shared_repo
node_shared_repo -->|"serves"| node_shared_usecases
node_shared_stmt -->|"imports"| node_shared_usecases
node_shared_bootstrap -->|"initializes"| node_shared_db
node_ios_app -->|"hosts"| node_ios_ui
node_ios_ui -->|"drives"| node_ios_vm
node_ios_vm -->|"uses"| node_shared_usecases
node_ios_vm -->|"reads/writes"| node_shared_repo
node_web_server -->|"routes"| node_web_feedback
node_web_server -->|"collects"| node_web_reports

click node_android_app "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/MainActivity.kt"
click node_android_ui "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/MainScreen.kt"
click node_android_vm "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/viewmodel/MainViewModel.kt"
click node_android_data "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/database/PennyWiseDatabase.kt"
click node_android_sms "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/receiver/SmsBroadcastReceiver.kt"
click node_android_stmt "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/statement/PdfParserFactory.kt"
click node_android_rules "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/domain/service/RuleEngine.kt"
click node_android_ai "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/service/LlmServiceImpl.kt"
click node_android_billing "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/billing/EntitlementGate.kt"
click node_android_widgets "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/widget/BudgetWidget.kt"
click node_android_settings "https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/screens/settings/SettingsScreen.kt"
click node_shared_facade "https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/PennyWiseSharedFacade.kt"
click node_shared_db "https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/local/SharedDatabase.kt"
click node_shared_repo "https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/repository/RoomSharedTransactionRepository.kt"
click node_shared_usecases "https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/domain/usecase/ManageBudgetUseCase.kt"
click node_shared_stmt "https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/statement/SharedStatementParserFactory.kt"
click node_shared_bootstrap "https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/bootstrap/SharedDataInitializer.kt"
click node_ios_app "https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/iosAppApp.swift"
click node_ios_ui "https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/App/MainTabView.swift"
click node_ios_vm "https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/ViewModels/HomeViewModel.swift"
click node_parser_registry "https://github.com/sarim2000/pennywiseai-tracker/blob/main/parser-core/src/main/kotlin/com/pennywiseai/parser/core/bank/BankParserFactory.kt"
click node_parser_banks "https://github.com/sarim2000/pennywiseai-tracker/blob/main/parser-core/src/main/kotlin/com/pennywiseai/parser/core/bank/BankParser.kt"
click node_web_server "https://github.com/sarim2000/pennywiseai-tracker/blob/main/pennywise-web/server/src/main/kotlin/Application.kt"
click node_web_feedback "https://github.com/sarim2000/pennywiseai-tracker/blob/main/pennywise-web/server/src/main/kotlin/feedback/FeedbackService.kt"
click node_web_reports "https://github.com/sarim2000/pennywiseai-tracker/blob/main/pennywise-web/server/src/main/kotlin/SmsReportService.kt"

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_android_app,node_android_ui,node_android_vm,node_android_data,node_android_sms,node_android_stmt,node_android_rules,node_android_ai,node_android_billing,node_android_widgets,node_android_settings toneBlue
class node_shared_facade,node_shared_db,node_shared_repo,node_shared_usecases,node_shared_stmt,node_shared_bootstrap toneAmber
class node_ios_app,node_ios_ui,node_ios_vm toneMint
class node_parser_registry,node_parser_banks toneRose
class node_web_server,node_web_feedback,node_web_reports toneIndigo
```

## Components

### Android app

Primary Android runtime with UI, ingestion, persistence, widgets, billing, and AI assistant.

- [Android app](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/MainActivity.kt): runtime · Main Android expense-tracking runtime and product shell. · `app/src/main/java/com/pennywiseai/tracker/MainActivity.kt`
- [Compose UI](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/MainScreen.kt): presentation · Bottom-nav shell, screens, shared composables, and presentation utilities. · `app/src/main/java/com/pennywiseai/tracker/ui/MainScreen.kt`
- [ViewModels](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/viewmodel/MainViewModel.kt): state boundary · Screen state and orchestration layer between UI and data/domain code. · `app/src/main/java/com/pennywiseai/tracker/ui/viewmodel/MainViewModel.kt`
- [Data layer](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/database/PennyWiseDatabase.kt): repositories · Room database, repositories, backup/export, enrichment, and local models. · `app/src/main/java/com/pennywiseai/tracker/data/database/PennyWiseDatabase.kt`
- [SMS ingestion](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/receiver/SmsBroadcastReceiver.kt): ingestion flow · Receivers, workers, and processors that normalize incoming bank messages. · `app/src/main/java/com/pennywiseai/tracker/receiver/SmsBroadcastReceiver.kt`
- [Statement import](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/statement/PdfParserFactory.kt): pdf import · PDF statement parsing, text extraction, enrichment, and import orchestration. · `app/src/main/java/com/pennywiseai/tracker/data/statement/PdfParserFactory.kt`
- [Rules engine](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/domain/service/RuleEngine.kt): automation · Deterministic transaction rules, templates, and historical rule application. · `app/src/main/java/com/pennywiseai/tracker/domain/service/RuleEngine.kt`
- [Local AI](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/data/service/LlmServiceImpl.kt): on-device llm · On-device finance assistant context building and inference service. · `app/src/main/java/com/pennywiseai/tracker/data/service/LlmServiceImpl.kt`
- [Entitlements](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/billing/EntitlementGate.kt): billing gate · Pro/free gating and variant-specific billing implementations. · `app/src/main/java/com/pennywiseai/tracker/billing/EntitlementGate.kt`
- [Widgets](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/widget/BudgetWidget.kt): home-screen widgets · Budget and recent-transaction projections backed by local repositories. · `app/src/main/java/com/pennywiseai/tracker/widget/BudgetWidget.kt`
- [Settings](https://github.com/sarim2000/pennywiseai-tracker/blob/main/app/src/main/java/com/pennywiseai/tracker/ui/screens/settings/SettingsScreen.kt): preferences · Appearance, lock, and configuration screens plus preference state. · `app/src/main/java/com/pennywiseai/tracker/ui/screens/settings/SettingsScreen.kt`

### Shared KMP

Cross-platform domain, persistence, and import logic reused by Android and iOS.

- [Shared facade](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/PennyWiseSharedFacade.kt): entry facade · KMP entrypoint exposing shared app logic across platforms. · `shared/src/commonMain/kotlin/com/pennywiseai/shared/PennyWiseSharedFacade.kt`
- [Shared database](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/local/SharedDatabase.kt): KMP Room · Cross-platform Room-style database abstraction, entities, and DAOs. · `shared/src/commonMain/kotlin/com/pennywiseai/shared/data/local/SharedDatabase.kt`
- [Shared repos](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/repository/RoomSharedTransactionRepository.kt): repositories · Platform-neutral repositories for finance domains and unrecognized SMS. · `shared/src/commonMain/kotlin/com/pennywiseai/shared/data/repository/RoomSharedTransactionRepository.kt`
- [Shared use-cases](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/domain/usecase/ManageBudgetUseCase.kt): domain logic · Cross-platform transaction, budget, account, rule, subscription, and import use-cases. · `shared/src/commonMain/kotlin/com/pennywiseai/shared/domain/usecase/ManageBudgetUseCase.kt`
- [Shared parsing](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/statement/SharedStatementParserFactory.kt): statement parser · Shared statement parsers and PDF text extraction for KMP clients. · `shared/src/commonMain/kotlin/com/pennywiseai/shared/data/statement/SharedStatementParserFactory.kt`
- [Bootstrap](https://github.com/sarim2000/pennywiseai-tracker/blob/main/shared/src/commonMain/kotlin/com/pennywiseai/shared/data/bootstrap/SharedDataInitializer.kt): initialization · Default categories and shared data initialization. · `shared/src/commonMain/kotlin/com/pennywiseai/shared/data/bootstrap/SharedDataInitializer.kt`

### iOS app

SwiftUI client layered over shared finance logic.

- [iOS app](https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/iosAppApp.swift): runtime · SwiftUI client for the shared expense-tracking product surface. · `iosApp/iosApp/iosAppApp.swift`
- [SwiftUI UI](https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/App/MainTabView.swift): presentation · Platform-native screens, components, and tab navigation. · `iosApp/iosApp/App/MainTabView.swift`
- [ViewModels](https://github.com/sarim2000/pennywiseai-tracker/blob/main/iosApp/iosApp/ViewModels/HomeViewModel.swift): state boundary · iOS state and screen orchestration layer. · `iosApp/iosApp/ViewModels/HomeViewModel.swift`

### Parser core

Standalone Kotlin SMS parser engine for bank and payment messages.

- [Parser registry](https://github.com/sarim2000/pennywiseai-tracker/blob/main/parser-core/src/main/kotlin/com/pennywiseai/parser/core/bank/BankParserFactory.kt): factory/registry · Central factory and registry for resolving the correct bank parser. · `parser-core/src/main/kotlin/com/pennywiseai/parser/core/bank/BankParserFactory.kt`
- [Bank parsers](https://github.com/sarim2000/pennywiseai-tracker/blob/main/parser-core/src/main/kotlin/com/pennywiseai/parser/core/bank/BankParser.kt): parser set · Large set of bank and payment-specific SMS parsers. · `parser-core/src/main/kotlin/com/pennywiseai/parser/core/bank/BankParser.kt`

### Web/server

Companion Kotlin server for feedback, parse reporting, and docs.

- [Web server](https://github.com/sarim2000/pennywiseai-tracker/blob/main/pennywise-web/server/src/main/kotlin/Application.kt): runtime · Kotlin server runtime for feedback, parse reporting, and docs. · `pennywise-web/server/src/main/kotlin/Application.kt`
- [Feedback](https://github.com/sarim2000/pennywiseai-tracker/blob/main/pennywise-web/server/src/main/kotlin/feedback/FeedbackService.kt): service · Feedback submission, fingerprinting, and related routing/views. · `pennywise-web/server/src/main/kotlin/feedback/FeedbackService.kt`
- [SMS reports](https://github.com/sarim2000/pennywiseai-tracker/blob/main/pennywise-web/server/src/main/kotlin/SmsReportService.kt): service · SMS report collection and parse-report support service. · `pennywise-web/server/src/main/kotlin/SmsReportService.kt`

## Connections

- Android app → Compose UI: hosts · Android activity and app shell present the Compose UI.
- Compose UI → ViewModels: drives · Screens delegate state and actions to ViewModels.
- ViewModels → Data layer: reads/writes · ViewModels coordinate repositories and persistence-backed flows.
- ViewModels → Rules engine: applies · Rule-related screens and flows use deterministic automation logic.
- ViewModels → Local AI: queries · Chat ViewModel builds assistant flows over local data.
- SMS ingestion → Parser registry: parses via · Inbound messages are normalized through parser-core.
- Parser registry → Bank parsers: selects · Registry resolves the appropriate bank or service parser.
- SMS ingestion → Data layer: persists · Normalized SMS events become local transactions and related records.
- Statement import → Parser registry: reuses logic · Statement import shares parsing concepts with the bank parser layer.
- Statement import → Data layer: imports to · Parsed statements are enriched and stored locally.
- Data layer → Widgets: feeds · Widgets derive lightweight projections from local repositories.
- Entitlements → ViewModels: gates · Entitlements constrain feature access in the UI flow.
- Entitlements → Android app: variants · Standard and F-Droid builds swap billing implementations.
- Shared facade → Shared database: bootstraps · Shared facade exposes the database-backed domain layer.
- Shared database → Shared repos: backs · Database DAOs and entities power shared repositories.
- Shared repos → Shared use-cases: serves · Repositories are consumed by shared domain use-cases.
- Shared parsing → Shared use-cases: imports · Statement parsing feeds shared import workflows.
- Bootstrap → Shared database: initializes · Default data seeds the shared local model.
- iOS app → SwiftUI UI: hosts · SwiftUI app entrypoint renders the native UI shell.
- SwiftUI UI → ViewModels: drives · Screens bind to platform ViewModels.
- ViewModels → Shared use-cases: uses · iOS delegates core finance behavior to the shared domain layer.
- ViewModels → Shared repos: reads/writes · iOS persists and reads via shared repositories.
- Web server → Feedback: routes · Server exposes feedback submission and related views.
- Web server → SMS reports: collects · Server handles SMS report intake and storage.
