# andre3oo0/football-analytics architecture

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

- Interactive diagram: https://gitdiagram.com/andre3oo0/football-analytics
- Repository: https://github.com/andre3oo0/football-analytics
- Video tour (about a minute): https://gitdiagram.com/andre3oo0/football-analytics/video

## Overview

This repository is a football analytics data pipeline: scheduled or manual runs fetch competition data, land it in DuckDB, transform it through dbt into a tested dimensional model, and optionally export marts as Parquet for Power BI. The graph follows documented pipeline stages and sampled ingestion/export code; individual dbt model dependencies and workflow commands are based on README documentation, since those implementation files were not sampled.

Main entry points: [`dbt/models/intermediate`](https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/intermediate) (Intermediate views), [`.github/workflows/pipeline.yml`](https://github.com/andre3oo0/football-analytics/blob/main/.github/workflows/pipeline.yml) (Pipeline workflow), [`ingestion/run.py`](https://github.com/andre3oo0/football-analytics/blob/main/ingestion/run.py) (Ingestion runner), [`ingestion/api_client.py`](https://github.com/andre3oo0/football-analytics/blob/main/ingestion/api_client.py) (API client)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_orchestration["Orchestration"]
  node_workflow["Pipeline workflow<br/>[pipeline.yml]"]
end

subgraph group_ingestion["Ingestion"]
  node_runner["Ingestion runner<br/>[run.py]"]
  node_client["API client<br/>[api_client.py]"]
  node_cache["Raw JSON cache"]
  node_loader["Raw loader<br/>[loader.py]"]
end

subgraph group_warehouse["Warehouse Modeling"]
  node_warehouse_db[("DuckDB warehouse")]
  node_staging["Staging views"]
  node_intermediate["Intermediate views"]
  node_competition_seed["Competition seed"]
  node_dimensions["Dimension tables"]
  node_match_facts["Match facts<br/>[fact_matches.sql]"]
  node_standing_facts["Derived standings<br/>[fact_standings.sql]"]
  node_quality["dbt data tests"]
end

subgraph group_serving["Serving"]
  node_exporter["Mart exporter<br/>[export_marts.py]"]
  node_parquet["Parquet exports"]
end

node_scheduler(("Schedule / manual trigger"))
node_api{{"Football-data.org API"}}
node_powerbi(("Power BI consumer"))

node_scheduler -->|"triggers"| node_workflow
node_workflow -->|"runs ingestion"| node_runner
node_workflow -->|"builds dbt"| node_staging
node_runner -->|"requests data"| node_client
node_client -->|"fetches"| node_api
node_client -->|"reads / writes"| node_cache
node_runner -->|"loads responses"| node_loader
node_loader -->|"upserts raw"| node_warehouse_db
node_warehouse_db -->|"reads raw"| node_staging
node_staging -->|"transforms"| node_intermediate
node_intermediate -->|"builds dimensions"| node_dimensions
node_competition_seed -->|"supplies reference"| node_dimensions
node_intermediate -->|"builds match fact"| node_match_facts
node_intermediate -->|"derives standings"| node_standing_facts
node_dimensions -->|"tested by"| node_quality
node_match_facts -->|"tested by"| node_quality
node_standing_facts -->|"tested by"| node_quality
node_warehouse_db -->|"reads marts"| node_exporter
node_exporter -->|"writes files"| node_parquet
node_parquet -.->|"consumed by"| node_powerbi

click node_workflow "https://github.com/andre3oo0/football-analytics/blob/main/.github/workflows/pipeline.yml"
click node_runner "https://github.com/andre3oo0/football-analytics/blob/main/ingestion/run.py"
click node_client "https://github.com/andre3oo0/football-analytics/blob/main/ingestion/api_client.py"
click node_cache "https://github.com/andre3oo0/football-analytics/tree/main/data/raw"
click node_loader "https://github.com/andre3oo0/football-analytics/blob/main/ingestion/loader.py"
click node_staging "https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/staging"
click node_intermediate "https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/intermediate"
click node_competition_seed "https://github.com/andre3oo0/football-analytics/blob/main/dbt/seeds/seed_competitions.csv"
click node_dimensions "https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/marts"
click node_match_facts "https://github.com/andre3oo0/football-analytics/blob/main/dbt/models/marts/fact_matches.sql"
click node_standing_facts "https://github.com/andre3oo0/football-analytics/blob/main/dbt/models/marts/fact_standings.sql"
click node_quality "https://github.com/andre3oo0/football-analytics/tree/main/dbt/tests"
click node_exporter "https://github.com/andre3oo0/football-analytics/blob/main/export_marts.py"
click node_parquet "https://github.com/andre3oo0/football-analytics/tree/main/exports"

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_workflow toneBlue
class node_runner,node_client,node_cache,node_loader toneAmber
class node_warehouse_db,node_staging,node_intermediate,node_competition_seed,node_dimensions,node_match_facts,node_standing_facts,node_quality,node_api toneMint
class node_exporter,node_parquet toneRose
class node_scheduler,node_powerbi toneIndigo
```

## Components

### Orchestration

- [Pipeline workflow](https://github.com/andre3oo0/football-analytics/blob/main/.github/workflows/pipeline.yml): `.github/workflows/pipeline.yml`

### Ingestion

- [Ingestion runner](https://github.com/andre3oo0/football-analytics/blob/main/ingestion/run.py): `ingestion/run.py`
- [API client](https://github.com/andre3oo0/football-analytics/blob/main/ingestion/api_client.py): `ingestion/api_client.py`
- [Raw JSON cache](https://github.com/andre3oo0/football-analytics/tree/main/data/raw): `data/raw`
- [Raw loader](https://github.com/andre3oo0/football-analytics/blob/main/ingestion/loader.py): `ingestion/loader.py`

### Warehouse Modeling

- **DuckDB warehouse**
- [Staging views](https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/staging): `dbt/models/staging`
- [Intermediate views](https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/intermediate): `dbt/models/intermediate`
- [Competition seed](https://github.com/andre3oo0/football-analytics/blob/main/dbt/seeds/seed_competitions.csv): `dbt/seeds/seed_competitions.csv`
- [Dimension tables](https://github.com/andre3oo0/football-analytics/tree/main/dbt/models/marts): `dbt/models/marts`
- [Match facts](https://github.com/andre3oo0/football-analytics/blob/main/dbt/models/marts/fact_matches.sql): `dbt/models/marts/fact_matches.sql`
- [Derived standings](https://github.com/andre3oo0/football-analytics/blob/main/dbt/models/marts/fact_standings.sql): `dbt/models/marts/fact_standings.sql`
- [dbt data tests](https://github.com/andre3oo0/football-analytics/tree/main/dbt/tests): `dbt/tests`

### Serving

- [Mart exporter](https://github.com/andre3oo0/football-analytics/blob/main/export_marts.py): `export_marts.py`
- [Parquet exports](https://github.com/andre3oo0/football-analytics/tree/main/exports): `exports`

### Other components

- **Schedule / manual trigger**
- **Football-data.org API**
- **Power BI consumer**

## Connections

- Schedule / manual trigger → Pipeline workflow: triggers
- Pipeline workflow → Ingestion runner: runs ingestion
- Pipeline workflow → Staging views: builds dbt
- Ingestion runner → API client: requests data
- API client → Football-data.org API: fetches
- API client → Raw JSON cache: reads / writes
- Ingestion runner → Raw loader: loads responses
- Raw loader → DuckDB warehouse: upserts raw
- DuckDB warehouse → Staging views: reads raw
- Staging views → Intermediate views: transforms
- Intermediate views → Dimension tables: builds dimensions
- Competition seed → Dimension tables: supplies reference
- Intermediate views → Match facts: builds match fact
- Intermediate views → Derived standings: derives standings
- Dimension tables → dbt data tests: tested by
- Match facts → dbt data tests: tested by
- Derived standings → dbt data tests: tested by
- DuckDB warehouse → Mart exporter: reads marts
- Mart exporter → Parquet exports: writes files
- Parquet exports → Power BI consumer: consumed by
