Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

Gym Management System

A full-stack gym management application for member registration, front-desk scanning, staff attendance, payments, and WhatsApp broadcasts.

Stack: NestJS + SQLite (backend) · React + Vite + Tailwind CSS (frontend)

Repository: github.com/mohamedmoamen8/gym_system


Features

Module Description
Dashboard Member counts, today's check-ins, 7-day visit chart, revenue totals
Front Desk Scanner Scan or type a member barcode to verify access and record check-ins
Register Member Add members with photo, phone, barcode, and membership plan
Members Search, filter, edit, and print member ID cards
Membership Plans Create and manage subscription tiers with pricing and duration
Payments Record payments, track revenue, and view monthly analytics
Staff Manage staff profiles with photos and access codes
Captain Station Staff clock-in / clock-out via access code with today's duty roster
Broadcast Send WhatsApp messages to selected active members via OpenWA

Additional capabilities:

  • JWT authentication with forced password change on first login
  • Configurable gym name and logo (settings)
  • Automatic membership expiry (hourly background job)
  • Member status: Active, Suspended, Expired

Project Structure

gym-management-system/
├── backend/          NestJS API — port 3000
│   ├── src/
│   │   ├── auth/         Login, JWT, owner account
│   │   ├── customers/    Member CRUD and barcode lookup
│   │   ├── checkins/     Visit tracking and analytics
│   │   ├── memberships/  Subscription plans
│   │   ├── payments/     Payment records and revenue
│   │   ├── staff/        Staff profiles and clock logs
│   │   ├── broadcast/    WhatsApp messaging (OpenWA)
│   │   ├── settings/     Gym branding and config
│   │   └── jobs/         Scheduled expiry updates
│   └── storage/photos/   Uploaded member and staff photos
└── frontend/         React + Vite — port 5173
    └── src/components/   UI tabs and pages

Getting Started

Prerequisites

  • Node.js 18+
  • npm

1. Backend

cd backend
npm install
cp .env.example .env   # optional — edit JWT secret and OpenWA settings
npm run start:dev

The API runs at http://localhost:3000/api.
Uploaded photos are served at http://localhost:3000/uploads/photos/<filename>.

On first run, a default owner account is created (see .env.example):

Field Default
Username owner
Password gym1234

Change the password after your first login.

2. Frontend

cd frontend
npm install
npm run dev

Open http://localhost:5173. The Vite dev server proxies /api and /uploads to the backend.


Environment Variables

Copy backend/.env.example to backend/.env:

Variable Description
PORT API port (default 3000)
JWT_SECRET Secret for signing JWT tokens — change in production
OWNER_USERNAME Default owner username seeded on first run
OWNER_PASSWORD Default owner password seeded on first run
OPENWA_URL OpenWA server URL (e.g. http://localhost:2785)
OPENWA_API_KEY API key from the OpenWA dashboard
OPENWA_SESSION OpenWA session name (e.g. gym)

Leave OpenWA variables empty to run broadcasts in mock mode (logs only, no messages sent).


API Reference

All routes are prefixed with /api. Most endpoints require a Authorization: Bearer <token> header.

Auth

Method Route Auth Description
POST /auth/login No Login with username and password
PATCH /auth/change-password Yes Change the logged-in owner's password

Customers (Members)

Method Route Description
POST /customers/register Register a member (multipart, optional photo)
GET /customers List members (?q= search, ?status= filter)
GET /customers/next-barcode Next auto-generated member ID
GET /customers/barcode/:code Lookup by barcode (records check-in)
GET /customers/expiring Members expiring within N days (?days=7)
GET /customers/:id Get member by UUID
PATCH /customers/:id Update member
DELETE /customers/:id Remove member

Check-ins

Method Route Description
POST /checkins Record a check-in { "customerId": "..." }
GET /checkins/today Today's check-in count
GET /checkins/daily Daily counts for last N days (?days=7)
GET /checkins/member/:customerId Check-in history for a member

Membership Plans

Method Route Auth Description
GET /memberships/active No Active plans (used by register form)
GET /memberships Yes All plans
POST /memberships Yes Create plan
PATCH /memberships/:id Yes Update plan
DELETE /memberships/:id Yes Delete plan

Payments

Method Route Description
POST /payments Record a payment
GET /payments List all payments
GET /payments/customer/:customerId Payments for a member
PATCH /payments/:id/status Update payment status
GET /payments/analytics/revenue Total revenue
GET /payments/analytics/monthly Monthly revenue breakdown

Staff

Method Route Auth Description
POST /staff Yes Create staff member (multipart, optional photo)
GET /staff Yes List all staff
GET /staff/logs/today No Today's shift logs
GET /staff/:id Yes Get staff by UUID
PATCH /staff/:id Yes Update staff
DELETE /staff/:id Yes Remove staff
POST /staff/clock-trigger No Clock in/out { "accessCode": "..." }

Broadcast

Method Route Description
POST /broadcast Send message to member UUIDs { "message": "...", "recipientIds": [...] }

Settings

Method Route Description
GET /settings List all settings
GET /settings/:key Get a setting value
POST /settings/:key Set a setting { "value": "..." }

WhatsApp Broadcast (OpenWA)

To send real WhatsApp messages:

  1. Run OpenWA locally (default port 2785)
  2. Create a session in the OpenWA dashboard and scan the QR code
  3. Create an API key under Admin → API Keys
  4. Set OPENWA_URL, OPENWA_API_KEY, and OPENWA_SESSION in backend/.env

Phone numbers should be international digits only (e.g. 201012345678).


Production Notes

  • Database: SQLite (backend/gym.sqlite) works for single-machine deployments. For multi-server setups, switch to PostgreSQL via @nestjs/typeorm.
  • Migrations: Set synchronize: false in app.module.ts and use TypeORM migrations for production.
  • Photos: Stored locally in backend/storage/photos/. Consider S3 or similar for production.
  • Security: Change JWT_SECRET, default owner credentials, and restrict CORS origins in main.ts.
  • Build frontend: cd frontend && npm run build — serve the dist/ folder behind your reverse proxy.

License

Private — UNLICENSED

About

A full-stack gym management application for member registration, front-desk scanning, staff attendance, payments, and WhatsApp broadcasts.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages