How digvijaynarayanpandey/expense-tracker-app works
1. Repo shape
This is a two-app monorepo: a React/Vite frontend in frontend/ and an Express/Mongoose backend in backend/. The backend exposes a REST API; the frontend is a single-page app that consumes it over HTTP.
2. Top-level product boundary
The application centers on personal finance tracking for one authenticated user. Core domain objects are User, Income, and Expense, with the dashboard acting as the read-model that aggregates those records into charts, summary cards, and recent-activity lists.
3. Frontend presentation layer
frontend/src/pages/ defines route-level screens for landing, auth, dashboard home, income, expense, guides, policy pages, and 404. components/ holds reusable UI blocks for cards, charts, forms, modals, navigation, and alerts. This is a classic page/layout/component split.
4. Frontend app shell and state
App.jsx and main.jsx bootstrap routing and the React tree. context/UserContext.jsx plus hooks/useUserAuth.jsx manage session-aware user state. ThemeContext suggests a UI preference boundary, separate from auth and data state.
5. Frontend-to-backend integration
utils/axiosInstance.js and utils/apiPaths.js centralize API calls. The client stores the JWT locally and attaches it to requests through the axios layer. The frontend depends on this to access protected routes like dashboard, income, expense, and profile endpoints.
6. Backend API surface
The Express app is split by resource: authRoutes, dashboardRoutes, incomeRoutes, and expenseRoutes. Controllers implement the business logic for registration/login, profile image updates, aggregate dashboard data, CRUD for income/expense, and Excel export endpoints.
7. Authentication and authorization flow
authController issues JWTs after login and likely hashes passwords through the User model layer or controller logic. authMiddleware protects all finance and profile routes by verifying the bearer token and attaching the authenticated user to the request context. Ownership checks prevent users from deleting records they do not own.
8. Persistence layer
config/db.js connects to MongoDB via Mongoose. The schema boundary is simple: User stores credentials and profile image URL, while Income and Expense store user-scoped financial transactions with date, amount, label/category, and emoji icon. This makes MongoDB the system of record for all finance data.
9. File upload boundary
middleware/uploadMiddle.js handles multipart uploads for profile photos. Uploaded images are stored in the backend’s uploads/ area, then their URL is saved back to the user record. This is a separate flow from normal JSON-based CRUD.
10. Reporting and aggregation
dashboardController computes cross-collection summaries such as total balance, total income, total expense, recent transactions, and time-windowed trends. The frontend dashboard components then render those aggregates into pie, bar, and line charts via Recharts.
11. Transaction workflows
Income and expense pages use modal-based forms, emoji pickers, and list views for create/read/delete interactions. Each transaction type has its own overview component, indicating separate UX and API paths even though they share the same conceptual pattern.
12. Export and offline artifacts
The backend includes Excel generation via xlsx for both income and expense exports. Those downloads are initiated from the frontend as file responses, so report generation is server-side rather than client-side.
13. Static/public and deployment concerns
The frontend includes public/ assets like robots.txt, sitemap.xml, and a verification HTML file, which suggests SEO and site verification are part of the deployed SPA. frontend/vercel.json indicates frontend hosting/deployment configuration is treated separately from the backend runtime.
14. Architecture diagram takeaway
The clean diagram should show: browser SPA → axios-based REST calls → Express controllers/middleware → Mongoose models → MongoDB, with a side branch for image upload storage and another for Excel file downloads. The key boundaries are auth, transaction CRUD, dashboard aggregation, and profile media handling.
Main entry points: components UI blocks · routes API routes · dashboardController.js Dashboard agg · authController.js Auth flow
Components 20
Frontend
React/Vite SPA
- App shell · Vite entry and top-level routing
frontend/src/main.jsx - Route pages · Landing, auth, dashboard, guides, policy and error screens
frontend/src/pages - Layouts · Auth and dashboard shells with nav and side menu
frontend/src/components/layouts - UI blocks · Cards, charts, forms, modals, alerts and reusable inputs
frontend/src/components - User state · Auth-aware user context and session hook
frontend/src/context - Theme state · Theme context for visual mode preferences
frontend/src/context/ThemeContext.jsx - API client · Axios instance and endpoint path helpers
frontend/src/utils/axiosInstance.js - Image upload · Frontend helper for profile photo upload flow
frontend/src/utils/uploadImage.js
Backend
Express/Mongoose API
- API server · Backend runtime and route wiring
backend/server.js - API routes · Auth, dashboard, income and expense route modules
backend/routes - Auth flow · Registration, login and profile update logic
backend/controllers/authController.js - Dashboard agg · Cross-collection summaries and trend calculations
backend/controllers/dashboardController.js - Income CRUD · Income create, read, delete and export logic
backend/controllers/incomeController.js - Expense CRUD · Expense create, read, delete and export logic
backend/controllers/expenseController.js - Auth guard · JWT verification and request user attachment
backend/middleware/authMiddleware.js - Upload middleware · Profile photo upload handling
backend/middleware/uploadMiddle.js - MongoDB · Mongoose connection setup
backend/config/db.js - User model · Credentials and profile fields
backend/models/User.js - Income model · User-scoped income transactions
backend/models/Income.js - Expense model · User-scoped expense transactions
backend/models/Expense.js
Connections 30
- App shell → Route pages: renders · Bootstraps route-level screens
- App shell → Layouts: wraps · Uses shared application shells
- Route pages → UI blocks: composes · Pages reuse shared UI blocks
- Layouts → User state: reads · Layouts depend on session-aware user state
- User state → API client: calls · User state uses API client for auth and profile data
- UI blocks → API client: calls · Forms and lists fetch or mutate data via axios
- Image upload → API client: uses · Upload helper sends requests through API layer
- User state → Theme state: separates · Theme preference is independent from auth state
- API client → API server: HTTP · Frontend talks to backend over REST
- API server → API routes: mounts · Express server registers resource routes
- API routes → Auth flow: dispatches · Auth endpoints
- API routes → Dashboard agg: dispatches · Dashboard endpoints
- API routes → Income CRUD: dispatches · Income endpoints
- API routes → Expense CRUD: dispatches · Expense endpoints
- Auth flow → Auth guard: protected by · Protected routes verify JWT bearer tokens
- Dashboard agg → Auth guard: protected by · Dashboard data requires authenticated user
- Income CRUD → Auth guard: protected by · Income CRUD is user-scoped
- Expense CRUD → Auth guard: protected by · Expense CRUD is user-scoped
- Auth flow → Upload middleware: uses · Profile image updates use multipart upload flow
- Auth flow → User model: persists · Auth logic reads and updates user records
- Dashboard agg → Income model: reads · Aggregates income records
- Dashboard agg → Expense model: reads · Aggregates expense records
- Income CRUD → Income model: persists · Income controller reads and writes income records
- Expense CRUD → Expense model: persists · Expense controller reads and writes expense records
- User model → MongoDB: stored in · User data is persisted in MongoDB via Mongoose
- Income model → MongoDB: stored in · Income data is persisted in MongoDB via Mongoose
- Expense model → MongoDB: stored in · Expense data is persisted in MongoDB via Mongoose
- UI blocks → Dashboard agg: shows · Dashboard charts render aggregated summaries
- UI blocks → Income CRUD: manages · Income screens drive create/delete workflows
- UI blocks → Expense CRUD: manages · Expense screens drive create/delete workflows