Full-stack Gym Management web application for admins, staff and members.
FitZone is a gym management system built to help gym owners and staff manage members, subscriptions, payments, attendance and analytics. It provides an admin dashboard with quick stats, revenue tracking, member lifecycle views and growth metrics.
The codebase is split into a Frontend (React) and a Backend (Node.js + Express). Data is persisted in MongoDB.
- Member management (create, update, delete, search)
- Membership plans and expiry tracking
- Payment and revenue reporting
- Dashboard stats (active members, new signups, churn)
- Notifications for expiring memberships
- Charts and visualizations for member growth and revenue
- Role-based access (admin / staff)
- Frontend: React (component-based, responsive UI)
- Backend: Node.js + Express
- Database: MongoDB (Mongoose ODM)
- Auth: JWT-based authentication
- Styling: Tailwind / CSS (adjust if different)
- Dev tools: nodemon, dotenv
- MVC-like separation: routes → controllers → services → models
- asyncHandler pattern is used across controllers for async error handling.
- Centralized error handler middleware for consistent API error responses.
- Clear endpoints segmentation for statistics and reporting.
- Node.js (v18+ recommended)
- npm or yarn
- MongoDB (local or Atlas)
- Git
Create a .env in the backend root with at least the following:
PORT=5000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=supersecretjwtkey
NODE_ENV=development
Add any third-party keys you use (email provider, payment gateway) as required.
cd backendnpm install- Add
.env(see above) npm run dev(ornodemon server.js)
The backend should start on http://localhost:5000 (or the port in your .env).
cd frontendnpm install- Create frontend
.envif required (e.g.VITE_API_BASE_URL=http://localhost:5000) npm start
Open http://localhost:3000 to view the app.
These are the major reporting/stat endpoints used by the dashboard. Adjust paths if your router prefixes differ.
POST /api/auth/login— login with{ email, password }➜ returns tokenPOST /api/members— create memberGET /api/members— list members (supports pagination & search)GET /api/members/:id— member detailsPUT /api/members/:id— update memberDELETE /api/members/:id— delete member
-
GET /api/stats— general dashboard statistics (active members, total revenue, new signups, etc.)- Example response:
{ activeMembers: 800, newSignups: 50, totalRevenue: 120000, burnRate: 15000 }
- Example response:
-
GET /api/revenue— revenue reporting for a date range or by month. Accepts query?from=YYYY-MM-DD&to=YYYY-MM-DDor?period=monthly.- Example response:
[{ month: '2025-10', revenue: 50000 }, ...]
- Example response:
-
GET /api/recent-members— lists recently joined members (supportslimit)- Example response:
[{ id, name, joinedAt, plan }, ...]
- Example response:
-
GET /api/expiring-members— lists members with memberships expiring soon. Supportsdays=30query.- Example response:
[{ id, name, expiryDate, daysLeft }, ...]
- Example response:
-
GET /api/member-growth— returns growth metrics for charting (daily/weekly/monthly)- Example response:
[{ date: '2025-10-01', newMembers: 5, cumulative: 420 }, ...]
- Example response:
- All routes use JSON responses and consistent HTTP status codes.
- Use
Authorization: Bearer <token>header for protected routes. - Controllers should follow the
asyncHandlerwrapper and delegate to service layer for business logic.
- Models:
User,Member,Plan,Payment,Attendance,Notification - Add a
seedscript to populate demo data (admin user, sample plans, sample members).
Example seed command in package.json:
"scripts": {
"seed": "node seeder.js"
}-
Use Jest or your preferred test runner for unit tests.
-
Test strategy:
- Unit test services and utilities
- Integration tests for critical endpoints (auth, member creation, revenue calculations)
- Build frontend (
npm run build) and serve via static hosting (Netlify, Vercel) or behind a CDN. - Deploy backend to a Node host (Heroku, Render, DigitalOcean App Platform, or VPS) and connect to MongoDB Atlas.
- Ensure environment variables are set in your hosting provider and that CORS is configured for the frontend origin.
- Use feature branches:
feat/<short-desc>orfix/<short-desc>. - Follow the
asyncHandlerpattern and centralized error handler for all new controllers. - Keep controllers thin — move business logic to services.
- Write tests for any non-trivial logic and add short PR descriptions.
- If revenue numbers look wrong, check timezone handling and date normalization when aggregating payments.
- For cash payments (rent, offline payments) add an offline payment record in
paymentswithmethod: 'cash'so metrics include them. - Use consistent date formats (ISO
YYYY-MM-DD/ ISO timestamps) across frontend and backend.
Osman Bin Nasir Abdul Razzaq