# kaleimhc/paneldata.app architecture

> Architecture diagram of the GitHub repository kaleimhc/paneldata.app, 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/kaleimhc/paneldata.app
- Repository: https://github.com/kaleimhc/paneldata.app

## Overview

paneldata.app is a Rails platform for exploring country-year indicators and estimating dynamic Panel-VARs. The main workflow selects indicators and a year, fetches country observations, and paints a choropleth; the analysis workflow submits a configured run, builds a balanced panel, computes estimates asynchronously, stores typed results, and presents them. The graph preserves these distinct stages and documented capabilities. Some subsystems are represented by exact directories because their source was not sampled; links to those are omitted where no caller relationship is evidenced.

Main entry points: [`app/controllers/analyses_controller.rb`](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/analyses_controller.rb) (Analysis endpoints), [`app/javascript/controllers/indicator_picker_controller.js`](https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/indicator_picker_controller.js) (Indicator picker), [`app/controllers/api/observations_controller.rb`](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/api/observations_controller.rb) (Observations API), [`app/jobs/pvar_job.rb`](https://github.com/kaleimhc/paneldata.app/blob/main/app/jobs/pvar_job.rb) (PVAR job)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_explore["Indicator exploration"]
  node_pages["Explore page"]
  node_observations_api["Observations API"]
  node_geo["Map geometry<br/>[geo_controller.rb]"]
  node_methodology["Methodology viewer"]
end

subgraph group_analysis["Panel-VAR analysis"]
  node_analyses["Analysis endpoints"]
  node_analysis_run[("Analysis run<br/>[analysis_run.rb]")]
  node_pvar_job["PVAR job<br/>[pvar_job.rb]"]
  node_panel_builder["Panel builder<br/>[panel_builder.rb]"]
  node_r_estimator["R estimator"]
  node_results[("Typed results<br/>[irf_estimate.rb]")]
end

subgraph group_data["Data domain"]
  node_catalog["Indicator catalog"]
  node_coverage["Indicator coverage"]
  node_indicator["Indicators<br/>[indicator.rb]"]
  node_observation[("Observations<br/>[observation.rb]")]
  node_country[("Countries<br/>[country.rb]")]
  node_indicator_taxonomy["Indicator taxonomy"]
end

subgraph group_presentation["User interface"]
  node_picker["Indicator picker"]
  node_choropleth["Choropleth map"]
  node_analysis_config["Run configuration"]
  node_result_view["Analysis result"]
  node_run_history["Run history"]
  node_search["Indicator search"]
end

node_visitor(("Visitor"))
node_external_queue["Sidekiq queue"]

node_visitor -->|"opens"| node_pages
node_visitor -->|"selects indicator"| node_picker
node_picker -->|"dispatches selection"| node_choropleth
node_choropleth -->|"fetches observations"| node_observations_api
node_observations_api -->|"queries"| node_observation
node_observations_api -->|"reads metadata"| node_indicator
node_observation -->|"joins"| node_country
node_visitor -->|"requests geometry"| node_geo
node_visitor -.->|"configures run"| node_analysis_config
node_analysis_config -.->|"submits run"| node_analyses
node_analyses -->|"validates indicators"| node_indicator
node_analyses -->|"creates run"| node_analysis_run
node_analyses -->|"enqueues"| node_pvar_job
node_pvar_job -.->|"builds panel"| node_panel_builder
node_pvar_job -.->|"runs estimation"| node_r_estimator
node_r_estimator -.->|"persists estimates"| node_results
node_analyses -->|"polls status"| node_analysis_run
node_visitor -.->|"views history"| node_run_history
node_run_history -.->|"requests summaries"| node_analyses
node_visitor -.->|"views result"| node_result_view
node_pages -->|"loads completed run"| node_analysis_run
node_result_view -.->|"renders estimates"| node_results
node_visitor -.->|"searches indicators"| node_search
node_search -->|"selects indicator"| node_picker
node_visitor -->|"opens methodology"| node_methodology
node_picker -.->|"filters catalog"| node_catalog
node_analyses -.->|"checks coverage"| node_coverage

click node_pages "https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/pages_controller.rb"
click node_picker "https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/indicator_picker_controller.js"
click node_choropleth "https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/choropleth_controller.js"
click node_observations_api "https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/api/observations_controller.rb"
click node_geo "https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/geo_controller.rb"
click node_catalog "https://github.com/kaleimhc/paneldata.app/blob/main/app/services/indicator_catalog.rb"
click node_coverage "https://github.com/kaleimhc/paneldata.app/blob/main/app/services/indicator_coverage.rb"
click node_indicator "https://github.com/kaleimhc/paneldata.app/blob/main/app/models/indicator.rb"
click node_observation "https://github.com/kaleimhc/paneldata.app/blob/main/app/models/observation.rb"
click node_country "https://github.com/kaleimhc/paneldata.app/blob/main/app/models/country.rb"
click node_analysis_config "https://github.com/kaleimhc/paneldata.app/blob/main/app/components/run_config_component.rb"
click node_analyses "https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/analyses_controller.rb"
click node_analysis_run "https://github.com/kaleimhc/paneldata.app/blob/main/app/models/analysis_run.rb"
click node_pvar_job "https://github.com/kaleimhc/paneldata.app/blob/main/app/jobs/pvar_job.rb"
click node_panel_builder "https://github.com/kaleimhc/paneldata.app/blob/main/app/services/panel_builder.rb"
click node_results "https://github.com/kaleimhc/paneldata.app/blob/main/app/models/irf_estimate.rb"
click node_result_view "https://github.com/kaleimhc/paneldata.app/blob/main/app/components/analysis_result_component.rb"
click node_run_history "https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/run_history_controller.js"
click node_search "https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/search_controller.js"
click node_methodology "https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/pages_controller.rb"
click node_indicator_taxonomy "https://github.com/kaleimhc/paneldata.app/blob/main/app/models/indicator_taxonomy.rb"

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_pages,node_observations_api,node_geo,node_methodology toneBlue
class node_analyses,node_analysis_run,node_pvar_job,node_panel_builder,node_r_estimator,node_results toneAmber
class node_catalog,node_coverage,node_indicator,node_observation,node_country,node_indicator_taxonomy toneMint
class node_picker,node_choropleth,node_analysis_config,node_result_view,node_run_history,node_search,node_external_queue toneRose
class node_visitor toneIndigo
```

## Components

### Indicator exploration

- [Explore page](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/pages_controller.rb): `app/controllers/pages_controller.rb`
- [Observations API](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/api/observations_controller.rb): `app/controllers/api/observations_controller.rb`
- [Map geometry](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/geo_controller.rb): `app/controllers/geo_controller.rb`
- [Methodology viewer](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/pages_controller.rb): `app/controllers/pages_controller.rb`

### Panel-VAR analysis

- [Analysis endpoints](https://github.com/kaleimhc/paneldata.app/blob/main/app/controllers/analyses_controller.rb): `app/controllers/analyses_controller.rb`
- [Analysis run](https://github.com/kaleimhc/paneldata.app/blob/main/app/models/analysis_run.rb): `app/models/analysis_run.rb`
- [PVAR job](https://github.com/kaleimhc/paneldata.app/blob/main/app/jobs/pvar_job.rb): `app/jobs/pvar_job.rb`
- [Panel builder](https://github.com/kaleimhc/paneldata.app/blob/main/app/services/panel_builder.rb): `app/services/panel_builder.rb`
- **R estimator**
- [Typed results](https://github.com/kaleimhc/paneldata.app/blob/main/app/models/irf_estimate.rb): `app/models/irf_estimate.rb`

### Data domain

- [Indicator catalog](https://github.com/kaleimhc/paneldata.app/blob/main/app/services/indicator_catalog.rb): `app/services/indicator_catalog.rb`
- [Indicator coverage](https://github.com/kaleimhc/paneldata.app/blob/main/app/services/indicator_coverage.rb): `app/services/indicator_coverage.rb`
- [Indicators](https://github.com/kaleimhc/paneldata.app/blob/main/app/models/indicator.rb): `app/models/indicator.rb`
- [Observations](https://github.com/kaleimhc/paneldata.app/blob/main/app/models/observation.rb): `app/models/observation.rb`
- [Countries](https://github.com/kaleimhc/paneldata.app/blob/main/app/models/country.rb): `app/models/country.rb`
- [Indicator taxonomy](https://github.com/kaleimhc/paneldata.app/blob/main/app/models/indicator_taxonomy.rb): `app/models/indicator_taxonomy.rb`

### User interface

- [Indicator picker](https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/indicator_picker_controller.js): `app/javascript/controllers/indicator_picker_controller.js`
- [Choropleth map](https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/choropleth_controller.js): `app/javascript/controllers/choropleth_controller.js`
- [Run configuration](https://github.com/kaleimhc/paneldata.app/blob/main/app/components/run_config_component.rb): `app/components/run_config_component.rb`
- [Analysis result](https://github.com/kaleimhc/paneldata.app/blob/main/app/components/analysis_result_component.rb): `app/components/analysis_result_component.rb`
- [Run history](https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/run_history_controller.js): `app/javascript/controllers/run_history_controller.js`
- [Indicator search](https://github.com/kaleimhc/paneldata.app/blob/main/app/javascript/controllers/search_controller.js): `app/javascript/controllers/search_controller.js`

### Other components

- **Visitor**
- **Sidekiq queue**

## Connections

- Visitor → Explore page: opens
- Visitor → Indicator picker: selects indicator (evidence: `app/javascript/controllers/indicator_picker_controller.js`)
- Indicator picker → Choropleth map: dispatches selection (evidence: `app/javascript/controllers/indicator_picker_controller.js`)
- Choropleth map → Observations API: fetches observations (evidence: `app/javascript/controllers/choropleth_controller.js`)
- Observations API → Observations: queries (evidence: `app/controllers/api/observations_controller.rb`)
- Observations API → Indicators: reads metadata (evidence: `app/controllers/api/observations_controller.rb`)
- Observations → Countries: joins
- Visitor → Map geometry: requests geometry
- Visitor → Run configuration: configures run
- Run configuration → Analysis endpoints: submits run
- Analysis endpoints → Indicators: validates indicators (evidence: `app/controllers/analyses_controller.rb`)
- Analysis endpoints → Analysis run: creates run (evidence: `app/controllers/analyses_controller.rb`)
- Analysis endpoints → PVAR job: enqueues (evidence: `app/controllers/analyses_controller.rb`)
- PVAR job → Panel builder: builds panel
- PVAR job → R estimator: runs estimation
- R estimator → Typed results: persists estimates
- Analysis endpoints → Analysis run: polls status (evidence: `app/controllers/analyses_controller.rb`)
- Visitor → Run history: views history
- Run history → Analysis endpoints: requests summaries
- Visitor → Analysis result: views result
- Explore page → Analysis run: loads completed run (evidence: `app/controllers/pages_controller.rb`)
- Analysis result → Typed results: renders estimates
- Visitor → Indicator search: searches indicators
- Indicator search → Indicator picker: selects indicator (evidence: `app/javascript/controllers/indicator_picker_controller.js`)
- Visitor → Methodology viewer: opens methodology
- Indicator picker → Indicator catalog: filters catalog
- Analysis endpoints → Indicator coverage: checks coverage
