# john-alexander-611/edhbulkup architecture

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

- Interactive diagram: https://gitdiagram.com/john-alexander-611/edhbulkup
- Repository: https://github.com/john-alexander-611/edhbulkup

## Overview

EDH Bulk Up helps users find Commander decks that fit cards they own, then analyzes a selected deck and recommends ways to fill gaps. The main workflow is collection upload, filtered deck matching, and per-commander analysis with missing-card and replacement suggestions. The frontend calls a FastAPI backend; backend logic uses cached EDHREC deck data and Scryfall card and tag data. Cache-building paths are included as product data preparation, not deployment machinery. Some backend endpoint wiring is unsampled, so uncertain internal calls are omitted.

Main entry points: [`services/deck_service.py`](https://github.com/john-alexander-611/edhbulkup/blob/main/services/deck_service.py) (Deck service), [`app/main.py`](https://github.com/john-alexander-611/edhbulkup/blob/main/app/main.py) (HTTP API), [`frontend/app/commanders/[commanderName]/page.tsx`](https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/app/commanders/%5BcommanderName%5D/page.tsx) (Deck analysis view), [`commander_specific.py`](https://github.com/john-alexander-611/edhbulkup/blob/main/commander_specific.py) (Replacement logic)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web experience"]
  node_home["Deck search<br/>[page.tsx]"]
  node_commander_view["Deck analysis view<br/>[page.tsx]"]
  node_frontend_api["API client<br/>[api.ts]"]
  node_tcgplayer["TCGplayer links<br/>[tcgplayer.ts]"]
end

subgraph group_backend["API and sessions"]
  node_backend_api["HTTP API<br/>[main.py]"]
  node_api_schemas["API schemas<br/>[schemas.py]"]
end

subgraph group_analysis["Deck analysis"]
  node_deck_service["Deck service<br/>[deck_service.py]"]
  node_collection_parser["Collection parser<br/>[parse_moxfield.py]"]
  node_collection_model["Collection model<br/>[collection.py]"]
  node_deck_model["Deck model<br/>[deck.py]"]
  node_commander_model["Commander model<br/>[commander.py]"]
  node_recommendations["Replacement logic"]
  node_results["Analysis results<br/>[results.py]"]
end

subgraph group_data["Cached data"]
  node_deck_cache[("Commander deck cache")]
  node_scryfall_cache[("Card metadata cache<br/>[cache_wrappers.py]")]
  node_tag_cache[("Functional tag cache<br/>[cache_wrappers.py]")]
end

subgraph group_prep["Data preparation"]
  node_deck_cache_builder["EDHREC cache builder<br/>[build_cache.py]"]
  node_edhrec_client["EDHREC client<br/>[edhrec_raw.py]"]
  node_scryfall_builder["Scryfall cache builder"]
  node_tag_builder["Tag cache builder<br/>[build_tag_cache.py]"]
end

node_user(("Collection owner"))
node_edhrec(("EDHREC"))
node_scryfall(("Scryfall"))
node_tcgplayer_service(("TCGplayer"))

node_user -->|"uses"| node_home
node_home -->|"requests"| node_frontend_api
node_commander_view -->|"requests"| node_frontend_api
node_frontend_api -->|"calls"| node_backend_api
node_backend_api -->|"validates"| node_api_schemas
node_backend_api -->|"delegates"| node_deck_service
node_deck_service -->|"parses"| node_collection_parser
node_deck_service -->|"uses"| node_collection_model
node_deck_service -->|"uses"| node_deck_model
node_deck_service -->|"loads"| node_deck_cache
node_deck_model -->|"uses"| node_commander_model
node_deck_service -->|"requests suggestions"| node_recommendations
node_recommendations -->|"looks up tags"| node_tag_cache
node_recommendations -->|"checks cards"| node_scryfall_cache
node_deck_service -->|"builds results"| node_results
node_backend_api -->|"reads presentation data"| node_scryfall_cache
node_deck_cache_builder -->|"fetches data"| node_edhrec_client
node_edhrec_client -->|"requests deck data"| node_edhrec
node_deck_cache_builder -->|"writes"| node_deck_cache
node_scryfall_builder -->|"downloads bulk data"| node_scryfall
node_scryfall_builder -->|"writes"| node_scryfall_cache
node_tag_builder -->|"retrieves tag data"| node_scryfall
node_tag_builder -->|"writes"| node_tag_cache
node_commander_view -.->|"opens purchase links"| node_tcgplayer
node_commander_view -.->|"links to"| node_tcgplayer_service

click node_home "https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/app/page.tsx"
click node_commander_view "https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/app/commanders/%5BcommanderName%5D/page.tsx"
click node_frontend_api "https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/lib/api.ts"
click node_tcgplayer "https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/lib/tcgplayer.ts"
click node_backend_api "https://github.com/john-alexander-611/edhbulkup/blob/main/app/main.py"
click node_api_schemas "https://github.com/john-alexander-611/edhbulkup/blob/main/app/schemas.py"
click node_deck_service "https://github.com/john-alexander-611/edhbulkup/blob/main/services/deck_service.py"
click node_collection_parser "https://github.com/john-alexander-611/edhbulkup/blob/main/parse_input/parse_moxfield.py"
click node_collection_model "https://github.com/john-alexander-611/edhbulkup/blob/main/models/collection.py"
click node_deck_model "https://github.com/john-alexander-611/edhbulkup/blob/main/models/deck.py"
click node_commander_model "https://github.com/john-alexander-611/edhbulkup/blob/main/models/commander.py"
click node_recommendations "https://github.com/john-alexander-611/edhbulkup/blob/main/commander_specific.py"
click node_results "https://github.com/john-alexander-611/edhbulkup/blob/main/services/results.py"
click node_deck_cache "https://github.com/john-alexander-611/edhbulkup/blob/main/create_cache/commander_data.json"
click node_scryfall_cache "https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/cache_wrappers.py"
click node_tag_cache "https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/cache_wrappers.py"
click node_deck_cache_builder "https://github.com/john-alexander-611/edhbulkup/blob/main/create_cache/build_cache.py"
click node_edhrec_client "https://github.com/john-alexander-611/edhbulkup/blob/main/create_cache/edhrec_raw.py"
click node_scryfall_builder "https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/build_scryfall_cache.py"
click node_tag_builder "https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/build_tag_cache.py"

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_home,node_commander_view,node_frontend_api,node_tcgplayer toneBlue
class node_backend_api,node_api_schemas toneAmber
class node_deck_service,node_collection_parser,node_collection_model,node_deck_model,node_commander_model,node_recommendations,node_results toneMint
class node_deck_cache,node_scryfall_cache,node_tag_cache toneRose
class node_deck_cache_builder,node_edhrec_client,node_scryfall_builder,node_tag_builder,node_user,node_edhrec,node_scryfall,node_tcgplayer_service toneIndigo
```

## Components

### Web experience

- [Deck search](https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/app/page.tsx): `frontend/app/page.tsx`
- [Deck analysis view](https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/app/commanders/%5BcommanderName%5D/page.tsx): `frontend/app/commanders/[commanderName]/page.tsx`
- [API client](https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/lib/api.ts): `frontend/lib/api.ts`
- [TCGplayer links](https://github.com/john-alexander-611/edhbulkup/blob/main/frontend/lib/tcgplayer.ts): `frontend/lib/tcgplayer.ts`

### API and sessions

- [HTTP API](https://github.com/john-alexander-611/edhbulkup/blob/main/app/main.py): `app/main.py`
- [API schemas](https://github.com/john-alexander-611/edhbulkup/blob/main/app/schemas.py): `app/schemas.py`

### Deck analysis

- [Deck service](https://github.com/john-alexander-611/edhbulkup/blob/main/services/deck_service.py): `services/deck_service.py`
- [Collection parser](https://github.com/john-alexander-611/edhbulkup/blob/main/parse_input/parse_moxfield.py): `parse_input/parse_moxfield.py`
- [Collection model](https://github.com/john-alexander-611/edhbulkup/blob/main/models/collection.py): `models/collection.py`
- [Deck model](https://github.com/john-alexander-611/edhbulkup/blob/main/models/deck.py): `models/deck.py`
- [Commander model](https://github.com/john-alexander-611/edhbulkup/blob/main/models/commander.py): `models/commander.py`
- [Replacement logic](https://github.com/john-alexander-611/edhbulkup/blob/main/commander_specific.py): `commander_specific.py`
- [Analysis results](https://github.com/john-alexander-611/edhbulkup/blob/main/services/results.py): `services/results.py`

### Cached data

- [Commander deck cache](https://github.com/john-alexander-611/edhbulkup/blob/main/create_cache/commander_data.json): `create_cache/commander_data.json`
- [Card metadata cache](https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/cache_wrappers.py): `scryfall/cache_wrappers.py`
- [Functional tag cache](https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/cache_wrappers.py): `scryfall/cache_wrappers.py`

### Data preparation

- [EDHREC cache builder](https://github.com/john-alexander-611/edhbulkup/blob/main/create_cache/build_cache.py): `create_cache/build_cache.py`
- [EDHREC client](https://github.com/john-alexander-611/edhbulkup/blob/main/create_cache/edhrec_raw.py): `create_cache/edhrec_raw.py`
- [Scryfall cache builder](https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/build_scryfall_cache.py): `scryfall/build_scryfall_cache.py`
- [Tag cache builder](https://github.com/john-alexander-611/edhbulkup/blob/main/scryfall/build_tag_cache.py): `scryfall/build_tag_cache.py`

### Other components

- **Collection owner**
- **EDHREC**
- **Scryfall**
- **TCGplayer**

## Connections

- Collection owner → Deck search: uses
- Deck search → API client: requests
- Deck analysis view → API client: requests
- API client → HTTP API: calls
- HTTP API → API schemas: validates
- HTTP API → Deck service: delegates
- Deck service → Collection parser: parses
- Deck service → Collection model: uses
- Deck service → Deck model: uses
- Deck service → Commander deck cache: loads
- Deck model → Commander model: uses
- Deck service → Replacement logic: requests suggestions
- Replacement logic → Functional tag cache: looks up tags
- Replacement logic → Card metadata cache: checks cards
- Deck service → Analysis results: builds results
- HTTP API → Card metadata cache: reads presentation data
- EDHREC cache builder → EDHREC client: fetches data
- EDHREC client → EDHREC: requests deck data
- EDHREC cache builder → Commander deck cache: writes
- Scryfall cache builder → Scryfall: downloads bulk data
- Scryfall cache builder → Card metadata cache: writes
- Tag cache builder → Scryfall: retrieves tag data
- Tag cache builder → Functional tag cache: writes
- Deck analysis view → TCGplayer links: opens purchase links
- Deck analysis view → TCGplayer: links to
