Skip to content

zephir-x/gymcore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GymCore - E2E Fitness SaaS Platform

.NET C# React TypeScript PostgreSQL Docker Stripe Architecture

A comprehensive, highly-concurrent SaaS platform built for boutique fitness clubs. Engineered from the ground up using .NET 9, React + TypeScript, and PostgreSQL. Designed with Clean Architecture principles, enforcing a strict separation of concerns and robust transactional safety.


GymCore Hero Demo

πŸ“– Table of Contents

  1. Project Overview & Live Demo
  2. Key Business Features
  3. Architectural Marvels (Tech Deep Dive)
  4. Technology Stack
  5. Project Structure
  6. Getting Started (Local Deployment)
  7. Test Scenarios
  8. Deployment & Infrastructure
  9. Error Handling and Diagnostics

1. Project Overview & Live Demo

GymCore serves as a full-fledged ecosystem bridging the gap between club members, personal trainers, and facility administrators. It seamlessly handles subscription life-cycles, strict facility access, dynamic pricing, and concurrent booking engines.

Production Environment: Fully containerized and deployed on a VPS via Nginx Reverse Proxy.

πŸš€ Live Demo: gymcore.com.pl

To quickly log in and test it, here's an example login:

For obvious reasons, I won't include the admin login details :)


2. Key Business Features

πŸ“± Mobile-First Experience

The project was built with a Mobile-First philosophy in mind. The interface seamlessly adapts to smartphone screens, providing a native experience without the need to install a dedicated app.

  • Adaptive Navigation: The desktop sidebar automatically transforms into an intuitive bottom navigation bar.
  • Touch-Friendly UX: Components and forms optimized for thumb navigation.
  • Compact Views: Intelligently displays only key data on small screens.

πŸ’³ Stripe-Powered Subscriptions

Stripe Checkout Flow

Memberships are managed by an advanced state machine. Integration with the Stripe API enables secure, asynchronous payments.

  • Dynamic States: Real-time status monitoring (Active, Expiring, Grace Period).
  • Asynchronous Billing: Full transaction processing via secure webhooks.
  • Discount Engine: Backend discount calculation before payment is finalized.

πŸ“… High-Concurrency Booking Engine

Booking Engine UI

The reservation system handles high traffic volumes and concurrent requests, ensuring smooth operation during peak hours.

  • Concurrency Control: Database-level locks eliminate overbooking.
  • Real-time Capacity: Instant updates of available spots in group sessions.
  • Flexible Logic: Supports group classes and individual one-on-one sessions with trainers.

πŸ€– AI Assistant & Google Maps

Google Maps and AI Admin Dashboard

Advanced tools optimize navigation and management processes within the club.

  • Google Maps API: Quick club location and routing for new members.
  • DeepSeek AI Support: Intelligent analytics on occupancy and revenue in real time.
  • Management Guidance: Proactive recommendations for optimizing the activity schedule.

πŸ” Automated Access Control & Dynamic QR Passes

Dynamic QR Entry Pass Flow

GymCore eliminates the need for physical membership cards.

  • Encrypted QR Codes: Unique, time-based codes generated from JWT tokens.
  • Instant Verification: Verify entry credentials at the reception desk in a fraction of a second.
  • Anti-Fraud: Single-use tokens eliminate the risk of unauthorized access sharing.


3. Architectural Marvels (Tech Deep Dive)

This project was built to demonstrate enterprise-grade patterns and solve complex backend challenges:

  • Clean Architecture & CQRS: The .NET backend utilizes the MediatR library to enforce the Command Query Responsibility Segregation pattern. This separates read operations from state-mutating commands, allowing for targeted optimization and strict input validation via FluentValidation pipelines.
    πŸ‘‰ View CQRS Handler implementation
  • Optimistic Concurrency Control: Implemented EF Core's RowVersion handling. If two users attempt to book the last spot in a class simultaneously, the database rejects the conflicting transaction, ensuring capacity integrity.
  • Background Hosted Services (Workers): - ScheduleGeneratorWorker: Autonomously generates upcoming class schedules and trainer slots on a rolling window without freezing the main API thread. Optimized for specific weekday triggers.
    πŸ‘‰ View Background Worker logic
  • GuardWorker: Monitors and updates expired subscription statuses autonomously.
  • Stripe Webhooks: Asynchronous payment fulfillment. The API listens to cryptographically signed Stripe webhooks to definitively activate user subscriptions only when the bank clears the transaction.
    πŸ‘‰ View Webhook endpoint implementation
  • Custom React Hooks: Implementation of highly reusable hooks like useDocumentTitle to dynamically modify the SPA's metadata state during client-side routing.
    πŸ‘‰ View Custom Hook code

πŸ“Š Database Schema (ERD)

The following diagram shows a relational database structure (3NF) that ensures transactional consistency for subscriptions, users, and the reservation system:

Database ERD

Key Relationships:

  • 1:N: User <-> Reservations (cascading deletes used).
  • M:N: Roles <-> Permissions (secured by associative tables).
  • Concurrency: Each reservation table has a RowVersion column to support optimistic locking (Optimistic Concurrency).

4. Technology Stack

Layer Technologies & Tools
Backend .NET 9, C# 13, ASP.NET Core Web API, MediatR, FluentValidation
Frontend React 18, TypeScript, Vite, TailwindCSS, React Query, Axios
Database PostgreSQL 16, Entity Framework Core (Code-First)
Infrastructure Docker, Docker Compose, Nginx (Reverse Proxy & Static Server)
Integrations Stripe API (Payments & Webhooks), DeepSeek API (AI Analytics)
Security Custom BCrypt Hashing, JWT Bearer Authentication

5. Project Structure

The repository is divided into two highly decoupled environments.

Click to expand the Architecture Tree
gymcore/
β”œβ”€β”€ backend/                             # .NET 9 Backend
β”‚   β”œβ”€β”€ GymCore.Api/                     # Presentation Layer (Controllers, Middlewares, Workers)
β”‚   β”œβ”€β”€ GymCore.Application/             # Business Logic (CQRS Handlers, Validation, Interfaces)
β”‚   β”œβ”€β”€ GymCore.Domain/                  # Core Entities, Enums, Exceptions
β”‚   β”œβ”€β”€ GymCore.Infrastructure/          # DB Context, EF Core Migrations, Identity, External Services
β”‚   └── Dockerfile                       # Multi-stage build for the .NET API
β”œβ”€β”€ frontend/                            # Vite + React Client
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/                  # Reusable UI components
β”‚   β”‚   β”œβ”€β”€ context/                     # Global state management
β”‚   β”‚   β”œβ”€β”€ hooks/                       # Custom React Hooks (e.g., useDocumentTitle)
β”‚   β”‚   β”œβ”€β”€ lib/                         # Utility functions
β”‚   β”‚   β”œβ”€β”€ pages/                       # Route views
β”‚   β”‚   β”œβ”€β”€ App.tsx                      # Root component
β”‚   β”‚   β”œβ”€β”€ main.tsx                     # Entry point
β”‚   β”‚   └── index.css                    # Global styles
β”‚   β”œβ”€β”€ Dockerfile                       # Multi-stage build (Node builder -> Nginx server)
β”‚   └── nginx.conf                       # Client-side routing configuration for SPA
└── docker-compose.yml                   # E2E orchestration (DB, API, Frontend Proxy)

6. Getting Started (Local Deployment)

Run the entire E2E ecosystem locally using Docker Desktop.

Prerequisites

  • Docker & Docker Compose
  • Node.js (Optional, for running frontend outside of Docker)

Installation Steps

  1. Clone the repository:
    git clone https://github.com/zephir-x/gymcore.git
    cd gymcore
  2. Configure Environment Variables:
    Create a .env file in the root directory. Use the provided .env.example template.
    cp .env.example .env
  3. Build and Spin Up Containers:
    docker compose up -d --build
  4. Access the application via http://localhost:5173

7. Test Scenarios

To quickly evaluate the system, use the following pre-seeded credentials:

Role Email Password Access Level
Administrator admin@gmail.com Admin123! Full CRUD, Analytics, Broadcasts
Member member1@gmail.com Member123! Store, Bookings, Subscriptions
Coach mariusz@gmail.com Coach123! Class Attendees, Calendar

Workflow to test:

  1. Log in as a Member: Navigate to the Subscriptions tab and purchase a tier using the Stripe test card (4242 4242 4242 4242).

  2. Webhook Fulfillment: Return to the app. Observe that your account status changes to Active via the Stripe Webhook fulfillment mechanism.

  3. Booking Engine: Navigate to Schedule and book a class. Verify that the current attendee count increments correctly.

  4. Administrative Oversight: Log out, and log in as the Administrator. Cancel the class you just booked. Navigate back to the Member view to confirm the cancellation is reflected dynamically.


8. Deployment & Infrastructure

The application is deployed as a multi-container solution managed by a Master Nginx Reverse Proxy, allowing for side-by-side hosting of multiple projects (like GymCore and GameNest) on a single VPS.

Production Architecture Diagram

graph TD
  Client([πŸ‘€ Client Browser]) -->|HTTPS / Port 443| CF[☁️ Cloudflare]
  CF -->|Proxy| MasterNginx[βš™οΈ Master Nginx Proxy]
  
  subgraph Docker web-proxy Network
    MasterNginx -->|Routing| GymFrontend[βš›οΈ React Frontend Container]
    MasterNginx -->|Routing /api/*| GymApi[πŸ”Œ .NET 9 API Container]
  end

  GymFrontend -.->|Axios calls| GymApi
  GymApi -->|EF Core| DB[(🐘 PostgreSQL 16)]
  
  Stripe([πŸ’³ Stripe Service]) -.->|Async Webhooks| GymApi
Loading
  • Nginx Proxy: Handles SSL/TLS termination and routes traffic to the appropriate containers based on server names.
  • Internal Networking: All projects reside within a shared web-proxy bridge network.
  • Persistence: Docker volumes ensure database data is preserved across container restarts.

9. Error Handling and Diagnostics

  • Global Exception Handling: The API utilizes a standardized ProblemDetails response format for all unhandled exceptions, ensuring clear API communication.
  • Logging: Application logs are captured via Docker and can be inspected using docker compose logs -f <service_name>.

Architected and developed by Kacper Gumulak - zephir-x.

About

GymCore - Modular Monolith Fitness Ecosystem (.NET Core & React).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages