# shotcrib77/dulolytics architecture

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

- Interactive diagram: https://gitdiagram.com/shotcrib77/dulolytics
- Repository: https://github.com/shotcrib77/dulolytics

## Overview

DuLOLytics takes two Riot IDs and a region, finds their shared League matches, computes a rough compatibility rating, and presents player profiles, score, and stat ratings with sharing. The graph follows the inspected search-to-results path and includes the documented Riot/Redis-backed data workflow. Other result-rendering details and integrations are represented only where supported by the excerpts or README; unsampled modules are not assumed to call one another.

Main entry points: [`app/components/StatsPageComponent.tsx`](https://github.com/shotcrib77/dulolytics/blob/master/app/components/StatsPageComponent.tsx) (Results view), [`app/lib/riot.ts`](https://github.com/shotcrib77/dulolytics/blob/master/app/lib/riot.ts) (Riot data workflow), [`app/api/duo/route.ts`](https://github.com/shotcrib77/dulolytics/blob/master/app/api/duo/route.ts) (Duo API), [`app/components/SearchCard.tsx`](https://github.com/shotcrib77/dulolytics/blob/master/app/components/SearchCard.tsx) (Duo search)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Search and results"]
  node_search["Duo search<br/>[SearchCard.tsx]"]
  node_home["Search page<br/>[page.tsx]"]
  node_statsroute["Stats route<br/>[page.tsx]"]
  node_results["Results view"]
  node_playercards["Player cards<br/>[PlayerCards.tsx]"]
  node_score["Compatibility score<br/>[PoroScore.tsx]"]
  node_overview["Stat overview<br/>[StatsOverview.tsx]"]
  node_sharing["Share results<br/>[ShareButton.tsx]"]
  node_og["Share image<br/>[route.tsx]"]
end

subgraph group_backend["Duo analysis"]
  node_duoapi["Duo API<br/>[route.ts]"]
  node_statscalc["Rating calculation<br/>[duoStats.ts]"]
  node_benchmarks["Rating benchmarks<br/>[constants.ts]"]
end

subgraph group_data["Riot and cache"]
  node_riotflow["Riot data workflow<br/>[riot.ts]"]
  node_cachehelper["Cache wrapper<br/>[cache.ts]"]
  node_redis[("Redis cache<br/>[redis.ts]")]
end

node_visitor(("Player"))
node_riotapi{{"Riot Games API"}}
node_ddragon{{"Data Dragon"}}

node_visitor -->|"enters duo"| node_search
node_home -->|"renders"| node_search
node_search -->|"routes with IDs"| node_statsroute
node_statsroute -->|"renders"| node_results
node_results -->|"fetches stats"| node_duoapi
node_duoapi -->|"requests analysis"| node_riotflow
node_riotflow -->|"fetches player data"| node_riotapi
node_riotflow -->|"caches API data"| node_cachehelper
node_cachehelper -->|"reads and writes"| node_redis
node_riotflow -->|"reads matches"| node_redis
node_riotflow -->|"calculates ratings"| node_statscalc
node_statscalc -->|"rates against"| node_benchmarks
node_duoapi -->|"counts searches"| node_redis
node_results -->|"renders profiles"| node_playercards
node_results -->|"renders score"| node_score
node_results -->|"renders ratings"| node_overview
node_results -->|"offers sharing"| node_sharing
node_sharing -.->|"requests image"| node_og
node_og -->|"fetches icons"| node_ddragon

click node_search "https://github.com/shotcrib77/dulolytics/blob/master/app/components/SearchCard.tsx"
click node_home "https://github.com/shotcrib77/dulolytics/blob/master/app/page.tsx"
click node_statsroute "https://github.com/shotcrib77/dulolytics/blob/master/app/stats/page.tsx"
click node_results "https://github.com/shotcrib77/dulolytics/blob/master/app/components/StatsPageComponent.tsx"
click node_playercards "https://github.com/shotcrib77/dulolytics/blob/master/app/components/PlayerCards.tsx"
click node_score "https://github.com/shotcrib77/dulolytics/blob/master/app/components/PoroScore.tsx"
click node_overview "https://github.com/shotcrib77/dulolytics/blob/master/app/components/StatsOverview.tsx"
click node_sharing "https://github.com/shotcrib77/dulolytics/blob/master/app/components/ShareButton.tsx"
click node_og "https://github.com/shotcrib77/dulolytics/blob/master/app/api/og/route.tsx"
click node_duoapi "https://github.com/shotcrib77/dulolytics/blob/master/app/api/duo/route.ts"
click node_riotflow "https://github.com/shotcrib77/dulolytics/blob/master/app/lib/riot.ts"
click node_statscalc "https://github.com/shotcrib77/dulolytics/blob/master/app/lib/duoStats.ts"
click node_benchmarks "https://github.com/shotcrib77/dulolytics/blob/master/app/lib/constants.ts"
click node_cachehelper "https://github.com/shotcrib77/dulolytics/blob/master/app/lib/cache.ts"
click node_redis "https://github.com/shotcrib77/dulolytics/blob/master/app/lib/redis.ts"

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_search,node_home,node_statsroute,node_results,node_playercards,node_score,node_overview,node_sharing,node_og toneBlue
class node_duoapi,node_statscalc,node_benchmarks toneAmber
class node_riotflow,node_cachehelper,node_redis,node_riotapi toneMint
class node_visitor,node_ddragon toneIndigo
```

## Components

### Search and results

- [Duo search](https://github.com/shotcrib77/dulolytics/blob/master/app/components/SearchCard.tsx): `app/components/SearchCard.tsx`
- [Search page](https://github.com/shotcrib77/dulolytics/blob/master/app/page.tsx): `app/page.tsx`
- [Stats route](https://github.com/shotcrib77/dulolytics/blob/master/app/stats/page.tsx): `app/stats/page.tsx`
- [Results view](https://github.com/shotcrib77/dulolytics/blob/master/app/components/StatsPageComponent.tsx): `app/components/StatsPageComponent.tsx`
- [Player cards](https://github.com/shotcrib77/dulolytics/blob/master/app/components/PlayerCards.tsx): `app/components/PlayerCards.tsx`
- [Compatibility score](https://github.com/shotcrib77/dulolytics/blob/master/app/components/PoroScore.tsx): `app/components/PoroScore.tsx`
- [Stat overview](https://github.com/shotcrib77/dulolytics/blob/master/app/components/StatsOverview.tsx): `app/components/StatsOverview.tsx`
- [Share results](https://github.com/shotcrib77/dulolytics/blob/master/app/components/ShareButton.tsx): `app/components/ShareButton.tsx`
- [Share image](https://github.com/shotcrib77/dulolytics/blob/master/app/api/og/route.tsx): `app/api/og/route.tsx`

### Duo analysis

- [Duo API](https://github.com/shotcrib77/dulolytics/blob/master/app/api/duo/route.ts): `app/api/duo/route.ts`
- [Rating calculation](https://github.com/shotcrib77/dulolytics/blob/master/app/lib/duoStats.ts): `app/lib/duoStats.ts`
- [Rating benchmarks](https://github.com/shotcrib77/dulolytics/blob/master/app/lib/constants.ts): `app/lib/constants.ts`

### Riot and cache

- [Riot data workflow](https://github.com/shotcrib77/dulolytics/blob/master/app/lib/riot.ts): `app/lib/riot.ts`
- [Cache wrapper](https://github.com/shotcrib77/dulolytics/blob/master/app/lib/cache.ts): `app/lib/cache.ts`
- [Redis cache](https://github.com/shotcrib77/dulolytics/blob/master/app/lib/redis.ts): `app/lib/redis.ts`

### Other components

- **Player**
- **Riot Games API**
- **Data Dragon**

## Connections

- Player → Duo search: enters duo (evidence: `app/components/SearchCard.tsx`)
- Search page → Duo search: renders (evidence: `app/page.tsx`)
- Duo search → Stats route: routes with IDs (evidence: `app/components/SearchCard.tsx`)
- Stats route → Results view: renders (evidence: `app/stats/page.tsx`)
- Results view → Duo API: fetches stats (evidence: `app/components/StatsPageComponent.tsx`)
- Duo API → Riot data workflow: requests analysis (evidence: `app/api/duo/route.ts`)
- Riot data workflow → Riot Games API: fetches player data (evidence: `app/lib/riot.ts`)
- Riot data workflow → Cache wrapper: caches API data (evidence: `app/lib/riot.ts`)
- Cache wrapper → Redis cache: reads and writes (evidence: `app/lib/cache.ts`)
- Riot data workflow → Redis cache: reads matches (evidence: `app/lib/riot.ts`)
- Riot data workflow → Rating calculation: calculates ratings (evidence: `app/lib/riot.ts`)
- Rating calculation → Rating benchmarks: rates against (evidence: `app/lib/duoStats.ts`)
- Duo API → Redis cache: counts searches (evidence: `app/api/duo/route.ts`)
- Results view → Player cards: renders profiles (evidence: `app/components/StatsPageComponent.tsx`)
- Results view → Compatibility score: renders score (evidence: `app/components/StatsPageComponent.tsx`)
- Results view → Stat overview: renders ratings (evidence: `app/components/StatsPageComponent.tsx`)
- Results view → Share results: offers sharing (evidence: `app/components/StatsPageComponent.tsx`)
- Share results → Share image: requests image
- Share image → Data Dragon: fetches icons (evidence: `app/api/og/route.tsx`)
