# mariokehl/gymportal-io architecture

> Architecture diagram of the GitHub repository mariokehl/gymportal-io, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/mariokehl/gymportal-io
- Repository: https://github.com/mariokehl/gymportal-io

## Overview

gymportal.io is a gym-management application for staff and members. Staff use the web interface to manage organizations, members, memberships, access, and finances; members use the PWA for account and check-in functions. Public gym widgets support registration and payment, with Mollie handling payment processing. The graph retains these major product branches and the central service/model layer. Wiring is inferred only where supported by sampled code or the repository structure; unsampled subsystem links are intentionally limited.

Main entry points: [`app/Http/Controllers/Web/MemberController.php`](https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Web/MemberController.php) (Member management), [`app/Http/Controllers/Api/WidgetController.php`](https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Api/WidgetController.php) (Gym registration widget), [`app/Models/Member.php`](https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Member.php) (Member records), [`app/Http/Controllers/Web`](https://github.com/mariokehl/gymportal-io/tree/develop/app/Http/Controllers/Web) (Web controllers)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Gym administration"]
  node_webui["Admin interface"]
  node_webcontrollers["Web controllers"]
  node_plans[("Plans and add-ons<br/>[MembershipPlan.php]")]
end

subgraph group_member["Member lifecycle"]
  node_members[("Member records<br/>[Member.php]")]
  node_membercontroller["Member management"]
  node_membershipservice["Membership services"]
  node_contracts["Contract handling"]
  node_mail["Member email"]
  node_gymdata[("Gym and member data<br/>[Gym.php]")]
end

subgraph group_payments["Payments and billing"]
  node_paymentscontroller["Payment workflows"]
  node_paymentservice["Payment services<br/>[PaymentService.php]"]
  node_paymentrecords[("Payment records<br/>[Payment.php]")]
  node_webhook["Payment webhook"]
end

subgraph group_access["Access and check-in"]
  node_pwa["Member PWA API"]
  node_checkin["Check-in services"]
  node_checkinrecords[("Check-in records<br/>[CheckIn.php]")]
end

subgraph group_integrations["External integrations"]
  node_mollie["Mollie API"]
  node_widget["Gym registration widget"]
  node_widgetviews["Widget experience<br/>[form.blade.php]"]
  node_google["Google Sheets"]
  node_syncjob["Check-in sync job"]
end

node_staff(("Gym staff"))
node_pwauser(("Gym members"))
node_widgetuser(("Widget visitor"))

node_staff -->|"uses"| node_webui
node_webui -->|"requests"| node_webcontrollers
node_webcontrollers -->|"dispatches"| node_membercontroller
node_membercontroller -->|"reads and writes"| node_members
node_membercontroller -->|"manages memberships"| node_membershipservice
node_membershipservice -->|"uses plans"| node_plans
node_membershipservice -->|"updates membership"| node_members
node_membercontroller -->|"handles contracts"| node_contracts
node_contracts -->|"dispatches mail"| node_mail
node_webcontrollers -->|"dispatches"| node_paymentscontroller
node_paymentscontroller -->|"processes payments"| node_paymentservice
node_paymentservice -->|"creates and updates"| node_paymentrecords
node_paymentservice -->|"requests payments"| node_mollie
node_mollie -->|"sends status events"| node_webhook
node_webhook -->|"updates status"| node_paymentrecords
node_webhook -->|"updates member status"| node_members
node_pwauser -->|"authenticates and checks in"| node_pwa
node_pwa -->|"authenticates member"| node_members
node_pwa -->|"records check-in"| node_checkin
node_checkin -->|"writes check-in"| node_checkinrecords
node_widgetuser -->|"uses"| node_widgetviews
node_widgetviews -->|"submits registration"| node_widget
node_widget -->|"validates gym"| node_gymdata
node_widget -->|"lists plans"| node_plans
node_widget -->|"initiates payment"| node_mollie
node_syncjob -.->|"syncs check-ins"| node_google
node_syncjob -->|"reads check-ins"| node_checkinrecords

click node_webui "https://github.com/mariokehl/gymportal-io/tree/develop/resources/js/Pages"
click node_webcontrollers "https://github.com/mariokehl/gymportal-io/tree/develop/app/Http/Controllers/Web"
click node_plans "https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/MembershipPlan.php"
click node_members "https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Member.php"
click node_membercontroller "https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Web/MemberController.php"
click node_membershipservice "https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/MembershipService.php"
click node_contracts "https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/ContractService.php"
click node_mail "https://github.com/mariokehl/gymportal-io/blob/develop/app/Mail/Dispatching/MemberMailDispatcher.php"
click node_paymentscontroller "https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Web/PaymentController.php"
click node_paymentservice "https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/PaymentService.php"
click node_paymentrecords "https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Payment.php"
click node_webhook "https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Api/V1/Public/MollieWebhookController.php"
click node_pwa "https://github.com/mariokehl/gymportal-io/tree/develop/app/Http/Controllers/Pwa"
click node_checkin "https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/StationCheckInService.php"
click node_checkinrecords "https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/CheckIn.php"
click node_widget "https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Api/WidgetController.php"
click node_widgetviews "https://github.com/mariokehl/gymportal-io/blob/develop/resources/views/widget/form.blade.php"
click node_gymdata "https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Gym.php"
click node_syncjob "https://github.com/mariokehl/gymportal-io/blob/develop/app/Jobs/SyncCheckInsToGoogleSheet.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_webui,node_webcontrollers,node_plans toneBlue
class node_members,node_membercontroller,node_membershipservice,node_contracts,node_mail,node_gymdata toneAmber
class node_paymentscontroller,node_paymentservice,node_paymentrecords,node_webhook toneMint
class node_pwa,node_checkin,node_checkinrecords toneRose
class node_mollie,node_widget,node_widgetviews,node_google,node_syncjob,node_staff,node_pwauser,node_widgetuser toneIndigo
```

## Components

### Gym administration

- [Admin interface](https://github.com/mariokehl/gymportal-io/tree/develop/resources/js/Pages): `resources/js/Pages`
- [Web controllers](https://github.com/mariokehl/gymportal-io/tree/develop/app/Http/Controllers/Web): `app/Http/Controllers/Web`
- [Plans and add-ons](https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/MembershipPlan.php): `app/Models/MembershipPlan.php`

### Member lifecycle

- [Member records](https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Member.php): `app/Models/Member.php`
- [Member management](https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Web/MemberController.php): `app/Http/Controllers/Web/MemberController.php`
- [Membership services](https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/MembershipService.php): `app/Services/MembershipService.php`
- [Contract handling](https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/ContractService.php): `app/Services/ContractService.php`
- [Member email](https://github.com/mariokehl/gymportal-io/blob/develop/app/Mail/Dispatching/MemberMailDispatcher.php): `app/Mail/Dispatching/MemberMailDispatcher.php`
- [Gym and member data](https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Gym.php): `app/Models/Gym.php`

### Payments and billing

- [Payment workflows](https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Web/PaymentController.php): `app/Http/Controllers/Web/PaymentController.php`
- [Payment services](https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/PaymentService.php): `app/Services/PaymentService.php`
- [Payment records](https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/Payment.php): `app/Models/Payment.php`
- [Payment webhook](https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Api/V1/Public/MollieWebhookController.php): `app/Http/Controllers/Api/V1/Public/MollieWebhookController.php`

### Access and check-in

- [Member PWA API](https://github.com/mariokehl/gymportal-io/tree/develop/app/Http/Controllers/Pwa): `app/Http/Controllers/Pwa`
- [Check-in services](https://github.com/mariokehl/gymportal-io/blob/develop/app/Services/StationCheckInService.php): `app/Services/StationCheckInService.php`
- [Check-in records](https://github.com/mariokehl/gymportal-io/blob/develop/app/Models/CheckIn.php): `app/Models/CheckIn.php`

### External integrations

- **Mollie API**
- [Gym registration widget](https://github.com/mariokehl/gymportal-io/blob/develop/app/Http/Controllers/Api/WidgetController.php): `app/Http/Controllers/Api/WidgetController.php`
- [Widget experience](https://github.com/mariokehl/gymportal-io/blob/develop/resources/views/widget/form.blade.php): `resources/views/widget/form.blade.php`
- **Google Sheets**
- [Check-in sync job](https://github.com/mariokehl/gymportal-io/blob/develop/app/Jobs/SyncCheckInsToGoogleSheet.php): `app/Jobs/SyncCheckInsToGoogleSheet.php`

### Other components

- **Gym staff**
- **Gym members**
- **Widget visitor**

## Connections

- Gym staff → Admin interface: uses
- Admin interface → Web controllers: requests
- Web controllers → Member management: dispatches
- Member management → Member records: reads and writes
- Member management → Membership services: manages memberships
- Membership services → Plans and add-ons: uses plans
- Membership services → Member records: updates membership
- Member management → Contract handling: handles contracts
- Contract handling → Member email: dispatches mail
- Web controllers → Payment workflows: dispatches
- Payment workflows → Payment services: processes payments
- Payment services → Payment records: creates and updates
- Payment services → Mollie API: requests payments
- Mollie API → Payment webhook: sends status events
- Payment webhook → Payment records: updates status
- Payment webhook → Member records: updates member status
- Gym members → Member PWA API: authenticates and checks in
- Member PWA API → Member records: authenticates member
- Member PWA API → Check-in services: records check-in
- Check-in services → Check-in records: writes check-in
- Widget visitor → Widget experience: uses
- Widget experience → Gym registration widget: submits registration
- Gym registration widget → Gym and member data: validates gym
- Gym registration widget → Plans and add-ons: lists plans
- Gym registration widget → Mollie API: initiates payment
- Check-in sync job → Google Sheets: syncs check-ins
- Check-in sync job → Check-in records: reads check-ins
