# sgonzalezlopez/timetrack architecture

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

- Interactive diagram: https://gitdiagram.com/sgonzalezlopez/timetrack
- Repository: https://github.com/sgonzalezlopez/timetrack

## Overview

This is a speed-skating club and competition management application: users manage skaters, clubs, competitions, training sessions, and race-time registries, with registry data supporting records and statistics. The visible runtime starts in `app.js`, mounts API and web routes, and initializes the application. API route modules dispatch to domain controllers, which operate on Mongoose models; selected controllers also apply role-based data filters. The tree shows management and private views and chart code, but the excerpts do not establish how their screens obtain data. Edges reflect shown source or SOURCE INDEX references; unsampled UI wiring is intentionally omitted.

Main entry points: [`api/routes.js`](https://github.com/sgonzalezlopez/timetrack/blob/main/api/routes.js) (API router), [`controllers/registry.controller.js`](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/registry.controller.js) (Race registries), [`controllers/trainingsession.controller.js`](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/trainingsession.controller.js) (Training sessions), [`controllers/track.controller.js`](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/track.controller.js) (Track management)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Application routes"]
  node_app["Application setup<br/>[app.js]"]
  node_api["API router<br/>[routes.js]"]
  node_category_route["Category API<br/>[category.route.js]"]
  node_club_route["Club API<br/>[club.route.js]"]
  node_coach_route["Coach API<br/>[coach.route.js]"]
  node_competition_route["Competition API"]
  node_registry_route["Registry API<br/>[registry.route.js]"]
  node_skater_route["Skater API<br/>[skater.route.js]"]
  node_track_route["Track API<br/>[track.route.js]"]
  node_training_route["Training API"]
end

subgraph group_domain["Skating operations"]
  node_category_ctrl["Category management"]
  node_club_ctrl["Club management<br/>[club.controller.js]"]
  node_coach_ctrl["Coach management"]
  node_competition_ctrl["Competition management"]
  node_registry_ctrl["Race registries"]
  node_skater_ctrl["Skater management"]
  node_track_ctrl["Track management"]
  node_training_ctrl["Training sessions"]
  node_filter["Role-based filtering<br/>[data.filter.js]"]
  node_geocoder["Geocoding helper<br/>[geocoder.js]"]
end

subgraph group_data["Domain data"]
  node_category_model[("Category records<br/>[category.model.js]")]
  node_club_model[("Club records<br/>[club.model.js]")]
  node_coach_model[("Coach records<br/>[coach.model.js]")]
  node_competition_model[("Competition records")]
  node_registry_model[("Race records<br/>[registry.model.js]")]
  node_skater_model[("Skater records<br/>[skater.model.js]")]
  node_track_model[("Track records<br/>[track.model.js]")]
  node_training_model[("Training records")]
end

subgraph group_web["Web interface"]
  node_web_routes["Web router<br/>[routes.js]"]
  node_management_route["Management pages"]
  node_private_route["Private pages<br/>[private.route.js]"]
  node_management_views["Management screens"]
  node_private_views["Private screens"]
end

node_user(("User"))

node_user -->|"uses"| node_app
node_app -->|"mounts"| node_api
node_app -->|"mounts"| node_web_routes
node_api -->|"routes to"| node_category_route
node_api -->|"routes to"| node_club_route
node_api -->|"routes to"| node_coach_route
node_api -->|"routes to"| node_competition_route
node_api -->|"routes to"| node_registry_route
node_api -->|"routes to"| node_skater_route
node_api -->|"routes to"| node_track_route
node_api -->|"routes to"| node_training_route
node_category_route -->|"dispatches"| node_category_ctrl
node_club_route -->|"dispatches"| node_club_ctrl
node_coach_route -->|"dispatches"| node_coach_ctrl
node_competition_route -->|"dispatches"| node_competition_ctrl
node_registry_route -->|"dispatches"| node_registry_ctrl
node_skater_route -->|"dispatches"| node_skater_ctrl
node_track_route -->|"dispatches"| node_track_ctrl
node_training_route -->|"dispatches"| node_training_ctrl
node_category_ctrl -->|"reads and writes"| node_category_model
node_club_ctrl -->|"reads and writes"| node_club_model
node_coach_ctrl -->|"reads and writes"| node_coach_model
node_competition_ctrl -->|"reads and writes"| node_competition_model
node_registry_ctrl -->|"queries and updates"| node_registry_model
node_skater_ctrl -->|"reads and writes"| node_skater_model
node_track_ctrl -->|"reads and writes"| node_track_model
node_training_ctrl -->|"reads and writes"| node_training_model
node_club_ctrl -->|"applies"| node_filter
node_competition_ctrl -->|"applies"| node_filter
node_registry_ctrl -->|"applies"| node_filter
node_skater_ctrl -->|"applies"| node_filter
node_training_ctrl -->|"applies"| node_filter
node_track_ctrl -->|"geocodes location"| node_geocoder
node_track_ctrl -->|"queries competitions"| node_competition_model
node_track_ctrl -->|"delegates registry query"| node_registry_ctrl
node_competition_ctrl -->|"delegates registry actions"| node_registry_ctrl
node_skater_ctrl -->|"delegates registry actions"| node_registry_ctrl
node_training_ctrl -->|"looks up registries"| node_registry_model
node_training_ctrl -->|"delegates registry actions"| node_registry_ctrl
node_training_ctrl -->|"loads skater"| node_skater_model
node_web_routes -->|"routes to"| node_management_route
node_web_routes -->|"routes to"| node_private_route

click node_app "https://github.com/sgonzalezlopez/timetrack/blob/main/app.js"
click node_api "https://github.com/sgonzalezlopez/timetrack/blob/main/api/routes.js"
click node_category_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/category.route.js"
click node_club_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/club.route.js"
click node_coach_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/coach.route.js"
click node_competition_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/competition.route.js"
click node_registry_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/registry.route.js"
click node_skater_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/skater.route.js"
click node_track_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/track.route.js"
click node_training_route "https://github.com/sgonzalezlopez/timetrack/blob/main/api/trainingsession.route.js"
click node_category_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/category.controller.js"
click node_club_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/club.controller.js"
click node_coach_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/coach.controller.js"
click node_competition_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/competition.controller.js"
click node_registry_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/registry.controller.js"
click node_skater_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/skater.controller.js"
click node_track_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/track.controller.js"
click node_training_ctrl "https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/trainingsession.controller.js"
click node_filter "https://github.com/sgonzalezlopez/timetrack/blob/main/middlewares/data.filter.js"
click node_geocoder "https://github.com/sgonzalezlopez/timetrack/blob/main/utils/geocoder.js"
click node_category_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/category.model.js"
click node_club_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/club.model.js"
click node_coach_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/coach.model.js"
click node_competition_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/competition.model.js"
click node_registry_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/registry.model.js"
click node_skater_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/skater.model.js"
click node_track_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/track.model.js"
click node_training_model "https://github.com/sgonzalezlopez/timetrack/blob/main/models/trainingsession.model.js"
click node_web_routes "https://github.com/sgonzalezlopez/timetrack/blob/main/views-routes/routes.js"
click node_management_route "https://github.com/sgonzalezlopez/timetrack/blob/main/views-routes/management.route.js"
click node_private_route "https://github.com/sgonzalezlopez/timetrack/blob/main/views-routes/private.route.js"
click node_management_views "https://github.com/sgonzalezlopez/timetrack/tree/main/views/management"
click node_private_views "https://github.com/sgonzalezlopez/timetrack/tree/main/views/private"

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_app,node_api,node_category_route,node_club_route,node_coach_route,node_competition_route,node_registry_route,node_skater_route,node_track_route,node_training_route,node_user toneBlue
class node_category_ctrl,node_club_ctrl,node_coach_ctrl,node_competition_ctrl,node_registry_ctrl,node_skater_ctrl,node_track_ctrl,node_training_ctrl,node_filter,node_geocoder toneAmber
class node_category_model,node_club_model,node_coach_model,node_competition_model,node_registry_model,node_skater_model,node_track_model,node_training_model toneMint
class node_web_routes,node_management_route,node_private_route,node_management_views,node_private_views toneRose
```

## Components

### Application routes

- [Application setup](https://github.com/sgonzalezlopez/timetrack/blob/main/app.js): `app.js`
- [API router](https://github.com/sgonzalezlopez/timetrack/blob/main/api/routes.js): `api/routes.js`
- [Category API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/category.route.js): `api/category.route.js`
- [Club API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/club.route.js): `api/club.route.js`
- [Coach API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/coach.route.js): `api/coach.route.js`
- [Competition API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/competition.route.js): `api/competition.route.js`
- [Registry API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/registry.route.js): `api/registry.route.js`
- [Skater API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/skater.route.js): `api/skater.route.js`
- [Track API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/track.route.js): `api/track.route.js`
- [Training API](https://github.com/sgonzalezlopez/timetrack/blob/main/api/trainingsession.route.js): `api/trainingsession.route.js`

### Skating operations

- [Category management](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/category.controller.js): `controllers/category.controller.js`
- [Club management](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/club.controller.js): `controllers/club.controller.js`
- [Coach management](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/coach.controller.js): `controllers/coach.controller.js`
- [Competition management](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/competition.controller.js): `controllers/competition.controller.js`
- [Race registries](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/registry.controller.js): `controllers/registry.controller.js`
- [Skater management](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/skater.controller.js): `controllers/skater.controller.js`
- [Track management](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/track.controller.js): `controllers/track.controller.js`
- [Training sessions](https://github.com/sgonzalezlopez/timetrack/blob/main/controllers/trainingsession.controller.js): `controllers/trainingsession.controller.js`
- [Role-based filtering](https://github.com/sgonzalezlopez/timetrack/blob/main/middlewares/data.filter.js): `middlewares/data.filter.js`
- [Geocoding helper](https://github.com/sgonzalezlopez/timetrack/blob/main/utils/geocoder.js): `utils/geocoder.js`

### Domain data

- [Category records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/category.model.js): `models/category.model.js`
- [Club records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/club.model.js): `models/club.model.js`
- [Coach records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/coach.model.js): `models/coach.model.js`
- [Competition records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/competition.model.js): `models/competition.model.js`
- [Race records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/registry.model.js): `models/registry.model.js`
- [Skater records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/skater.model.js): `models/skater.model.js`
- [Track records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/track.model.js): `models/track.model.js`
- [Training records](https://github.com/sgonzalezlopez/timetrack/blob/main/models/trainingsession.model.js): `models/trainingsession.model.js`

### Web interface

- [Web router](https://github.com/sgonzalezlopez/timetrack/blob/main/views-routes/routes.js): `views-routes/routes.js`
- [Management pages](https://github.com/sgonzalezlopez/timetrack/blob/main/views-routes/management.route.js): `views-routes/management.route.js`
- [Private pages](https://github.com/sgonzalezlopez/timetrack/blob/main/views-routes/private.route.js): `views-routes/private.route.js`
- [Management screens](https://github.com/sgonzalezlopez/timetrack/tree/main/views/management): `views/management`
- [Private screens](https://github.com/sgonzalezlopez/timetrack/tree/main/views/private): `views/private`

### Other components

- **User**

## Connections

- User → Application setup: uses (evidence: `app.js`)
- Application setup → API router: mounts (evidence: `app.js`)
- Application setup → Web router: mounts (evidence: `app.js`)
- API router → Category API: routes to (evidence: `api/routes.js`)
- API router → Club API: routes to (evidence: `api/routes.js`)
- API router → Coach API: routes to (evidence: `api/routes.js`)
- API router → Competition API: routes to (evidence: `api/routes.js`)
- API router → Registry API: routes to (evidence: `api/routes.js`)
- API router → Skater API: routes to (evidence: `api/routes.js`)
- API router → Track API: routes to (evidence: `api/routes.js`)
- API router → Training API: routes to (evidence: `api/routes.js`)
- Category API → Category management: dispatches (evidence: `api/category.route.js`)
- Club API → Club management: dispatches (evidence: `api/club.route.js`)
- Coach API → Coach management: dispatches (evidence: `api/coach.route.js`)
- Competition API → Competition management: dispatches (evidence: `api/competition.route.js`)
- Registry API → Race registries: dispatches (evidence: `api/registry.route.js`)
- Skater API → Skater management: dispatches (evidence: `api/skater.route.js`)
- Track API → Track management: dispatches (evidence: `api/track.route.js`)
- Training API → Training sessions: dispatches (evidence: `api/trainingsession.route.js`)
- Category management → Category records: reads and writes (evidence: `controllers/category.controller.js`)
- Club management → Club records: reads and writes (evidence: `controllers/club.controller.js`)
- Coach management → Coach records: reads and writes (evidence: `controllers/coach.controller.js`)
- Competition management → Competition records: reads and writes (evidence: `controllers/competition.controller.js`)
- Race registries → Race records: queries and updates (evidence: `controllers/registry.controller.js`)
- Skater management → Skater records: reads and writes (evidence: `controllers/skater.controller.js`)
- Track management → Track records: reads and writes (evidence: `controllers/track.controller.js`)
- Training sessions → Training records: reads and writes (evidence: `controllers/trainingsession.controller.js`)
- Club management → Role-based filtering: applies (evidence: `controllers/club.controller.js`)
- Competition management → Role-based filtering: applies (evidence: `controllers/competition.controller.js`)
- Race registries → Role-based filtering: applies (evidence: `controllers/registry.controller.js`)
- Skater management → Role-based filtering: applies (evidence: `controllers/skater.controller.js`)
- Training sessions → Role-based filtering: applies (evidence: `controllers/trainingsession.controller.js`)
- Track management → Geocoding helper: geocodes location (evidence: `controllers/track.controller.js`)
- Track management → Competition records: queries competitions (evidence: `controllers/track.controller.js`)
- Track management → Race registries: delegates registry query (evidence: `controllers/track.controller.js`)
- Competition management → Race registries: delegates registry actions (evidence: `controllers/competition.controller.js`)
- Skater management → Race registries: delegates registry actions (evidence: `controllers/skater.controller.js`)
- Training sessions → Race records: looks up registries (evidence: `controllers/trainingsession.controller.js`)
- Training sessions → Race registries: delegates registry actions (evidence: `controllers/trainingsession.controller.js`)
- Training sessions → Skater records: loads skater (evidence: `controllers/trainingsession.controller.js`)
- Web router → Management pages: routes to (evidence: `views-routes/routes.js`)
- Web router → Private pages: routes to (evidence: `views-routes/routes.js`)
