# loamysand/whatspoppingabq architecture

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

- Interactive diagram: https://gitdiagram.com/loamysand/whatspoppingabq
- Repository: https://github.com/loamysand/whatspoppingabq

## Overview

What's Popping ABQ collects Albuquerque event and traffic data, stores it in PostgreSQL, and presents event-impact analysis in an interactive dashboard. The primary workflow scrapes and validates events, geocodes venues, and loads them; separate Prefect flows gather event-time and rotating baseline traffic measurements. Analytics compare event conditions with baselines for dashboard visualizations. The README documents capabilities beyond the sampled code, including quality indicators and category analysis; those branches are represented at their documented subsystem paths. Relationships without shown call sites are omitted.

Main entry points: [`database/db_utils.py`](https://github.com/loamysand/whatspoppingabq/blob/main/database/db_utils.py) (Database utilities), [`database/schema/event_analytics_schema.sql`](https://github.com/loamysand/whatspoppingabq/blob/main/database/schema/event_analytics_schema.sql) (PostgreSQL), [`collectors/baseline_schedule.py`](https://github.com/loamysand/whatspoppingabq/blob/main/collectors/baseline_schedule.py) (Baseline schedule), [`flows/ingest_events.py`](https://github.com/loamysand/whatspoppingabq/blob/main/flows/ingest_events.py) (Ingestion flow)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingestion["Event ingestion"]
  node_event_scraper["Event scraper"]
  node_ingest_flow["Ingestion flow<br/>[ingest_events.py]"]
  node_geocoder["Venue geocoder<br/>[geocoding.py]"]
end

subgraph group_traffic["Traffic collection"]
  node_traffic_flow["Traffic flows<br/>[collect_traffic.py]"]
  node_event_collector["Event collector"]
  node_baseline_schedule["Baseline schedule"]
  node_baseline_collector["Baseline collector"]
  node_collection_rules["Collection rules"]
  node_flow_collector["TomTom flow client"]
end

subgraph group_storage["Data and analytics"]
  node_database[("PostgreSQL")]
  node_db_utils["Database utilities<br/>[db_utils.py]"]
end

subgraph group_presentation["Analysis and dashboard"]
  node_correlation["Impact analysis"]
  node_dashboard["Interactive dashboard"]
  node_html_dashboard["HTML dashboard"]
  node_traffic_report["Traffic report"]
  node_event_times["Event-time analysis"]
end

node_event_source(("Visit Albuquerque"))
node_maps_api(("Google Maps API"))
node_prefect(("Prefect runner"))
node_tomtom_api(("TomTom Traffic API"))
node_dashboard_user(("Dashboard user"))

node_event_source -->|"provides listings"| node_event_scraper
node_event_scraper -->|"supplies events"| node_ingest_flow
node_ingest_flow -->|"loads events"| node_db_utils
node_ingest_flow -->|"geocodes venues"| node_geocoder
node_geocoder -->|"requests coordinates"| node_maps_api
node_prefect -->|"runs flow"| node_ingest_flow
node_prefect -->|"runs flows"| node_traffic_flow
node_traffic_flow -->|"runs collection"| node_event_collector
node_traffic_flow -->|"runs schedule"| node_baseline_schedule
node_baseline_schedule -->|"collects venue data"| node_baseline_collector
node_baseline_schedule -->|"reads venues"| node_db_utils
node_baseline_schedule -->|"stores measurements"| node_db_utils
node_event_collector -->|"requests measurements"| node_flow_collector
node_event_collector -->|"stores measurements"| node_db_utils
node_baseline_collector -->|"requests measurements"| node_flow_collector
node_flow_collector -->|"fetches traffic"| node_tomtom_api
node_db_utils -->|"reads and writes"| node_database
node_correlation -->|"queries measurements"| node_database
node_dashboard -->|"queries analytics"| node_database
node_dashboard_user -->|"views impact"| node_dashboard
node_html_dashboard -->|"queries data"| node_database
node_traffic_report -->|"uses analyses"| node_correlation
node_event_times -->|"queries events"| node_database

click node_event_scraper "https://github.com/loamysand/whatspoppingabq/blob/main/scrapers/visit_abq_detail_scraper.py"
click node_ingest_flow "https://github.com/loamysand/whatspoppingabq/blob/main/flows/ingest_events.py"
click node_geocoder "https://github.com/loamysand/whatspoppingabq/blob/main/utils/geocoding.py"
click node_traffic_flow "https://github.com/loamysand/whatspoppingabq/blob/main/flows/collect_traffic.py"
click node_event_collector "https://github.com/loamysand/whatspoppingabq/blob/main/collectors/tomtom_event_traffic_collector.py"
click node_baseline_schedule "https://github.com/loamysand/whatspoppingabq/blob/main/collectors/baseline_schedule.py"
click node_baseline_collector "https://github.com/loamysand/whatspoppingabq/blob/main/collectors/baseline_collector_tomtom.py"
click node_collection_rules "https://github.com/loamysand/whatspoppingabq/blob/main/collectors/traffic_collection_rules.py"
click node_flow_collector "https://github.com/loamysand/whatspoppingabq/blob/main/collectors/tomtom_flow_collector.py"
click node_database "https://github.com/loamysand/whatspoppingabq/blob/main/database/schema/event_analytics_schema.sql"
click node_db_utils "https://github.com/loamysand/whatspoppingabq/blob/main/database/db_utils.py"
click node_correlation "https://github.com/loamysand/whatspoppingabq/blob/main/analysis/event_traffic_correlation.py"
click node_dashboard "https://github.com/loamysand/whatspoppingabq/blob/main/analysis/event_traffic_dashboard.py"
click node_html_dashboard "https://github.com/loamysand/whatspoppingabq/blob/main/analysis/generate_html_dashboard.py"
click node_traffic_report "https://github.com/loamysand/whatspoppingabq/blob/main/analysis/generate_traffic_report.py"
click node_event_times "https://github.com/loamysand/whatspoppingabq/blob/main/analysis/analyze_event_times.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_event_scraper,node_ingest_flow,node_geocoder,node_dashboard_user toneBlue
class node_traffic_flow,node_event_collector,node_baseline_schedule,node_baseline_collector,node_collection_rules,node_flow_collector toneAmber
class node_database,node_db_utils,node_maps_api,node_tomtom_api toneMint
class node_correlation,node_dashboard,node_html_dashboard,node_traffic_report,node_event_times toneRose
class node_event_source,node_prefect toneIndigo
```

## Components

### Event ingestion

- [Event scraper](https://github.com/loamysand/whatspoppingabq/blob/main/scrapers/visit_abq_detail_scraper.py): `scrapers/visit_abq_detail_scraper.py`
- [Ingestion flow](https://github.com/loamysand/whatspoppingabq/blob/main/flows/ingest_events.py): `flows/ingest_events.py`
- [Venue geocoder](https://github.com/loamysand/whatspoppingabq/blob/main/utils/geocoding.py): `utils/geocoding.py`

### Traffic collection

- [Traffic flows](https://github.com/loamysand/whatspoppingabq/blob/main/flows/collect_traffic.py): `flows/collect_traffic.py`
- [Event collector](https://github.com/loamysand/whatspoppingabq/blob/main/collectors/tomtom_event_traffic_collector.py): `collectors/tomtom_event_traffic_collector.py`
- [Baseline schedule](https://github.com/loamysand/whatspoppingabq/blob/main/collectors/baseline_schedule.py): `collectors/baseline_schedule.py`
- [Baseline collector](https://github.com/loamysand/whatspoppingabq/blob/main/collectors/baseline_collector_tomtom.py): `collectors/baseline_collector_tomtom.py`
- [Collection rules](https://github.com/loamysand/whatspoppingabq/blob/main/collectors/traffic_collection_rules.py): `collectors/traffic_collection_rules.py`
- [TomTom flow client](https://github.com/loamysand/whatspoppingabq/blob/main/collectors/tomtom_flow_collector.py): `collectors/tomtom_flow_collector.py`

### Data and analytics

- [PostgreSQL](https://github.com/loamysand/whatspoppingabq/blob/main/database/schema/event_analytics_schema.sql): `database/schema/event_analytics_schema.sql`
- [Database utilities](https://github.com/loamysand/whatspoppingabq/blob/main/database/db_utils.py): `database/db_utils.py`

### Analysis and dashboard

- [Impact analysis](https://github.com/loamysand/whatspoppingabq/blob/main/analysis/event_traffic_correlation.py): `analysis/event_traffic_correlation.py`
- [Interactive dashboard](https://github.com/loamysand/whatspoppingabq/blob/main/analysis/event_traffic_dashboard.py): `analysis/event_traffic_dashboard.py`
- [HTML dashboard](https://github.com/loamysand/whatspoppingabq/blob/main/analysis/generate_html_dashboard.py): `analysis/generate_html_dashboard.py`
- [Traffic report](https://github.com/loamysand/whatspoppingabq/blob/main/analysis/generate_traffic_report.py): `analysis/generate_traffic_report.py`
- [Event-time analysis](https://github.com/loamysand/whatspoppingabq/blob/main/analysis/analyze_event_times.py): `analysis/analyze_event_times.py`

### Other components

- **Visit Albuquerque**
- **Google Maps API**
- **Prefect runner**
- **TomTom Traffic API**
- **Dashboard user**

## Connections

- Visit Albuquerque → Event scraper: provides listings (evidence: `README.md`)
- Event scraper → Ingestion flow: supplies events (evidence: `flows/ingest_events.py`)
- Ingestion flow → Database utilities: loads events (evidence: `flows/ingest_events.py`)
- Ingestion flow → Venue geocoder: geocodes venues (evidence: `flows/ingest_events.py`)
- Venue geocoder → Google Maps API: requests coordinates (evidence: `README.md`)
- Prefect runner → Ingestion flow: runs flow (evidence: `README.md`)
- Prefect runner → Traffic flows: runs flows (evidence: `README.md`)
- Traffic flows → Event collector: runs collection (evidence: `flows/collect_traffic.py`)
- Traffic flows → Baseline schedule: runs schedule (evidence: `flows/collect_traffic.py`)
- Baseline schedule → Baseline collector: collects venue data (evidence: `collectors/baseline_schedule.py`)
- Baseline schedule → Database utilities: reads venues (evidence: `collectors/baseline_schedule.py`)
- Baseline schedule → Database utilities: stores measurements (evidence: `collectors/baseline_schedule.py`)
- Event collector → TomTom flow client: requests measurements (evidence: `collectors/tomtom_event_traffic_collector.py`)
- Event collector → Database utilities: stores measurements (evidence: `collectors/tomtom_event_traffic_collector.py`)
- Baseline collector → TomTom flow client: requests measurements (evidence: `collectors/baseline_collector_tomtom.py`)
- TomTom flow client → TomTom Traffic API: fetches traffic (evidence: `collectors/tomtom_flow_collector.py`)
- Database utilities → PostgreSQL: reads and writes (evidence: `database/db_utils.py`)
- Impact analysis → PostgreSQL: queries measurements (evidence: `analysis/event_traffic_correlation.py`)
- Interactive dashboard → PostgreSQL: queries analytics (evidence: `README.md`)
- Dashboard user → Interactive dashboard: views impact (evidence: `README.md`)
- HTML dashboard → PostgreSQL: queries data (evidence: `analysis/generate_html_dashboard.py`)
- Traffic report → Impact analysis: uses analyses (evidence: `analysis/generate_traffic_report.py`)
- Event-time analysis → PostgreSQL: queries events (evidence: `analysis/analyze_event_times.py`)
