No description
  • JavaScript 99.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
renovate-bot c5aca2263a
All checks were successful
CI / Frontend tests, backend tests, and build (push) Successful in 53s
Merge pull request 'Update vite' (#61) from renovate/vite into main
2026-08-17 12:02:50 +00:00
.forgejo/workflows Match house CI conventions: ubuntu-latest and qualified action URLs 2026-07-16 20:45:33 -05:00
backend Update dependency express-session to ^1.19.0 2026-08-03 12:02:41 +00:00
docs Reconcile calculation audit and changelog with degradation work 2026-07-16 20:58:45 -05:00
Specs Reorganization 2026-05-08 22:29:11 -05:00
src Add battery degradation and rate-escalation-adjusted payback 2026-06-05 13:41:20 -05:00
.dockerignore Add v1 Ameren MO rate & battery storage calculator 2026-05-08 23:16:54 -05:00
.env.example Complete power modeling roadmap 2026-05-14 00:03:59 -05:00
.gitignore Add gitignore and lockfiles for reproducible builds 2026-07-16 20:40:23 -05:00
CHANGELOG.md Reconcile calculation audit and changelog with degradation work 2026-07-16 20:58:45 -05:00
docker-compose.full.yml Add shared home calculation runtime 2026-05-22 12:48:14 -05:00
docker-compose.yml Add v1 Ameren MO rate & battery storage calculator 2026-05-08 23:16:54 -05:00
Dockerfile Wire full-stack auth proxy 2026-05-21 14:22:18 -05:00
index.html Add v1 Ameren MO rate & battery storage calculator 2026-05-08 23:16:54 -05:00
nginx.conf Wire full-stack auth proxy 2026-05-21 14:22:18 -05:00
package-lock.json Update vite 2026-08-17 12:02:44 +00:00
package.json Update vite 2026-08-17 12:02:44 +00:00
postcss.config.js Add v1 Ameren MO rate & battery storage calculator 2026-05-08 23:16:54 -05:00
README.md Refresh docs and move work tracking to Forgejo issues 2026-07-16 20:40:23 -05:00
renovate.json Add CI workflow and Renovate configuration 2026-07-16 20:40:23 -05:00
tailwind.config.js Add v1 Ameren MO rate & battery storage calculator 2026-05-08 23:16:54 -05:00
vite.config.js Add v1 Ameren MO rate & battery storage calculator 2026-05-08 23:16:54 -05:00

Ameren MO Rate Plan & Battery Storage Calculator

Interactive web app for comparing Ameren Missouri residential rate plans, modeling battery/solar ROI, evaluating backup runtime, and reconciling modeled bills against actual Ameren bills.

Run Frontend Only

docker compose up --build

Then open http://localhost:3000.

Run Full Stack

cp .env.example .env
docker compose -f docker-compose.full.yml up --build

The full stack starts:

  • frontend on port 3000
  • backend API on port 4000
  • PostgreSQL with a persistent Docker volume

Homelab / Caddy

The app works behind a normal subdomain reverse proxy. Point Caddy at the frontend container if you only run the frontend, or at the backend/frontend ports separately if you split them.

One simple pattern is:

battery.example.com {
  reverse_proxy 10.1.1.14:3000
}

If you expose backend APIs through the same hostname, proxy /api/* and /auth/* to the backend and everything else to the frontend:

battery.example.com {
  handle /api/* {
    reverse_proxy 10.1.1.14:4000
  }
  handle /auth/* {
    reverse_proxy 10.1.1.14:4000
  }
  handle {
    reverse_proxy 10.1.1.14:3000
  }
}

Authentik / OIDC

Authentication is configured with environment variables. No Authentik groups are required; home roles are managed inside the app.

Required for OIDC mode:

  • AUTH_MODE=oidc
  • AUTH_REQUIRED=true
  • PUBLIC_APP_URL=https://battery.example.com
  • SESSION_SECRET=<long random value>
  • OIDC_ISSUER_URL=<Authentik issuer URL>
  • OIDC_CLIENT_ID=<client id>
  • OIDC_CLIENT_SECRET=<client secret>
  • OIDC_REDIRECT_URI=https://battery.example.com/auth/callback

When using docker-compose.full.yml, the frontend container proxies /api/* and /auth/* to the backend container. Use FRONTEND_PORT for the public frontend port and BACKEND_HOST_PORT if you need to expose the backend directly. The backend always listens on port 4000 inside the Compose network.

The backend validates OIDC issuer, audience, expiration, signature, and login nonce. API routes for home-scoped data require home membership once auth is enabled.

Data Sources

  • Emporia usage: CSV import is the active path. Backend sync jobs and integration settings exist for a future official or user-provided adapter.
  • Weather: CSV import or Open-Meteo historical daily temperature sync using the home latitude/longitude.
  • Ameren billing: manual entry or CSV import. Ameren Missouri customer billing API support is not assumed.

Configuration And Backups

  • Browser state persists in localStorage.
  • JSON export/import remains available in the My Data tab.
  • Backend snapshot migration is available in the My Data tab when the API is reachable.
  • PostgreSQL backup example:
docker compose -f docker-compose.full.yml exec postgres pg_dump -U battery battery_storage > battery_storage.sql

Restore example:

docker compose -f docker-compose.full.yml exec -T postgres psql -U battery battery_storage < battery_storage.sql

Features

  • Overview: rate comparison, dispatch impact, and rate reference.
  • My Data: Emporia CSV import, circuit backup status, outage priority, whole-home exclusions, persistence tools.
  • Batteries: configurable battery library and cost metrics.
  • Backup: reserve settings, outage scenarios, load shedding, SOC/load charts.
  • Weather: home location, geocoding, weather import/sync, temperature correlation.
  • Solar: panel library, installer costs, export/no-export settings, lifetime production.
  • Billing: manual/CSV bill import and modeled-vs-actual reconciliation.
  • Quotes: installer quote scenarios with included hardware and revision history.
  • Projections: 15-year savings and payback projections.
  • Reports: saved report snapshots and shareable home dashboards.
  • Admin: auth status, homes, memberships, integration status, and backend diagnostics.

Database Migrations

Migrations run automatically on backend startup. To apply a new migration manually:

docker compose -f docker-compose.full.yml exec backend node src/migrate.js

Migrations are applied in filename order and recorded individually in the schema_migrations table, so each file runs exactly once.

Current migrations:

File Description
001_initial.sql Initial schema: users, homes, memberships, battery/inverter/solar/installer configurations, circuit assignments, imported usage, weather, external integrations, app state snapshots, background jobs
002_billing_auth_ops.sql Billing periods, home auth columns, and supporting indexes
003_circuit_whole_home_exclusion.sql Adds exclude_from_whole_home to circuit_assignments
003_home_audit_and_current_configs.sql Home audit events plus name indexes on home-scoped configuration tables
004_home_calculation_results.sql Cached calculation results per home
005_calculation_cache_revisions.sql Home data revision tracking and calculation cache lookup indexes
006_home_report_snapshots.sql Saved report snapshots

Note: two migrations share the 003_ prefix. This is harmless — ordering is deterministic and each is tracked by its full filename — but new migrations should use the next unused number (007_) to keep the sequence unambiguous.

Development

Frontend tests:

npm test

Backend tests:

npm --prefix backend test

Production build:

npm run build

CI runs all three of the above on every pull request to main (.forgejo/workflows/ci.yml).

Contributing

  • Planned work lives in Forgejo issues and milestones, not in a roadmap document. docs/roadmap.md is retained as a historical record of the completed build-out.
  • Changes are recorded in CHANGELOG.md following Keep a Changelog. Add user-visible changes to the Unreleased section as you go.
  • Versioning follows Semantic Versioning. The project is at 1.0.0 as of 2026-06-03.
  • Dependencies are managed by Renovate (renovate.json). Major updates require approval from the Renovate dependency dashboard rather than opening automatically.