{"id":49021059,"url":"https://github.com/jkdevcode/trackmyexpenses","last_synced_at":"2026-04-19T04:01:42.562Z","repository":{"id":345380366,"uuid":"1026769364","full_name":"jkdevcode/trackmyexpenses","owner":"jkdevcode","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-14T20:57:46.000Z","size":14945,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T22:28:28.123Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jkdevcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-26T15:19:28.000Z","updated_at":"2026-04-10T15:51:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jkdevcode/trackmyexpenses","commit_stats":null,"previous_names":["jkdevcode/trackmyexpenses"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jkdevcode/trackmyexpenses","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkdevcode%2Ftrackmyexpenses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkdevcode%2Ftrackmyexpenses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkdevcode%2Ftrackmyexpenses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkdevcode%2Ftrackmyexpenses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jkdevcode","download_url":"https://codeload.github.com/jkdevcode/trackmyexpenses/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkdevcode%2Ftrackmyexpenses/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31994010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-19T04:01:40.240Z","updated_at":"2026-04-19T04:01:42.541Z","avatar_url":"https://github.com/jkdevcode.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TrackMyExpenses\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](./LICENSE)\n[![Backend CI](https://github.com/jkdevcode/trackmyexpenses/actions/workflows/backend-ci.yml/badge.svg)](https://github.com/jkdevcode/trackmyexpenses/actions/workflows/backend-ci.yml)\n[![Frontend CI](https://github.com/jkdevcode/trackmyexpenses/actions/workflows/frontend-ci.yml/badge.svg)](https://github.com/jkdevcode/trackmyexpenses/actions/workflows/frontend-ci.yml)\n[![Dockerized](https://img.shields.io/badge/Dockerized-Yes-2496ED.svg?logo=docker\u0026logoColor=white\u0026style=flat-square)](#docker-compose)\n[![Version](https://img.shields.io/badge/version-v1.0.0-0A7EA4.svg?style=flat-square)](https://github.com/jkdevcode/trackmyexpenses/tags)\n\nTrackMyExpenses is a full-stack expense management platform built as a monorepo with a React frontend and a NestJS backend. The application combines secure authentication, OCR-assisted invoice capture, multi-currency expense tracking, shared date filters, PDF reporting, and a Docker-ready local environment in a single workflow.\n\n## Features\n\n- Secure authentication with register, login, logout, protected routes, and password recovery via email reset links.\n- Invoice workflows for manual entry and OCR-assisted capture, including product snapshots and quantity validation that only allows decimal quantities for `kg` items.\n- Shared filtering across dashboard, invoices, and reports with `week`, `month`, `year`, `all`, and `custom` date ranges.\n- Dashboard analytics and PDF reports with availability checks before download.\n- Multi-currency invoices with exchange-rate support and normalized totals in the user's base currency.\n- Localized public pages, legal pages, cookie consent messaging, and contact metadata for the frontend experience.\n- Dockerized frontend, backend, and MySQL services for local smoke tests and container-based deployment workflows.\n\n## Tech Stack\n\n| Layer | Stack |\n| --- | --- |\n| Frontend | React 19, Vite, TypeScript, TanStack Query, React Hook Form, Yup, HeroUI, i18next, Playwright |\n| Backend | NestJS 11, Prisma, MySQL, Zod, JWT cookie auth, Nodemailer, Puppeteer, Tesseract.js |\n| Integrations | Gemini OCR assistance, Exchange Rate API, Redis cache (optional), Sentry (frontend, optional), SMTP |\n| DevOps | Docker, Docker Compose, Nginx, GitHub Actions, GHCR |\n\n## Project Structure\n\n- `frontend/`: React SPA with feature-based modules for auth, dashboard, invoices, reports, settings, landing, and legal pages.\n- `backend/`: NestJS REST API under `/api` with Prisma, Swagger, auth, invoices, OCR, reporting, and infrastructure modules.\n- `.github/workflows/`: CI/CD workflows for backend, frontend, Docker smoke tests, and staging delivery.\n\n## Getting Started\n\n1. Copy `backend/.env.example` to `backend/.env` and `frontend/.env.example` to `frontend/.env`.\n2. Install dependencies in each app:\n   - `cd backend \u0026\u0026 npm install`\n   - `cd frontend \u0026\u0026 npm install`\n3. Start MySQL locally. You can use your own server or run only the database container from the repo root:\n   - `docker compose up -d mysql`\n4. Prepare the database from `backend/`:\n   - `npx prisma migrate dev`\n5. Start the backend:\n   - `npm run start:dev`\n6. Start the frontend from `frontend/`:\n   - `npm run dev`\n7. Open the app at `http://localhost:5173` and Swagger at `http://localhost:3000/docs`.\n\n## Docker Compose\n\n1. Copy the root `.env.example` to `.env` and `backend/.env.example` to `backend/.env`.\n2. Review the root compose values, especially `MYSQL_ROOT_PASSWORD`, `VITE_API_URL`, `VITE_ASSETS_URL`, and `FRONTEND_PORT`.\n3. Start the full stack from the repository root:\n   - `docker compose up --build -d`\n4. Open:\n   - Frontend: `http://localhost:5173`\n   - Backend API: `http://localhost:3000/api`\n   - Swagger: `http://localhost:3000/docs`\n5. Health checks are exposed at:\n   - Frontend: `http://localhost:5173/healthz`\n   - Backend: `http://localhost:3000/api/health`\n\nNotes:\n\n- The frontend container serves the Vite build through Nginx.\n- The backend container runs `docker-entrypoint.sh`, generates the Prisma client, and applies `prisma migrate deploy` when `PRISMA_MIGRATE_DEPLOY=true`.\n- The backend image now normalizes shell-script line endings during build and waits for a successful database connection before running Prisma startup steps, which makes `docker compose up` more reliable on Windows-based checkouts.\n- Inside the Docker Compose network, the backend connects to MySQL with the host `mysql`. Local host-machine processes should keep using `localhost`.\n\n## Delivery and Tooling\n\n- GitHub Actions validate backend tests, frontend build/E2E, Docker image builds, and a Docker Compose smoke test.\n- A manual CD workflow builds and pushes the backend image to GHCR and can trigger a staging rollout over SSH.\n- A Postman collection for the API lives in `backend/docs/postman/trackmyexpenses.postman_collection.json`.\n\n## Documentation\n\n- [`backend/README.md`](./backend/README.md): API capabilities, auth flow, SMTP setup, Swagger, and backend environment variables.\n- [`frontend/README.md`](./frontend/README.md): frontend routes, auth/report flows, shared filters, state management, and frontend environment variables.\n- [`.github/workflows/README.md`](./.github/workflows/README.md): CI/CD workflow responsibilities, Docker smoke tests, and staging deployment notes.\n- [`backend/docs/postman/README.md`](./backend/docs/postman/README.md): how to use the shared Postman collection.\n\n## 📄 License\n\nThis project is licensed under the [MIT License](./LICENSE). See the `LICENSE` file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjkdevcode%2Ftrackmyexpenses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjkdevcode%2Ftrackmyexpenses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjkdevcode%2Ftrackmyexpenses/lists"}