How nkrameshkrishnan/expense-tracker works
Purpose and Entry Points
Ledger is a zero-build, static expense-tracking SPA hosted on GitHub Pages. It uses a Google Sheet as the authoritative database through a Google Apps Script web app; browser seed data supports an unconnected demo mode.
Primary entry points:
• index.html loads the application shell and CDN dependencies.
• assets/app.js owns UI routing, views, forms, and user actions.
• google-apps-script/Code.gs is separately deployed as the Sheet-facing API.
• .github/workflows/deploy.yml produces the Pages deployment.
Client Application Shell
The frontend is ES-module JavaScript with no server runtime or package build. assets/app.js coordinates navigation between dashboard, transactions, budget, charts, and data-management flows, then renders against state supplied by the store.
• index.html
• assets/app.js
• assets/styles.css
Charts are browser-rendered through Chart.js, while spreadsheet import/export uses SheetJS loaded from CDNs.
State, Persistence, and Data Source Boundary
assets/store.js defines the data abstraction: a Sheets-backed store when configured, plus IndexedDB and memory/seed-backed behavior for local use. The configured endpoint/token may be injected at deployment or entered at runtime and retained in browser localStorage.
The key boundary is that the UI talks to a store API rather than directly assuming Google Sheets. On load or explicit reload, transaction and budget state is refreshed from the remote Sheet; failed writes are surfaced rather than queued offline.
• assets/store.js
• assets/config.js
• data/seed.json
Transaction and Budget Flow
Transactions use a normalized model with positive amount values; type determines whether a row represents expense or income. Client actions add, update, or delete transactions through the Sheets store, then refresh/render dependent dashboard and chart data.
Budget data is category-by-month and is maintained separately from transactions. Aggregation, CSV/XLSX-oriented transformations, and flat-table imports are handled in the browser.
• assets/app.js
• assets/store.js
• assets/xlsxio.js
Google Sheets API and Workbook Safety
google-apps-script/Code.gs is the authoritative mutation adapter. It exposes GET/POST handlers because Apps Script web apps do not support other verbs. Client mutations are POSTed as text/plain;charset=utf-8 to avoid an unanswerable CORS preflight.
The script validates the Transactions header layout before writing. It preserves the workbook’s established formulas and reports: dates are real Sheet Date objects; formula-backed Month/Year columns are not overwritten; deletes clear rows rather than removing them; inserts reuse cleared slots. Budget writes target only allowed month columns.
• google-apps-script/Code.gs
• assets/store.js
External Services and Security Boundary
GitHub Pages hosts public static assets. GitHub Actions can inject SHEETS_ENDPOINT and SHEETS_TOKEN into generated assets/config.js; this avoids committing them but does not hide them from deployed-page visitors. Runtime entry is the only option that keeps those values out of published assets.
Google Apps Script executes as the Sheet owner and accesses the Google Spreadsheet. A shared token protects API calls only when it is not shipped with the static client.
• .github/workflows/deploy.yml
• assets/config.js
• google-apps-script/Code.gs
Deployment Pipeline
The Pages workflow validates and publishes the static repository, overwriting endpoint configuration from optional GitHub secrets. No application compilation occurs. The Apps Script deployment is manual and independent: code changes require creating a new web-app deployment version.
• .github/workflows/deploy.yml
• assets/config.js
• index.html
Main entry points: store.js Store API · app.js UI router and views · index.html Application shell · deploy.yml Pages workflow
Components 15
Static browser client
Zero-build SPA served as static files.
- Application shell
index.html - UI router and views · Owns user actions, forms, and rendered screens.
assets/app.js - Client styles
assets/styles.css - Chart.js · Renders dashboard and analysis charts.
- Spreadsheet I/O · Handles flat-table imports and CSV/XLSX transformations.
assets/xlsxio.js
Data and API
Store abstraction and Google Sheets mutation boundary.
- Store API · Selects Sheets-backed, IndexedDB, or memory/seed behavior.
assets/store.js - Endpoint configuration · Accepts deployed or runtime-entered endpoint and token values.
assets/config.js - Browser persistence · Retains runtime connection settings and local data mode.
- Demo seed data · Supports unconnected browser demo mode.
data/seed.json - Sheets API adapter · GET/POST adapter that validates and safely mutates workbook rows.
google-apps-script/Code.gs - Google Spreadsheet · Stores transactions, budgets, formulas, and reports.
Delivery
Independent static-site and Apps Script deployment paths.
- Pages workflow · Validates and publishes static assets without a build step.
.github/workflows/deploy.yml - GitHub Pages · Serves the public SPA.
- GitHub secrets · Optional source for generated endpoint and token configuration.
- Apps Script deployment · New web-app versions are deployed independently.
Connections 16
- GitHub Pages → Application shell: serves
- Application shell → UI router and views: loads
- Application shell → Client styles: loads
- UI router and views → Store API: reads and mutates data
- UI router and views → Chart.js: renders charts with
- UI router and views → Spreadsheet I/O: imports and exports via
- Store API → Endpoint configuration: uses connection settings
- Endpoint configuration → Browser persistence: runtime values retained in
- Store API → Browser persistence: uses local mode
- Store API → Demo seed data: loads demo data
- Store API → Sheets API adapter: GET/POST text/plain API · Writes refresh state; failed writes are surfaced.
- Sheets API adapter → Google Spreadsheet: validates and safely updates · Preserves formulas and reuses cleared transaction rows.
- Pages workflow → Endpoint configuration: optionally injects secrets into
- GitHub secrets → Pages workflow: provides endpoint/token
- Pages workflow → GitHub Pages: publishes static repository
- Apps Script deployment → Sheets API adapter: deploys web-app version