A visual financial ledger engineered for speed, privacy, and seamless multi-device budgeting.
Features • Install • Architecture • Database • Developer & Build • Quick Start • Tech Stack • Roadmap
Ledgio isn't just another budgeting app — it's a local-first vault that works fully offline, syncs to your own Supabase account when you're online, with per-user data isolation enforced by Row Level Security. Glassmorphic 3D UI meets a carefully tested offline sync engine.
🌌 3D Interactive UI
|
📱 100% Offline-First PWA
|
⚡ Offline-First Sync Engine
|
🔐 Private Vault & Security
|
💎 Net Worth Hero Card
|
🎯 Savings Goals & Milestones
|
🤝 Loans & Debts
|
🛡️ Admin System & Announcements
|
🔑 Authentication & Identity
|
🏷️ Custom Categories & Budgets
|
💵 Income Ledger & History
|
💡 Leftover Funds Quick Action
|
| 💱 12 Live Currencies | Real-time exchange rates, synced daily with cached offline fallback — ₹ $ € £ د.إ S$ CA$ A$ ¥ ﷼ ৳ रू
|
| 📱 Touch-Optimized Ledger | Responsive stacked cards, 46px touch targets, search, category chips |
| 📈 2×2 Stat Grids | Income, Expenses, Remaining Balance, Savings Rate with visual spend caps |
| 📉 Interactive Analytics | 6-month spending trends, category breakdowns, month stepper navigation, 1-click CSV/JSON export |
| 💻 Desktop (Windows / Mac) | 📱 Mobile (Android / iOS / Mi / WebViews) |
|---|---|
| 1️⃣ Open Ledgio in Chrome or Edge | 1️⃣ Android — tap Install App or Menu (⋮) |
| 2️⃣ Click Install App | 2️⃣ iOS Safari — tap Share (⬆) → Add to Home Screen |
| 3️⃣ Launch from Desktop / Taskbar | 3️⃣ Webviews — tap (⋮) → Open in Chrome |
erDiagram
AUTH_USERS ||--|| PROFILES : "has profile"
AUTH_USERS ||--o{ EXPENSES : "records"
AUTH_USERS ||--o{ BUDGETS : "defines"
AUTH_USERS ||--o{ GOALS : "targets"
AUTH_USERS ||--o{ GOAL_DEPOSITS : "contributes"
GOALS ||--o{ GOAL_DEPOSITS : "tracks ledger"
AUTH_USERS ||--o{ LOANS : "tracks"
AUTH_USERS ||--o{ LOAN_SETTLEMENTS : "settles"
LOANS ||--o{ LOAN_SETTLEMENTS : "records history"
AUTH_USERS ||--o{ USER_CATEGORIES : "customizes"
AUTH_USERS ||--o{ APP_ANALYTICS : "generates"
AUTH_USERS ||--o{ ANNOUNCEMENTS : "receives"
AUTH_USERS ||--o{ INCOME_ENTRIES : "tracks income"
ANNOUNCEMENTS {
uuid id PK "Auto-generated UUID"
text message "Broadcast Alert Body"
timestamp created_at "Publication Timestamp"
}
PROFILES {
uuid id PK "auth.users FK"
text full_name "User Display Name"
text currency "Preferred Currency (INR, USD...)"
boolean dark_mode "Dark Theme Preference"
numeric income "Monthly Income Baseline"
text[] hidden_builtins "Hidden Built-in Category Keys"
integer reset_epoch "Authoritative Reset Epoch"
timestamp updated_at "LWW Sync Timestamp"
}
EXPENSES {
uuid id PK "Auto-generated UUID"
uuid user_id FK "auth.users Reference"
text name "Merchant / Description"
numeric amount "Transaction Value"
text category "Classified Category"
date date "Transaction Date"
timestamp updated_at "LWW Sync Timestamp"
}
BUDGETS {
uuid id PK "Auto-generated UUID"
uuid user_id FK "auth.users Reference"
text category "Assigned Category"
numeric monthly_limit "Monthly Spending Cap"
timestamp updated_at "LWW Sync Timestamp"
}
GOALS {
uuid id PK "Auto-generated UUID"
uuid user_id FK "auth.users Reference"
text name "Goal Target Name"
numeric target_amount "Target Savings Amount"
date target_date "Target Completion Date"
text category "Goal Category"
text color "Accent Color Hex"
text icon "FontAwesome Icon Class"
text notes "Optional Notes"
timestamp updated_at "LWW Sync Timestamp"
}
GOAL_DEPOSITS {
uuid id PK "Auto-generated UUID"
uuid goal_id FK "goals Reference (CASCADE)"
uuid user_id FK "auth.users Reference"
numeric amount "Signed Amount (+Deposit, -Withdrawal)"
date deposit_date "Contribution Date"
text note "Optional Memo"
timestamp updated_at "LWW Sync Timestamp"
}
LOANS {
uuid id PK "Auto-generated UUID"
uuid user_id FK "auth.users Reference"
text person_name "Contact Name"
text direction "lent / borrowed"
text kind "cash / on_behalf"
numeric principal "Loan Principal (>0)"
date loan_date "Disbursement Date"
text notes "Optional Reason / Memo"
timestamp updated_at "LWW Sync Timestamp"
}
LOAN_SETTLEMENTS {
uuid id PK "Auto-generated UUID"
uuid loan_id FK "loans Reference (CASCADE)"
uuid user_id FK "auth.users Reference"
numeric amount "Settlement Amount (>0)"
date settle_date "Payment Date"
text note "Optional Memo / Write-off"
timestamp updated_at "LWW Sync Timestamp"
}
USER_CATEGORIES {
uuid id PK "Auto-generated UUID"
uuid user_id FK "auth.users Reference"
text name "Category Name"
text icon "FontAwesome Icon Class"
text color "Accent Color Hex"
timestamp updated_at "LWW Sync Timestamp"
}
APP_ANALYTICS {
uuid id PK "Auto-generated UUID"
uuid user_id FK "Optional auth.users Reference"
text event_type "app_launch / app_install"
text platform "Android / iOS / Windows / macOS"
text display_mode "standalone / browser"
text device_type "mobile / desktop / tablet"
text app_version "Release Version"
text screen_res "Screen Dimensions"
timestamp created_at "Event Timestamp"
}
INCOME_ENTRIES {
uuid id PK "Auto-generated UUID"
uuid user_id FK "auth.users Reference"
uuid loan_id FK "Optional loans Reference (SET NULL)"
uuid settlement_id "Optional settlement Reference UUID"
numeric amount "Signed Amount"
date entry_date "Transaction Date"
text type "add / opening / adjustment"
text note "Optional Memo"
timestamp updated_at "LWW Sync Timestamp"
}
🔒 Every table is RLS-isolated per user. Deposits and settlements are first-class records — goal and loan balances are always computed, never stored.
📋 Table Specifications & Security Policies
| Table | Purpose | Security Policy (RLS) |
|---|---|---|
profiles |
Identity, avatar name, theme, income baseline, currency preferences, hidden built-ins, reset epoch | Restricted to auth.uid() = id |
expenses |
Transaction records, category mappings, dates, amounts, LWW timestamps | Isolated per account (auth.uid() = user_id) |
budgets |
Monthly spending limits and category allocations | Unique per (user_id, category) |
goals |
Target savings buckets — metadata & targets only, balance computed from deposits | Isolated per account (auth.uid() = user_id) |
goal_deposits |
First-class signed ledger records (+ deposit, - withdrawal) |
Cascades with parent goal, isolated to auth.uid() = user_id |
loans |
People-centric debt ledger — metadata, kind (cash/on_behalf), & principal only; outstanding computed from settlements |
Isolated per account (auth.uid() = user_id) |
loan_settlements |
Additive settlement records validating amount <= outstanding |
Cascades with parent loan, isolated to auth.uid() = user_id |
user_categories |
Custom categories cloud backup (name, icon, color) | Unique per (user_id, LOWER(name)), isolated to auth.uid() = user_id |
app_analytics |
Privacy-first install/launch telemetry | Permissive client INSERT; SELECT restricted strictly to Admin UUID via RLS (SEC-04); length and event-type CHECK constraints (phase5d) |
announcements |
System-wide broadcast alerts displayed in-app | SELECT allowed for all authenticated users; INSERT restricted strictly to Admin UUID via RLS |
income_entries |
Dated ledger of income events (add, opening, adjustment) with double-entry loan linkage |
Isolated per account (auth.uid() = user_id) |
Ledgio utilizes an offline-first modular domain architecture. Core sub-domains formerly housed inside a monolithic app.js have been surgically extracted into independent, cohesive modules that communicate with the host application via explicit dependency injection bridges (configure({ ... })).
| Module | Namespace | Purpose & Guarantees |
|---|---|---|
supabase-config.js |
SUPABASE_CONFIG |
Central credentials, authorized admin UUIDs, and the singleton client factory (window.getSupabaseClient()). |
sync-engine.js |
LedgioSyncEngine |
Offline FIFO mutation queue, LWW conflict resolver, exponential backoff replay, and Dead-Letter Queue (DLQ). Enforces Stage 0 unconditional enqueuing. |
loans.js |
LedgioLoans |
Loans & debt settlements ledger. Enforces dual loan kinds (cash vs on_behalf), zero cash-flow on cash write-offs, ledger-synced opening adjustments, and stealth masking. |
income.js |
LedgioIncome |
Dated income ledger, RFC 1321 MD5 deterministic opening balance IDs, monthly vs. lifetime calculations, and balance adjustment delta previews. |
goals.js |
LedgioGoals |
Target savings buckets, first-class additive deposits ledger, child-first cascade delete ordering, and celebration confetti. |
categories.js |
LedgioCategories |
Built-in category metadata, custom categories CRUD, cloud roaming cache (user_categories), hidden built-ins, and safe reassignment. |
expenses.js |
LedgioExpenses |
Expense CRUD, category monthly limits, 80%/100% warning threshold evaluations, and spend-by-category calculations. |
vault.js |
LedgioVault |
Private vault lock screen, PBKDF2/SHA-256 salted PIN hash, WebAuthn biometric unlock, inactivity/visibility auto-lock, and stealth privacy masking. |
pwa-installer.js |
— | PWA installation prompts, beforeinstallprompt interceptor, and platform-specific fallback guides. |
auth.js |
— | Supabase Auth/OAuth handlers, persistent sessions, hardened onAuthStateChange, transient SIGNED_OUT shields, and pre-logout safety checks. |
app.js |
— | Application orchestration, 3-phase bootstrap sequence, Chart.js trends, header controls, modal routing, and UI glue. |
📂 Click to expand full project tree
Ledgio/
├── .github/
│ └── workflows/
│ └── runtime-gate.yml # GitHub Actions CI Workflow for Automated Runtime Regression Gates
│
├── assets/
│ ├── css/
│ │ ├── styles.css # 3D Design Tokens, Mesh Lighting & Theme CSS
│ │ ├── styles.min.css # Production Minified Theme Styles
│ │ ├── dashboard.css # Dashboard Grid, Badges & Mobile Responsive CSS
│ │ └── dashboard.min.css # Production Minified Dashboard Styles
│ ├── js/
│ │ ├── app.js # Orchestration, Dashboard State, Charts & UI Glue
│ │ ├── app.min.js # Production Minified Orchestration Engine
│ │ ├── auth.js # Session Management, OAuth & Hardened Auth State Handlers
│ │ ├── auth.min.js # Production Minified Auth Module
│ │ ├── categories.js # Built-in & Custom Categories, Cloud Roaming & Reassignment
│ │ ├── categories.min.js # Production Minified Categories Domain
│ │ ├── expenses.js # Expense CRUD, Category Budgets & Warning Thresholds
│ │ ├── expenses.min.js # Production Minified Expenses Domain
│ │ ├── goals.js # Savings Goals, First-Class Deposits & Cascade Deletes
│ │ ├── goals.min.js # Production Minified Goals Domain
│ │ ├── income.js # Income Ledger, Dated Entries & Deterministic Opening Balances
│ │ ├── income.min.js # Production Minified Income Domain
│ │ ├── loans.js # Loans & Debt Settlements Ledger, Dual Kinds & Accounting Integrity
│ │ ├── loans.min.js # Production Minified Loans Domain
│ │ ├── pwa-installer.js # PWA Install Prompts, Diagnostics & Device Fallback
│ │ ├── pwa-installer.min.js # Production Minified PWA Engine
│ │ ├── supabase-config.js # Supabase Client Singleton Factory & Admin Configuration
│ │ ├── supabase-config.min.js # Production Minified Database Client Config
│ │ ├── sync-engine.js # Offline-First FIFO Mutation Queue, LWW Resolver & DLQ
│ │ ├── sync-engine.min.js # Production Minified Sync Engine
│ │ ├── vault.js # Private Vault, PIN Salt/Hash, WebAuthn, Stealth & Auto-Lock
│ │ └── vault.min.js # Production Minified Vault Domain
│ └── icons/
│ ├── favicon.png # Browser Tab Icon (32x32)
│ ├── apple-touch-icon.png # iOS Safari Web Clip Icon (180x180)
│ ├── icon-192.png # App Launcher Icon (192x192)
│ ├── icon-512.png # High-Res Launcher Icon (512x512)
│ └── icon-maskable-512.png # Adaptive Maskable Android Icon (512x512)
│
├── backend/
│ ├── migrations/
│ │ ├── phase3_offline_sync.sql # Offline-first sync engine & LWW triggers
│ │ ├── phase4_savings_goals.sql # Savings goals & first-class deposits DDL
│ │ ├── phase5_loans.sql # Loans & debt settlements ledger DDL
│ │ ├── phase5b_announcements.sql # System announcements & admin broadcast DDL
│ │ ├── phase5c_analytics_rls.sql # Telemetry RLS lockdown to Admin UUID (SEC-04)
│ │ ├── phase5d_analytics_hardening.sql # Length + event-type CHECK constraints on app_analytics (SEC-05)
│ │ ├── phase6_income_entries.sql # Dated income events ledger & opening balance backfill
│ │ ├── phase6b_loan_linked_income.sql # Loan & settlement foreign key references in income_entries
│ │ ├── phase7_categories.sql # Custom categories cloud persistence & hidden built-ins DDL
│ │ ├── phase7b_reset_epoch.sql # Multi-device reset epoch counter DDL
│ │ └── phase8_loan_kinds.sql # Dual loan kinds schema (cash vs on_behalf)
│ ├── README.md # Database Architecture & Deployment Guide
│ ├── supabase-schema.sql # Base PostgreSQL DDL, RLS Policies & Triggers
│ ├── verify_schema_phase4.sql # Schema & FK verification script (Goals)
│ └── verify_schema_phase5.sql # Schema & FK verification script (Loans)
│
├── scripts/
│ ├── build.ps1 # Automated UTF-8 Asset Minifier (auto-bumps SW cache)
│ ├── capture_loan_screenshots.ps1 # Automated multi-viewport screenshot capture utility
│ └── test_runtime_gate.ps1 # Headless Browser Runtime Regression Suite (244 assertion gates)
│
├── tests/
│ ├── headless_regression.html # Interactive in-browser DOM assertion harness (39 gate suites)
│ └── screenshot_loans.html # Visual test harness for multi-resolution loan card rendering
│
├── .gitignore # Git Exclusion Rules & Secrets Shield
├── README.md # Comprehensive Project Documentation
├── index.html # 3D SaaS Landing Page & Live Budget Simulator
├── dashboard.html # Core Financial Application (7 Modular Views)
├── login.html # Split-Screen Responsive Login Portal (OAuth Enabled)
├── signup.html # Split-Screen Responsive Signup Portal (OAuth Enabled)
├── manifest.json # PWA Web App Manifest, Shortcuts & Configuration
└── sw.js # Root-Scoped Offline Service Worker (v1.4.84)
1. Clone the repository
git clone https://github.com/Code-Breaker-Ctrl/Ledgio.git
cd Ledgio2. Run database migrations
In your Supabase SQL Editor, run these in order before enabling cloud sync:
| Step | File | Purpose |
|---|---|---|
| 1 | backend/supabase-schema.sql |
Base schema & RLS policies |
| 2 | backend/migrations/phase3_offline_sync.sql |
LWW timestamp triggers & offline engine |
| 3 | backend/migrations/phase4_savings_goals.sql |
Goals & goal-deposits ledger |
| 4 | backend/migrations/phase5_loans.sql |
Loans & debt settlements ledger |
| 5 | backend/migrations/phase5b_announcements.sql |
System announcements & admin broadcast DDL |
| 6 | backend/migrations/phase5c_analytics_rls.sql |
Telemetry RLS lockdown to Admin UUID (SEC-04) |
| 7 | backend/migrations/phase5d_analytics_hardening.sql |
Length + event-type CHECK constraints on app_analytics (SEC-05) |
| 8 | backend/migrations/phase6_income_entries.sql |
Dated income events ledger & opening balance backfill |
| 9 | backend/migrations/phase6b_loan_linked_income.sql |
Loan & settlement linkage in income_entries |
| 10 | backend/migrations/phase7_categories.sql |
Custom categories cloud persistence & hidden built-ins DDL |
| 11 | backend/migrations/phase7b_reset_epoch.sql |
Multi-device reset epoch counter DDL |
| 12 | backend/migrations/phase8_loan_kinds.sql |
Dual loan kinds schema (cash vs on_behalf) |
| ✓ optional | backend/verify_schema_phase4.sql |
Assert schema validity (Goals) |
| ✓ optional | backend/verify_schema_phase5.sql |
Assert schema validity (Loans) |
3. Configure Supabase & OAuth
Open assets/js/supabase-config.js and set your project credentials:
window.SUPABASE_CONFIG = {
url: 'https://your-project.supabase.co',
anonKey: 'your-anon-public-key'
};
// Optional: authorized administrative user UUIDs
window.LEDGIO_ADMIN_USER_IDS = ['your-admin-uuid-here'];In Supabase Dashboard → Authentication → URL Configuration, set the Site URL to your domain (e.g.
https://<username>.github.io/Ledgio/) and add redirect URLs for/dashboard.html,/, and/login.html. Then enable Google and/or GitHub under Authentication → Providers.
4. Launch the application
# Quick local launch with Python
python -m http.server 8000Open http://localhost:8000 in your browser. 🎉
In dashboard.html, all domain modules are deferred and load in strict dependency order before app.js:
<!-- 1. Supabase Client Library (CDN) -->
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2" defer></script>
<!-- 2. Database Config & Singleton Client Factory -->
<script src="assets/js/supabase-config.min.js?v=1.4.92" defer></script>
<!-- 3. Offline Sync Engine (FIFO Mutation Queue & LWW Engine) -->
<script src="assets/js/sync-engine.min.js?v=1.4.92" defer></script>
<!-- 4. Loans & Debts Domain (Dual Kinds & Accounting Integrity) -->
<script src="assets/js/loans.min.js?v=1.4.92" defer></script>
<!-- 5. Income Ledger Domain (Dated Entries & RFC 1321 MD5 Balances) -->
<script src="assets/js/income.min.js?v=1.4.92" defer></script>
<!-- 6. Savings Goals Domain (First-Class Deposits & Cascades) -->
<script src="assets/js/goals.min.js?v=1.4.92" defer></script>
<!-- 7. Categories Domain (Cloud Roaming & Dynamic Reassignment) -->
<script src="assets/js/categories.min.js?v=1.4.92" defer></script>
<!-- 8. Expenses & Budgets Domain (CRUD & 80%/100% Thresholds) -->
<script src="assets/js/expenses.min.js?v=1.4.92" defer></script>
<!-- 9. Private Vault Domain (PIN Hash, WebAuthn & Stealth Masking) -->
<script src="assets/js/vault.min.js?v=1.4.92" defer></script>
<!-- 10. PWA Installer & Device Detection -->
<script src="assets/js/pwa-installer.min.js?v=1.4.92" defer></script>
<!-- 11. Authentication & Hardened Session State Handlers -->
<script src="assets/js/auth.min.js?v=1.4.92" defer></script>
<!-- 12. Main Application Orchestration, Charts & Event Wiring -->
<script src="assets/js/app.min.js?v=1.4.92" defer></script>Why this order matters:
- Namespace Registration: Domain modules register their public namespaces (
LedgioSyncEngine,LedgioLoans,LedgioIncome,LedgioGoals,LedgioCategories,LedgioExpenses,LedgioVault) before orchestration runs. - Bridge Configuration:
app.jsconfigures each domain bridge viaLedgio<Domain>.configure({ ... }), injecting host dependencies (state access, toasts, undo, formatting, mutation enqueuing) without tight coupling. - Stage 0 Guarantees: Any user action within a domain module immediately persists locally and enqueues mutations through
LedgioSyncEngine.enqueueMutation(), maintaining offline autonomy.
Ledgio includes an automated asset minification script (scripts/build.ps1) that compresses stylesheets and JavaScript modules with UTF-8 encoding (no BOM):
powershell -ExecutionPolicy Bypass -File scripts\build.ps1- CSS Minification: Strips comments, collapses whitespace, and generates
.min.cssbundles (styles.min.css,dashboard.min.css). - JS Minification: Processes all 11 JavaScript modules (
supabase-config.js,sync-engine.js,loans.js,income.js,goals.js,categories.js,expenses.js,vault.js,pwa-installer.js,auth.js,app.js) to generate production-ready.min.jsfiles.
Ledgio maintains a comprehensive headless browser test runner (scripts/test_runtime_gate.ps1) powering automated verification in GitHub Actions CI and local testing:
powershell -ExecutionPolicy Bypass -File scripts\test_runtime_gate.ps1-
Test Scope: 244 automated assertion gates across 39 gate suites executed headlessly in Chromium / Edge against
tests/headless_regression.html. -
Core Verifications:
- Phase 1 Paint: Synchronous 0ms local paint from offline cache before network calls.
- Reset Epoch Recovery: Multi-device convergence, epoch incrementing, and remote wipe cascades.
-
Accounting Integrity: Zero cash-flow on cash write-offs, synchronized opening adjustments, principal
$\ge$ settled guards, and integer-cents precision. - Pay-Cycle & Recurring Salary: Custom pay-cycle day boundaries (1st to 28th), cycle-aware budget/income/expense partitioning, and automated monthly salary crediting with triple-guard idempotency.
- Vault Security: Synchronous Phase 1 lock screen gating, PBKDF2/SHA-256 salted PIN hashes, and stealth privacy masking across cards, modals, and tables.
- Sync Resilience: Offline FIFO mutation replay, dead-letter quarantine (DLQ), and clock-skew immunity.
- Session Stability: Supabase singleton client factory integrity, token refresh resilience, and transient sign-out immunity.
The major domain extraction is complete. All core financial domains (sync, loans, income, goals, categories, expenses, vault) now live in dedicated, standalone modules with clean host bridges. The remaining app.js is dedicated to top-level lifecycle orchestration, Chart.js trends, header navigation, and global view switches.
| Layer | Technology |
|---|---|
| Frontend | Vanilla JavaScript (ES6+), HTML5, CSS3 Glassmorphism, IntersectionObserver, content-visibility |
| PWA & Offline | Service Worker API (sw.js), Web App Manifest, BroadcastChannel API |
| Security & Hardware | WebAuthn API (PublicKeyCredential), Web Crypto API (SHA-256 salted PIN hashing) |
| Database & Auth | Supabase — PostgreSQL 15, Row Level Security, GoTrue Auth (Email + Google/GitHub OAuth) |
| Charts & Visuals | Chart.js, Canvas Confetti |
| Icons & Typography | Font Awesome 6, Plus Jakarta Sans, Space Grotesk |
| Testing & QA | Headless Edge/Chrome regression suite — 244 automated DOM assertion gates across 39 test suites (scripts/test_runtime_gate.ps1, GitHub Actions CI) |
- 🗓️ Month-Cycle Planner & Recurring Salary (v1.4.84) — custom pay-cycle start day boundaries (1st to 28th) and automated monthly salary crediting
- 📄 PDF Financial Statements — exportable monthly and annual financial statements
- 📦 TWA / Play Store Packaging — mobile wrapper with native
BiometricPromptbridge
Licensed under the MIT License — free for personal and commercial use.