Commit Graph
15 Commits
Author SHA1 Message Date
ngenohkevin f83f644cd3 v1.3.5: reparse progress spinner + Today default on Home
- Re-parse ALL now shows a spinner + "Re-parsing all transactions…"
  while running, so taps don't feel ignored. Button is hidden during
  the work; reappears after the result line.
- Empty result (no transactions to re-parse) shows a hint pointing at
  "Import SMS history" instead of a confusing "0 of 0".
- Home period selector defaults to Today instead of Month — the spec
  showed Month first, but in practice users want to see today's
  spending at a glance and switch out only when needed.
2026-05-16 22:08:59 +03:00
ngenohkevin 6571cd0497 v1.3.4: fix Fuliza auto-pay balance + outstanding + reparse-all
Two parser bugs around Fuliza auto-pay that produced wrong balance and
phantom-outstanding alerts:

1. BALANCE_REGEX required the literal "Ksh" before the amount, but the
   full-clear auto-pay SMS ends "Your M-PESA balance is 8581.08." with
   no Ksh prefix. Balance was lost → stored as 0 → Home's
   getLatestTransactionWithBalance filter (balance > 0) fell back to a
   stale older transaction. Made the Ksh optional.

2. parseFulizaAutoPay was stuffing the *available Fuliza limit* into
   fulizaOutstanding. Those are opposites (available = ceiling - owed).
   After a full clear that meant FulizaRule saw the full 14k limit and
   raised "You owe Ksh 14,000" — incorrect. Now:
     - full clear  -> fulizaOutstanding = 0   (rule correctly bails)
     - partial     -> fulizaOutstanding = null (rule defers to the
                                                previous Fuliza tx;
                                                avoids reporting the
                                                available-limit value)

Reparse all transactions
- New "Re-parse ALL transactions" entry in You → Data. Walks every
  stored row through MpesaSmsParser and updates parser-derived fields
  in place, preserving user fields (categoryId, accountId, note, id).
- Needed because the broken regex above silently corrupted historical
  rows on import; this is the no-data-loss path back to correctness.
2026-05-16 21:56:10 +03:00
ngenohkevin c5be379c8e v1.3.3: donut chart circularity + period selector on Home
DonutChart was hardcoded to a 180dp Canvas. When placed in a 50/50 Row
inside the "Where it went" card on the S24 Ultra, the canvas overflowed
the parent column and clipped into an oval. Switched to
fillMaxWidth + aspectRatio(1f) + fillMaxSize Canvas so the donut always
stays circular and scales to whatever the parent gives it. Stroke width
also scales (18% of the box, capped at 32dp).

Home screen lost the Today / This Week / Month period selector in the
bento rewrite (HomeViewModel still exposed it, the UI just never
rendered it). Restored as a LedgaChip row above the hero card. The
hero overline now also tracks the selection ("SPENT TODAY" /
"SPENT THIS WEEK" / "SPENT THIS MONTH").
2026-05-16 21:28:37 +03:00
ngenohkevin 5ca2f89303 v1.3.2 hotfix: migration FK crash + dark-theme insight teaser
MIGRATION_1_2 was using ALTER TABLE to add transactions.accountId, but
SQLite can't add a FOREIGN KEY via ALTER. Room validates schema after
migration and threw IllegalStateException ("Migration didn't properly
handle: transactions") because the FK to mpesa_accounts was missing.
The whole DB stayed at v1, blocking every read/write — which is why
SMS import + SMS receive looked dead too.

Fix: standard SQLite table-swap dance. Create transactions_new with
both FKs declared, INSERT … SELECT old rows in, drop the old table,
rename. All indices recreated. Defensive DROP IF EXISTS in case a
prior failed run left junk.

BentoCard now picks title + overline colors from the tonal background
luminance instead of unconditionally using onSurface. On dark theme
the Insights teaser had near-white text on the (light-theme) pale
green bg — invisible. Now it adapts:
  - light tonal bg → dark ink
  - dark tonal bg → light ink
HomeScreen Insights teaser switched from hardcoded LedgaAccentSoft to
MaterialTheme.colorScheme.primaryContainer so the bg itself also
adapts to theme.
2026-05-16 13:55:31 +03:00
ngenohkevin 3dc9e0305e v1.3.1 hotfix: status-bar overlap + font fallback
- LedgaTopBar now applies WindowInsets.statusBars padding. Previously
  enableEdgeToEdge was on but the top bar drew at y=0, so the avatar
  and trailing icons sat under the system clock / WiFi indicator.
- PillTabBar uses WindowInsets.navigationBars padding instead of a
  hardcoded 21dp bottom so the floating pill sits above the system
  gesture pill on devices like the S24 Ultra.
- Typography switched from Google-Fonts Inter to FontFamily.SansSerif.
  Inter requires a downloadable-fonts round-trip via Google Play
  Services that doesn't always succeed; the fallback was hitting
  FontFamily.Default, which inherits the user's system font choice —
  on Samsung One UI that's frequently a handwritten / script style
  and broke the type rhythm everywhere. SansSerif uses the platform
  sans (One UI Sans on Galaxy, Roboto elsewhere) regardless of user
  preference.
2026-05-16 13:36:23 +03:00
ngenohkevin 85c3f167ab Untrack internal planning docs
LEDGA_REDESIGN.md and PROJECT_PLAN.md are kept locally for reference
but shouldn't live in the public repo.
2026-05-16 13:26:22 +03:00
ngenohkevin 51264301a8 v1.3.0: major redesign — bento UI, Insights, Goals, multi-SIM, in-app updates
UI overhaul
- Modern fintech bento design system (LedgaText, Space, Radius, Motion).
- Inter font via Google Fonts.
- New PillTabBar + LedgaTopBar; 4-tab IA: Home / Activity / Insights / You.
- Home rewritten as bento cards; new AccountChip leading slot.
- Activity wraps Transactions + Trends behind a segmented control.
- Trends gains a GitHub-style heatmap calendar.
- You consolidates Settings into grouped bento cards.

Insights (Phase C)
- Rule engine + 6 rules: anomaly (z-score), recurring detection, fee tips,
  Fuliza outstanding, Fuliza auto-pay pairing, positive nudges.
- Daily InsightWorker (3 AM); generates on screen entry for first-time users.
- Natural-key dedup so dismiss/snooze state survives re-runs.
- Home teaser surfaces the top active insight.

Goals (Phase D)
- New Goal entity + GoalContribution table.
- 3 contribution rules: AllSavingsDeposits, ToRecipient, Manual.
- Rule-based contributions compute live via SQL aggregation (no
  duplicate rows). Manual rule uses goal_contributions table.
- GoalsScreen with progress rings + status badges; AddGoalSheet;
  GoalDetailScreen with contributing-transactions list.
- "Add to goal" entry in TransactionDetailSheet for Manual goals.

Multi-SIM (Phase E)
- MpesaAccount entity captured per-subscription on SMS receive
  (SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX with legacy fallback).
- READ_PHONE_STATE permission (optional; falls back to "Line N" labels).
- Every screen-facing query is account-scoped via TransactionRepository
  composing with the selected-account flow.
- AccountSwitcherSheet on Home; AccountsScreen with rename / recolor /
  set-primary; BackfillScreen with 3-prong attribution (SMS-inbox auto,
  date range, per-transaction manual via TransactionDetailSheet).

In-app updates (Phase F + G)
- Chunked APK download with progress reporting.
- UpdateRepository state machine (Idle → Downloading → Ready → Failed).
- Full-screen UpdateScreen with parsed What's new / Fixes sections.
- "Remind me later" persists dismissed version.
- Background UpdateCheckWorker pre-fetches APK on unmetered network.
- Home banner: "available" vs "ready to install" copy variants.
- Proactive REQUEST_INSTALL_PACKAGES permission prompt with settings
  deep-link before firing the installer intent.

Parser quality
- Hustler Fund "sent KshX to NAME" amount-first phrasing now matches.
- "Give cash to AGENT" agent-deposit format recognized as DEPOSIT.
- Fuliza auto-pay recipient labels rewritten as "Fuliza overdraft
  (auto-cleared / auto-partial)" for clearer transaction lists.
- 8 new real-world regression fixtures from sanitized export.
- Audit: 0 UNKNOWN against 6,565-transaction real history (was 838).

Database
- v3 schema: mpesa_accounts, goals, goal_contributions, insights tables.
- transactions gains accountId (FK), note.
- Explicit MIGRATION_1_2 + MIGRATION_2_3.

Tests
- 65 unit tests across parser (33), rule engine (14), goal rules (8),
  update logic (8), parser audit (1), insights dry-run (1).
- Two test suites (audit, dry-run) read the local export when present,
  skip cleanly in CI.

Design spec
- LEDGA_REDESIGN.md captures the full direction + tokens + per-screen
  wireframes + phased PR plan.

versionCode 3, versionName 1.3.0.
2026-05-16 13:17:54 +03:00
ngenohkevin 00975aa7cc Fix update notification: add banner UI + reset rate limit on version change 2026-03-21 22:35:00 +03:00
ngenohkevin d29498edbb Add re-parse unparsed messages button
Settings > Data now has "Re-parse Unparsed Messages" button that
re-runs the fixed parser on all UNKNOWN transactions, properly
categorizing previously missed Fuliza auto-deductions, withdrawals,
airtime, and reversals.
2026-03-21 22:26:45 +03:00
ngenohkevin 729ef15cd3 Fix parser + redesign UI
Parser fixes (838 → ~0 unparsed):
- Fuliza auto-deduction (full/partial pay from balance)
- Withdraw alt format (Withdraw Ksh from agent)
- Reversal alt format (Reversal of transaction)
- Airtime self with lowercase confirmed
- Hustler Fund with 4-digit year dates
- Balance check messages filtered out
- SMS normalization (newlines, extra spaces)
- Amount regex handles Ksh with/without space

UI improvements:
- Category-specific Material icons (not generic cart)
- Colored icon backgrounds with rounded corners
- Green balance card with M-Pesa branding
- Category breakdown section (where your money went)
- Balance uses last non-zero transaction
- Better card shapes (20dp rounded)
- Font weight hierarchy
2026-03-21 22:11:36 +03:00
ngenohkevin 0f2ad432d6 Fix CI: add contents write permission for release creation 2026-03-21 21:35:06 +03:00
ngenohkevin e7120fe5ee Fix: remove default WorkManagerInitializer for Hilt custom init 2026-03-21 21:24:11 +03:00
ngenohkevin 706993e084 Fix CI: create keystore directory before decoding 2026-03-21 21:12:09 +03:00
ngenohkevin 047565500e Add README with features, tech stack, and usage docs 2026-03-21 21:11:26 +03:00
ngenohkevin 79741192b9 Initial release — Ledga M-Pesa spending tracker
Complete Android app (Kotlin/Jetpack Compose) with:
- SMS parser for all 17 M-Pesa transaction types
- Room database with auto-categorization engine
- Real-time SMS capture via BroadcastReceiver
- Onboarding flow with SMS history import
- Home dashboard with balance, spending, donut chart
- Transactions list with search, filters, day grouping
- Trends screen with Vico bar charts, top merchants
- Budget system with progress tracking
- Transaction detail sheet with re-categorization
- Notifications (daily/weekly summaries, budget alerts)
- Google Drive backup & restore
- Manual export/import (CSV + JSON ZIP)
- Self-update system via GitHub Releases API
- Theme system (System/Light/Dark) + font scaling
- Adaptive app icon with splash screen
- GitHub Actions CI/CD for release APK builds
2026-03-21 20:53:59 +03:00