diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f29b61e..cc0641c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,55 +1,12 @@ -# Contributing To OpenLedger +# Contributing to OpenLedger -Thanks for considering a contribution. OpenLedger is intentionally small, calm, and privacy-first. Changes should make the app more trustworthy, understandable, and maintainable without turning it into a bank-connected growth product. +Please see [docs/Contributing.md](docs/Contributing.md) for the full contributing guide. -## Local Setup +## Quick Links -```bash -git clone https://github.com/sparshsam/openledger.git -cd openledger -npm install -npm run dev -``` +- [Development Setup](docs/Development.md) +- [Architecture](docs/Architecture.md) +- [Deployment](docs/Deployment.md) +- [Testing](docs/Testing.md) -Open `http://localhost:3000`. - -## Required Checks - -Run these before opening a pull request: - -```bash -npm run lint -npm run typecheck -npm run build -``` - -For UI changes, also check: - -- Desktop around `1440x1000` -- Mobile around `390x900` -- CSV import preview -- Manual transaction form -- Account management -- JSON export/import - -## Product Principles - -- No bank login unless it is optional and clearly separated from local mode. -- No shame language, gamification, or manipulative finance copy. -- Prefer clear data ownership over convenience. -- Keep privacy limitations explicit. -- Keep the interface quiet and legible. - -## Pull Requests - -Please include: - -- What changed -- Why it changed -- Validation performed -- Screenshots for visual changes -- Known limitations or follow-up work - -## License - -By contributing, you agree that your contributions are provided under the project's AGPL-3.0-or-later license. +By contributing, you agree that your contributions will be licensed under AGPLv3. diff --git a/README.md b/README.md index fc470d8..d61aee7 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,183 @@ -# OpenLedger +
+ + + OpenLedger + +

OpenLedger

+

+ A private, local-first personal finance ledger. +
+ No bank connections, no dashboards, no noise. Your financial data stays on your device. +

+
+
-**A private, local-first personal finance ledger. No bank connections, no dashboards, no noise.** +

+ OpenLedger Dashboard +

-[![Live app](https://img.shields.io/badge/live-ledger.kovina.org-7A2F00?style=flat-square)](https://ledger.kovina.org) -[![CI](https://img.shields.io/github/actions/workflow/status/sparshsam/openledger/ci.yml?branch=main&style=flat-square&label=ci)](https://github.com/sparshsam/openledger/actions/workflows/ci.yml) -[![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0--or--later-6f7d61?style=flat-square)](LICENSE) -[![Next.js](https://img.shields.io/badge/Next.js-16-black?style=flat-square)](https://nextjs.org) -[![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?style=flat-square)](https://www.typescriptlang.org) +
-OpenLedger is a calm, local-first finance tool for everyday budgeting and records. It runs entirely in the browser — your financial data stays on your device unless you choose to back it up. +
-**Live app:** [https://ledger.kovina.org](https://ledger.kovina.org) +[![Website](https://img.shields.io/badge/website-ledger.kovina.org-7A2F00?style=for-the-badge&logo=vercel)](https://ledger.kovina.org) +[![Latest Release](https://img.shields.io/github/v/release/sparshsam/openledger?sort=semver&style=for-the-badge&label=Release&color=2563eb)](https://github.com/sparshsam/openledger/releases) +[![Source Code](https://img.shields.io/badge/Source%20Code-GitHub-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/sparshsam/openledger) -![OpenLedger dashboard](assets/screenshot-main.png) +
-## Quick Links +
-| Link | Description | -| --- | --- | -| [Live app](https://ledger.kovina.org) | Production deployment on Vercel | -| [Architecture docs](docs/architecture.md) | Data model, auth, and sync architecture | -| [Security policy](SECURITY.md) | Reporting guidance and current limitations | -| [Contributing](CONTRIBUTING.md) | Local setup and contribution expectations | -| [Changelog](CHANGELOG.md) | Notable project changes | -| [License](LICENSE) | AGPL-3.0-or-later | +--- + +## Gallery + +

+ Ledger Dashboard + Mobile View +

+ Transactions View +

+ +
+ +--- + +## Why OpenLedger + +Most finance tools want to connect to your bank, analyze your spending, and sell you insights. OpenLedger does none of that. + +**It's a ledger — not a dashboard.** Enter transactions manually. Track accounts, budgets, and goals. Your data lives in your browser. Cloud backup is optional and opt-in. No analytics, no telemetry, no third-party data collection. No bank credentials or Plaid connections. + +
+ +--- ## Features -- **Accounts** — Create checking, credit, savings, and loan accounts. Every transaction belongs to an account. -- **Transactions** — Manual entry with edit, duplicate, delete. Search, filter by date/account/category/type, sortable columns. -- **CSV Import** — Import bank statement CSV/TSV files with column mapping, preview, duplicate detection, and account selection. -- **Budgets** — Monthly spending plans with progress tracking and over-budget warnings. -- **Goals** — Savings milestones with target amounts, progress tracking, and contribution support. -- **Recurring Entries** — Schedule-based recurring transaction engine with upcoming entry preview. -- **Receipt Capture** — Photo upload from camera or gallery, stored in Supabase Storage. -- **Cloud Sync** — Signed-in users can manually back up and restore their ledger to Supabase. -- **Search** — Global search across all transactions with Quick Jump keyboard navigation. -- **Guest Mode** — Full local functionality without signing in. No account required. -- **MCP Server** — AI agents (Claude Code, Cursor, etc.) can read/write your data via the Model Context Protocol. -- **PWA** — Installable as a standalone app with service worker caching. - -## Tech Stack - -| Layer | Technology | -|-------|-----------| -| Framework | Next.js 16 (App Router) | -| Language | TypeScript 5 | -| Styling | Tailwind CSS 4 + custom CSS | -| State | React hooks + `localStorage` persistence | -| Auth | Supabase Auth (Google OAuth) | -| Cloud | Supabase Postgres (Elora project, `openledger_` prefix) | -| Crash Reporting | Sentry (optional) | -| Hosting | Vercel → [ledger.kovina.org](https://ledger.kovina.org) | -| License | AGPL-3.0-or-later | - -## Screenshots - -| Ledger dashboard | Transactions view | +
+ +| | | |---|---| -| ![Overview](assets/screenshot-main.png) | ![Transactions](assets/screenshot-search.png) | +| **Accounts** — Checking, credit, savings, loan. Every transaction belongs to an account. | **Transactions** — Manual entry, edit, duplicate, delete. Search, filter, sort. | +| **CSV Import** — Bank statement CSV/TSV import with column mapping, preview, dedup. | **Budgets** — Monthly spending plans with progress tracking and over-budget warnings. | +| **Goals** — Savings milestones with target amounts and progress tracking. | **Recurring Entries** — Schedule-based recurring transaction engine with preview. | +| **Receipt Capture** — Photo upload from camera or gallery to Supabase Storage. | **Guest Mode** — Full local functionality without signing in. No account required. | +| **Cloud Sync** — Manual backup and restore to Supabase (opt-in). | **Search** — Global search with Quick Jump keyboard navigation. | +| **MCP Server** — AI agents can read/write your data via Model Context Protocol. | **PWA** — Installable as a standalone app with offline caching. | + +
+ +
+ +--- + +## Designed For + +**People who want a calm, honest view of their finances — no algorithms, no upsells.** + +- **Budget-conscious individuals** tracking everyday spending against monthly plans +- **Freelancers** keeping simple income/expense records +- **Anyone tired of apps that try to sell them something while they check their balance + +
-## Privacy +--- -OpenLedger is **local-first by design**: +## Design Philosophy -- All data stays in your browser's `localStorage` by default. -- CSV parsing happens locally — no data is uploaded to a server. -- Cloud backup is **opt-in** — only triggered manually by signed-in users. -- No analytics, no telemetry, no third-party data collection. -- No bank credentials or Plaid connections. +> _"A calm finance tool — quiet, capable, private."_ -> **Important:** `localStorage` is convenient but not encrypted secure storage. Export JSON backups regularly and store them somewhere you control. +No dashboards. No charts begging for attention. No push notifications. Local-first by design — your data lives in your browser unless you choose to back it up. Clean typography, generous spacing, dark-mode first. Every screen has one job. -## Local Development +
-```bash -git clone https://github.com/sparshsam/openledger.git -cd openledger -npm install -npm run dev -``` +--- -Open [http://localhost:3000](http://localhost:3000). The app works fully without any environment variables. +## Built With -### Optional: Supabase auth + cloud backup +

+ Next.js 16 + TypeScript + Tailwind CSS 4 + Supabase + Vercel + MCP + Sentry +

-Copy `.env.example` to `.env.local` and uncomment the Supabase variables to enable Google sign-in and cloud backup. +
-## Deployment +--- -Deploys automatically from `main` to Vercel: +## Version Journey -```bash -npx vercel --prod -``` +| Version | Date | Highlights | +|---------|------|------------| +| **v0.11.0** | 2026-06 | Receipt capture, cloud sync, MCP server | +| **v0.10.0** | 2026-05 | Goals, recurring entries, CSV import engine | +| **v0.9.0** | 2026-05 | Budgets, search with Quick Jump | +| **v0.8.0** | 2026-04 | Guest mode, PWA readiness | +| **v0.7.0** | 2026-04 | Transaction search, filters, sortable columns | +| **v0.6.0** | 2026-03 | Multi-account support, CSV import | +| **v0.5.0** | 2026-03 | Accounts, transaction CRUD | +| **v0.4.0** | 2026-02 | IndexedDB persistence, local-first architecture | +| **v0.3.0** | 2026-02 | TypeScript migration, Tailwind CSS | +| **v0.2.0** | 2026-01 | Basic ledger UI, manual entry | +| **v0.1.0** | 2026-01 | Initial prototype | -Required environment variables for production: -- `NEXT_PUBLIC_SUPABASE_URL` — Supabase project URL -- `NEXT_PUBLIC_SUPABASE_ANON_KEY` — Public anon key -- `SUPABASE_SERVICE_ROLE_KEY` — For MCP token auth (server-only) +[Full Changelog](CHANGELOG.md) -## What's Next +
-See [ROADMAP.md](ROADMAP.md) for planned work. Current release is **v0.9.11** — Release Readiness. +--- ## License -AGPL-3.0-or-later. See [LICENSE](LICENSE). +AGPL-3.0-or-later — see [LICENSE](LICENSE) + +Built by [@sparshsam](https://github.com/sparshsam) + +
+ +--- + +## Part of the Open Collection + +

+ + + + + + + +
+ OpenPalette
+ OpenPalette
+ A color studio for designers
+ Repo · + Web +
+ OpenSend
+ OpenSend
+ Free file sharing, no account needed
+ Repo · + Web +
+ OpenSprout
+ OpenSprout
+ Plant care records
+ Repo · + Web +
+ OpenTone
+ OpenTone
+ Offline music library
+ Repo +
+

+ +

+ View all Open* repositories → +

diff --git a/assets/branding/icon-512.png b/assets/branding/icon-512.png new file mode 100644 index 0000000..c4b4260 Binary files /dev/null and b/assets/branding/icon-512.png differ diff --git a/assets/branding/icon-source.png b/assets/branding/icon-source.png new file mode 100644 index 0000000..ba4e349 Binary files /dev/null and b/assets/branding/icon-source.png differ diff --git a/assets/branding/icon.svg b/assets/branding/icon.svg new file mode 100644 index 0000000..e17e7b1 --- /dev/null +++ b/assets/branding/icon.svg @@ -0,0 +1,4 @@ + + + OL + \ No newline at end of file diff --git a/assets/gallery/dashboard-mobile.png b/assets/gallery/dashboard-mobile.png new file mode 100644 index 0000000..1e8a2c3 Binary files /dev/null and b/assets/gallery/dashboard-mobile.png differ diff --git a/assets/gallery/screenshot-main.png b/assets/gallery/screenshot-main.png new file mode 100644 index 0000000..aa3a002 Binary files /dev/null and b/assets/gallery/screenshot-main.png differ diff --git a/assets/gallery/screenshot-search.png b/assets/gallery/screenshot-search.png new file mode 100644 index 0000000..d557f1c Binary files /dev/null and b/assets/gallery/screenshot-search.png differ diff --git a/assets/hero/dashboard-desktop.png b/assets/hero/dashboard-desktop.png new file mode 100644 index 0000000..aa3a002 Binary files /dev/null and b/assets/hero/dashboard-desktop.png differ diff --git a/docs/Architecture.md b/docs/Architecture.md new file mode 100644 index 0000000..2670bd4 --- /dev/null +++ b/docs/Architecture.md @@ -0,0 +1,37 @@ +# Architecture + +> Full architecture documentation at [`docs/architecture.md`](architecture.md) (existing). + +## Overview + +OpenLedger is a **local-first** single-page application. The entire ledger runs in the browser with IndexedDB as the primary data store and localStorage as a fallback. Cloud sync via Supabase is optional and opt-in. + +## Stack + +``` +Framework: Next.js 16 (App Router) +Language: TypeScript 5 +Styling: Tailwind CSS 4 + custom CSS +State: React hooks + IndexedDB persistence +Auth: Supabase Auth (Google OAuth) — optional +Cloud: Supabase Postgres (Elora project, openledger_ prefix) +Crash: Sentry (optional) +Hosting: Vercel → ledger.kovina.org +License: AGPL-3.0-or-later +``` + +## Storage Architecture + +``` +Browser (Next.js SPA) + ├── IndexedDB — primary data store + ├── localStorage — secondary store (learnings, rules, settings) + ├── Service Worker — offline cache, PWA shell + ├── Supabase Auth — optional Google sign-in + ├── Supabase Postgres — optional cloud backup + └── Supabase Storage — optional receipt photos +``` + +## Additional Resources + +- [Architecture (full)](architecture.md) diff --git a/docs/Contributing.md b/docs/Contributing.md new file mode 100644 index 0000000..7a1a89b --- /dev/null +++ b/docs/Contributing.md @@ -0,0 +1,12 @@ +# Contributing + +> The full contributing guide is at [`CONTRIBUTING.md`](../CONTRIBUTING.md). + +## Quick Summary + +1. Create a feature branch from `main` +2. Run all checks before submitting +3. Keep changes focused — one feature per PR +4. Update CHANGELOG.md + +By contributing, you agree that your contributions will be licensed under AGPLv3. diff --git a/docs/Deployment.md b/docs/Deployment.md new file mode 100644 index 0000000..5bdb60d --- /dev/null +++ b/docs/Deployment.md @@ -0,0 +1,17 @@ +# Deployment + +Deploys automatically from `main` to Vercel. + +[https://ledger.kovina.org](https://ledger.kovina.org) + +```bash +npx vercel --prod +``` + +## Required Environment Variables + +| Variable | Description | +|----------|-------------| +| `NEXT_PUBLIC_SUPABASE_URL` | Supabase project URL | +| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Public anon key | +| `SUPABASE_SERVICE_ROLE_KEY` | For MCP token auth (server-only) | diff --git a/docs/Development.md b/docs/Development.md new file mode 100644 index 0000000..dadcb62 --- /dev/null +++ b/docs/Development.md @@ -0,0 +1,39 @@ +# Development + +## Prerequisites + +- Node.js 20+ +- npm +- Supabase account (optional, for cloud sync) + +## Setup + +```bash +git clone https://github.com/sparshsam/openledger.git +cd openledger +npm install +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000). The app works fully without any environment variables. + +### Optional: Supabase auth + cloud backup + +Copy `.env.example` to `.env.local` and uncomment the Supabase variables to enable Google sign-in and cloud backup. + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `NEXT_PUBLIC_SUPABASE_URL` | Supabase project URL | +| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Public anon key | +| `SUPABASE_SERVICE_ROLE_KEY` | For MCP token auth (server-only) | + +## Commands + +| Command | Description | +|---------|-------------| +| `npm run dev` | Start development server | +| `npm run lint` | Run ESLint | +| `npm run typecheck` | TypeScript type checking | +| `npm run build` | Build for production | diff --git a/docs/Testing.md b/docs/Testing.md new file mode 100644 index 0000000..9caf01b --- /dev/null +++ b/docs/Testing.md @@ -0,0 +1,20 @@ +# Testing + +## Running Tests + +```bash +# Lint +npm run lint + +# Type checking +npm run typecheck + +# Build verification +npm run build +``` + +## Before Submitting a PR + +1. Run `npm run lint`, `npm run typecheck`, `npm run build` +2. Keep changes focused — one feature per PR +3. Update CHANGELOG.md