Budget Planner helps you manage budgets, allocate planned amounts to categories, and keep track of expenses. The project includes a web client and an authenticated REST API backed by PostgreSQL.
🚀 Demo: https://meow-budget-mashahori.msk1.amvera.tech/
- 🔐 Register and sign in with secure session-based authentication.
- 🔑 Recover forgotten passwords with one-time email reset links.
- 🗓️ Create and edit budgets with date ranges and currencies.
- 🗂️ Organize planned amounts into categories.
- 🧾 Add and manage expenses.
- 📊 Review planned, spent, and remaining amounts.
- 🌐 Switch the interface between Russian and English; the selected language is saved in the browser.
- 🗄️ Manage the database schema with PostgreSQL migrations.
- ☁️ Build and deploy with Docker on Amvera Cloud.
| Area | Technologies |
|---|---|
| Client | React, TypeScript, Vite, React Router, TanStack Query |
| Server | Node.js, Express, TypeScript |
| Database | PostgreSQL |
| Authentication | Express Session, PostgreSQL session store |
| Server tests | Jest |
| Deployment | Docker, Amvera Cloud |
- Node.js 24.21.0 or later
- PostgreSQL 14 or later
- npm
Create a local database:
createdb -U postgres budget_plannerAlternatively, run this in psql:
CREATE DATABASE budget_planner;Copy the example environment file and update server/.env with your local
PostgreSQL connection details:
cd server
Copy-Item .env.example .envSet the values in server/.env:
PORT=3000
CORS_ORIGIN=http://localhost:5173
DATABASE_URL=postgresql://postgres:your-password@localhost:5432/budget_planner
SESSION_SECRET=replace-with-a-random-secret-at-least-32-characters-long
CLIENT_URL=http://localhost:5173
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASSWORD=your-smtp-password
SMTP_FROM=Budget Planner <no-reply@example.com>Replace the database username and password with your own. SESSION_SECRET
must be a unique random value of at least 32 characters. Never commit real
credentials or secrets to Git. Configure the SMTP values with credentials
from your email provider to enable password recovery. Reset links expire after
30 minutes.
Install dependencies, apply the migrations, and start the server:
npm install
npm run migrate
npm run build
npm startThe API will be available at http://localhost:3000.
In a separate terminal, from the project root:
cd client
npm install
npm run devOpen the URL printed by Vite (by default, http://localhost:5173). During local
development, Vite proxies API requests to the server on port 3000.
Run these commands from the relevant directory.
Server (server):
npm test
npm run compile
npm run lint
npm run format:checkClient (client):
npm run compile
npm run lint
npm run format:check
npm run buildRun npm run format to format files automatically.
The repository is configured to build a Docker image from the project root. The image builds the client and server; the server serves the client app and runs pending database migrations when the container starts.
- Create a PostgreSQL database in Amvera and get its connection string.
- Create an application connected to this repository and use the repository
root as the build root (where
Dockerfileandamvera.ymlare located). - Set the following application environment variables:
DATABASE_URL— the PostgreSQL connection string.SESSION_SECRET— a unique random secret of at least 32 characters.
- Start a build and assign a domain to the application.
The container sets NODE_ENV=production and PORT=3000. Keep the database as a
separate resource so its data persists across deployments.
client/ React client
server/ Express API
server/src/db/migrations/ PostgreSQL migrations
server/docs/ API and data model documentation
Made to make planning your spending a little easier 💚