# bettergovph/open-budget-data architecture

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

- Interactive diagram: https://gitdiagram.com/bettergovph/open-budget-data
- Repository: https://github.com/bettergovph/open-budget-data

## Overview

This repository converts Philippine NEP/GAA budget records and UACS reference data into JSON, then loads the data into Neo4j for budget and hierarchy analysis. The workflow spans source conversion, dimension data, graph synchronization, and post-sync validation. Converter output paths and several sync operations are visible in excerpts; broader pipeline and data-model relationships are documented in the README, while unsampled sync details are not inferred.

Main entry points: [`sync.py`](https://github.com/bettergovph/open-budget-data/blob/main/sync.py) (Neo4j synchronizer), [`data/budget`](https://github.com/bettergovph/open-budget-data/tree/main/data/budget) (Budget records), [`scripts/nep-gaa/converter.py`](https://github.com/bettergovph/open-budget-data/blob/main/scripts/nep-gaa/converter.py) (Budget converter), [`scripts/nep-gaa-excel/converter.py`](https://github.com/bettergovph/open-budget-data/blob/main/scripts/nep-gaa-excel/converter.py) (Excel import)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_conversion["Data conversion"]
  node_budget_converter["Budget converter<br/>[converter.py]"]
  node_excel_converter["Excel import<br/>[converter.py]"]
end

subgraph group_reference["Reference dimensions"]
  node_funding_converter["Funding converter<br/>[converter.py]"]
  node_location_converter["Location converter<br/>[converter.py]"]
  node_pap_converter["PAP converter<br/>[converter.py]"]
  node_object_analyzer["Object-code analysis<br/>[analyze.py]"]
  node_org_converter["Organization converter<br/>[converter.py]"]
end

subgraph group_outputs["Converted datasets"]
  node_budget_data["Budget records"]
  node_funding_data["Funding data"]
  node_location_data["Location data"]
  node_pap_data["PAP data"]
  node_object_data["Object codes"]
  node_org_data["Organization data"]
end

subgraph group_graph["Graph database"]
  node_sync["Neo4j synchronizer<br/>[sync.py]"]
  node_neo4j[("Neo4j graph")]
  node_validator["Graph validator<br/>[validator.py]"]
end

node_user(("Data operator"))

node_user -->|"runs"| node_budget_converter
node_budget_converter -->|"writes records"| node_budget_data
node_user -->|"runs"| node_excel_converter
node_excel_converter -.->|"exports JSON"| node_budget_data
node_user -->|"runs"| node_funding_converter
node_funding_converter -->|"writes data"| node_funding_data
node_user -->|"runs"| node_location_converter
node_location_converter -->|"writes data"| node_location_data
node_user -->|"runs"| node_pap_converter
node_pap_converter -->|"writes data"| node_pap_data
node_user -->|"runs"| node_object_analyzer
node_user -->|"runs"| node_org_converter
node_org_converter -->|"writes data"| node_org_data
node_user -->|"starts sync"| node_sync
node_budget_data -->|"loads records"| node_sync
node_funding_data -->|"loads data"| node_sync
node_location_data -->|"loads data"| node_sync
node_pap_data -.->|"loads data"| node_sync
node_object_data -.->|"loads data"| node_sync
node_org_data -->|"loads data"| node_sync
node_sync -->|"writes graph"| node_neo4j
node_user -->|"runs checks"| node_validator
node_validator -->|"queries graph"| node_neo4j

click node_budget_converter "https://github.com/bettergovph/open-budget-data/blob/main/scripts/nep-gaa/converter.py"
click node_excel_converter "https://github.com/bettergovph/open-budget-data/blob/main/scripts/nep-gaa-excel/converter.py"
click node_funding_converter "https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/funding-source/converter.py"
click node_location_converter "https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/location/converter.py"
click node_pap_converter "https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/mfo-pap/converter.py"
click node_object_analyzer "https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/object-code/analyze.py"
click node_org_converter "https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/organization/converter.py"
click node_budget_data "https://github.com/bettergovph/open-budget-data/tree/main/data/budget"
click node_funding_data "https://github.com/bettergovph/open-budget-data/tree/main/data/funding_source"
click node_location_data "https://github.com/bettergovph/open-budget-data/tree/main/data/location"
click node_pap_data "https://github.com/bettergovph/open-budget-data/tree/main/data/pap"
click node_object_data "https://github.com/bettergovph/open-budget-data/tree/main/data/object_code"
click node_org_data "https://github.com/bettergovph/open-budget-data/tree/main/data/organization"
click node_sync "https://github.com/bettergovph/open-budget-data/blob/main/sync.py"
click node_validator "https://github.com/bettergovph/open-budget-data/blob/main/validator.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_budget_converter,node_excel_converter toneBlue
class node_funding_converter,node_location_converter,node_pap_converter,node_object_analyzer,node_org_converter toneAmber
class node_budget_data,node_funding_data,node_location_data,node_pap_data,node_object_data,node_org_data toneMint
class node_sync,node_neo4j,node_validator toneRose
class node_user toneIndigo
```

## Components

### Data conversion

- [Budget converter](https://github.com/bettergovph/open-budget-data/blob/main/scripts/nep-gaa/converter.py): `scripts/nep-gaa/converter.py`
- [Excel import](https://github.com/bettergovph/open-budget-data/blob/main/scripts/nep-gaa-excel/converter.py): `scripts/nep-gaa-excel/converter.py`

### Reference dimensions

- [Funding converter](https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/funding-source/converter.py): `scripts/uacs/funding-source/converter.py`
- [Location converter](https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/location/converter.py): `scripts/uacs/location/converter.py`
- [PAP converter](https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/mfo-pap/converter.py): `scripts/uacs/mfo-pap/converter.py`
- [Object-code analysis](https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/object-code/analyze.py): `scripts/uacs/object-code/analyze.py`
- [Organization converter](https://github.com/bettergovph/open-budget-data/blob/main/scripts/uacs/organization/converter.py): `scripts/uacs/organization/converter.py`

### Converted datasets

- [Budget records](https://github.com/bettergovph/open-budget-data/tree/main/data/budget): `data/budget`
- [Funding data](https://github.com/bettergovph/open-budget-data/tree/main/data/funding_source): `data/funding_source`
- [Location data](https://github.com/bettergovph/open-budget-data/tree/main/data/location): `data/location`
- [PAP data](https://github.com/bettergovph/open-budget-data/tree/main/data/pap): `data/pap`
- [Object codes](https://github.com/bettergovph/open-budget-data/tree/main/data/object_code): `data/object_code`
- [Organization data](https://github.com/bettergovph/open-budget-data/tree/main/data/organization): `data/organization`

### Graph database

- [Neo4j synchronizer](https://github.com/bettergovph/open-budget-data/blob/main/sync.py): `sync.py`
- **Neo4j graph**
- [Graph validator](https://github.com/bettergovph/open-budget-data/blob/main/validator.py): `validator.py`

### Other components

- **Data operator**

## Connections

- Data operator → Budget converter: runs (evidence: `scripts/nep-gaa/converter.py`)
- Budget converter → Budget records: writes records (evidence: `scripts/nep-gaa/converter.py`)
- Data operator → Excel import: runs (evidence: `scripts/nep-gaa-excel/converter.py`)
- Excel import → Budget records: exports JSON
- Data operator → Funding converter: runs (evidence: `scripts/uacs/funding-source/converter.py`)
- Funding converter → Funding data: writes data (evidence: `scripts/uacs/funding-source/converter.py`)
- Data operator → Location converter: runs (evidence: `scripts/uacs/location/converter.py`)
- Location converter → Location data: writes data (evidence: `scripts/uacs/location/converter.py`)
- Data operator → PAP converter: runs (evidence: `scripts/uacs/mfo-pap/converter.py`)
- PAP converter → PAP data: writes data (evidence: `README.md`)
- Data operator → Object-code analysis: runs (evidence: `scripts/uacs/object-code/analyze.py`)
- Data operator → Organization converter: runs (evidence: `scripts/uacs/organization/converter.py`)
- Organization converter → Organization data: writes data (evidence: `scripts/uacs/organization/converter.py`)
- Data operator → Neo4j synchronizer: starts sync (evidence: `sync.py`)
- Budget records → Neo4j synchronizer: loads records (evidence: `README.md`)
- Funding data → Neo4j synchronizer: loads data (evidence: `sync.py`)
- Location data → Neo4j synchronizer: loads data (evidence: `README.md`)
- PAP data → Neo4j synchronizer: loads data
- Object codes → Neo4j synchronizer: loads data
- Organization data → Neo4j synchronizer: loads data (evidence: `sync.py`)
- Neo4j synchronizer → Neo4j graph: writes graph (evidence: `sync.py`)
- Data operator → Graph validator: runs checks (evidence: `validator.py`)
- Graph validator → Neo4j graph: queries graph (evidence: `validator.py`)
