# purpurbc/company-intel architecture

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

- Interactive diagram: https://gitdiagram.com/purpurbc/company-intel
- Repository: https://github.com/purpurbc/company-intel

## Overview

Cintela is a Swedish company-data product: official SCB and Bolagsverket inputs are imported into PostgreSQL, exposed through a FastAPI service, and explored in a Next.js interface. The main user journey is company search and filtering through company history/details or geographic and national market overviews; profiles and saved segments support reuse. The README documents resumable imports and cache refresh behavior. Source excerpts confirm API startup/router registration and database-backed services, but not most endpoint-to-service or importer call wiring, so those links are omitted.

Main entry points: [`web/src/lib/api.ts`](https://github.com/purpurbc/company-intel/blob/master/web/src/lib/api.ts) (API client), [`api/main.py`](https://github.com/purpurbc/company-intel/blob/master/api/main.py) (API application), [`api/database.py`](https://github.com/purpurbc/company-intel/blob/master/api/database.py) (API connections), [`worker/ingest/repository.py`](https://github.com/purpurbc/company-intel/blob/master/worker/ingest/repository.py) (Company resolution)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web experience"]
  node_company_ui["Company search<br/>[page.tsx]"]
  node_company_detail["Company detail<br/>[page.tsx]"]
  node_geo_ui["Geographic views<br/>[page.tsx]"]
  node_county_ui["County overview<br/>[page.tsx]"]
  node_sweden_ui["Sweden overview<br/>[page.tsx]"]
  node_profile_ui["Saved segments<br/>[page.tsx]"]
  node_web_api["API client<br/>[api.ts]"]
end

subgraph group_api["API and services"]
  node_api_app["API application<br/>[main.py]"]
  node_company_routes["Company routes<br/>[companies.py]"]
  node_geo_routes["Geography routes<br/>[counties.py]"]
  node_sweden_routes["Sweden routes<br/>[sweden.py]"]
  node_profile_routes["Profile routes<br/>[profile.py]"]
  node_company_service["Company search<br/>[company_service.py]"]
  node_geo_service["County analytics<br/>[county_service.py]"]
  node_database_api["API connections<br/>[database.py]"]
end

subgraph group_ingest["Data ingestion"]
  node_scb_import["SCB imports"]
  node_scb_client["SCB client<br/>[scb_base_client.py]"]
  node_bulk_import["Bulk imports<br/>[importer.py]"]
  node_bv_stats["Statistics import<br/>[importer.py]"]
  node_ingest_merge["Company resolution<br/>[repository.py]"]
  node_stats_repo["Statistics persistence<br/>[repository.py]"]
  node_worker_db["Worker connections<br/>[database.py]"]
end

subgraph group_store["Data storage"]
  node_postgres[("PostgreSQL")]
end

node_user(("Analyst"))
node_scb["SCB"]
node_bolagsverket["Bolagsverket"]

node_user -->|"searches"| node_company_ui
node_user -->|"explores"| node_geo_ui
node_user -->|"reviews"| node_sweden_ui
node_user -->|"manages"| node_profile_ui
node_company_ui -->|"requests"| node_web_api
node_company_detail -->|"requests"| node_web_api
node_geo_ui -->|"requests"| node_web_api
node_county_ui -->|"requests"| node_web_api
node_sweden_ui -->|"requests"| node_web_api
node_profile_ui -->|"requests"| node_web_api
node_web_api -->|"calls"| node_api_app
node_api_app -->|"dispatches"| node_company_routes
node_api_app -->|"dispatches"| node_geo_routes
node_api_app -->|"dispatches"| node_sweden_routes
node_api_app -->|"dispatches"| node_profile_routes
node_company_service -->|"queries"| node_database_api
node_geo_service -->|"queries"| node_database_api
node_database_api -->|"reads"| node_postgres
node_scb -.->|"supplies data"| node_scb_client
node_scb_client -->|"serves requests"| node_scb_import
node_scb_import -->|"imports records"| node_ingest_merge
node_bolagsverket -.->|"supplies files"| node_bulk_import
node_bolagsverket -.->|"supplies files"| node_bv_stats
node_bulk_import -->|"imports records"| node_ingest_merge
node_ingest_merge -->|"persists"| node_worker_db
node_bv_stats -->|"stores snapshots"| node_stats_repo
node_stats_repo -->|"uses connection"| node_worker_db
node_worker_db -->|"writes"| node_postgres

click node_company_ui "https://github.com/purpurbc/company-intel/blob/master/web/src/app/companies/page.tsx"
click node_company_detail "https://github.com/purpurbc/company-intel/blob/master/web/src/app/company/%5Borg_nr%5D/page.tsx"
click node_geo_ui "https://github.com/purpurbc/company-intel/blob/master/web/src/app/geography/page.tsx"
click node_county_ui "https://github.com/purpurbc/company-intel/blob/master/web/src/app/county/%5Bcounty_code%5D/page.tsx"
click node_sweden_ui "https://github.com/purpurbc/company-intel/blob/master/web/src/app/sweden/page.tsx"
click node_profile_ui "https://github.com/purpurbc/company-intel/blob/master/web/src/app/profile/page.tsx"
click node_web_api "https://github.com/purpurbc/company-intel/blob/master/web/src/lib/api.ts"
click node_api_app "https://github.com/purpurbc/company-intel/blob/master/api/main.py"
click node_company_routes "https://github.com/purpurbc/company-intel/blob/master/api/routers/companies.py"
click node_geo_routes "https://github.com/purpurbc/company-intel/blob/master/api/routers/counties.py"
click node_sweden_routes "https://github.com/purpurbc/company-intel/blob/master/api/routers/sweden.py"
click node_profile_routes "https://github.com/purpurbc/company-intel/blob/master/api/routers/profile.py"
click node_company_service "https://github.com/purpurbc/company-intel/blob/master/api/services/company_service.py"
click node_geo_service "https://github.com/purpurbc/company-intel/blob/master/api/services/county_service.py"
click node_database_api "https://github.com/purpurbc/company-intel/blob/master/api/database.py"
click node_scb_import "https://github.com/purpurbc/company-intel/blob/master/worker/scb/company_importer.py"
click node_scb_client "https://github.com/purpurbc/company-intel/blob/master/worker/scb/scb_base_client.py"
click node_bulk_import "https://github.com/purpurbc/company-intel/blob/master/worker/bulk_files/importer.py"
click node_bv_stats "https://github.com/purpurbc/company-intel/blob/master/worker/bolagsverket_statistics/importer.py"
click node_ingest_merge "https://github.com/purpurbc/company-intel/blob/master/worker/ingest/repository.py"
click node_stats_repo "https://github.com/purpurbc/company-intel/blob/master/worker/bolagsverket_statistics/repository.py"
click node_worker_db "https://github.com/purpurbc/company-intel/blob/master/worker/database.py"
click node_postgres "https://github.com/purpurbc/company-intel/tree/master/db"

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_company_ui,node_company_detail,node_geo_ui,node_county_ui,node_sweden_ui,node_profile_ui,node_web_api toneBlue
class node_api_app,node_company_routes,node_geo_routes,node_sweden_routes,node_profile_routes,node_company_service,node_geo_service,node_database_api toneAmber
class node_scb_import,node_scb_client,node_bulk_import,node_bv_stats,node_ingest_merge,node_stats_repo,node_worker_db toneMint
class node_postgres toneRose
class node_user,node_scb,node_bolagsverket toneIndigo
```

## Components

### Web experience

- [Company search](https://github.com/purpurbc/company-intel/blob/master/web/src/app/companies/page.tsx): `web/src/app/companies/page.tsx`
- [Company detail](https://github.com/purpurbc/company-intel/blob/master/web/src/app/company/%5Borg_nr%5D/page.tsx): `web/src/app/company/[org_nr]/page.tsx`
- [Geographic views](https://github.com/purpurbc/company-intel/blob/master/web/src/app/geography/page.tsx): `web/src/app/geography/page.tsx`
- [County overview](https://github.com/purpurbc/company-intel/blob/master/web/src/app/county/%5Bcounty_code%5D/page.tsx): `web/src/app/county/[county_code]/page.tsx`
- [Sweden overview](https://github.com/purpurbc/company-intel/blob/master/web/src/app/sweden/page.tsx): `web/src/app/sweden/page.tsx`
- [Saved segments](https://github.com/purpurbc/company-intel/blob/master/web/src/app/profile/page.tsx): `web/src/app/profile/page.tsx`
- [API client](https://github.com/purpurbc/company-intel/blob/master/web/src/lib/api.ts): `web/src/lib/api.ts`

### API and services

- [API application](https://github.com/purpurbc/company-intel/blob/master/api/main.py): `api/main.py`
- [Company routes](https://github.com/purpurbc/company-intel/blob/master/api/routers/companies.py): `api/routers/companies.py`
- [Geography routes](https://github.com/purpurbc/company-intel/blob/master/api/routers/counties.py): `api/routers/counties.py`
- [Sweden routes](https://github.com/purpurbc/company-intel/blob/master/api/routers/sweden.py): `api/routers/sweden.py`
- [Profile routes](https://github.com/purpurbc/company-intel/blob/master/api/routers/profile.py): `api/routers/profile.py`
- [Company search](https://github.com/purpurbc/company-intel/blob/master/api/services/company_service.py): `api/services/company_service.py`
- [County analytics](https://github.com/purpurbc/company-intel/blob/master/api/services/county_service.py): `api/services/county_service.py`
- [API connections](https://github.com/purpurbc/company-intel/blob/master/api/database.py): `api/database.py`

### Data ingestion

- [SCB imports](https://github.com/purpurbc/company-intel/blob/master/worker/scb/company_importer.py): `worker/scb/company_importer.py`
- [SCB client](https://github.com/purpurbc/company-intel/blob/master/worker/scb/scb_base_client.py): `worker/scb/scb_base_client.py`
- [Bulk imports](https://github.com/purpurbc/company-intel/blob/master/worker/bulk_files/importer.py): `worker/bulk_files/importer.py`
- [Statistics import](https://github.com/purpurbc/company-intel/blob/master/worker/bolagsverket_statistics/importer.py): `worker/bolagsverket_statistics/importer.py`
- [Company resolution](https://github.com/purpurbc/company-intel/blob/master/worker/ingest/repository.py): `worker/ingest/repository.py`
- [Statistics persistence](https://github.com/purpurbc/company-intel/blob/master/worker/bolagsverket_statistics/repository.py): `worker/bolagsverket_statistics/repository.py`
- [Worker connections](https://github.com/purpurbc/company-intel/blob/master/worker/database.py): `worker/database.py`

### Data storage

- [PostgreSQL](https://github.com/purpurbc/company-intel/tree/master/db): `db`

### Other components

- **Analyst**
- **SCB**
- **Bolagsverket**

## Connections

- Analyst → Company search: searches
- Analyst → Geographic views: explores
- Analyst → Sweden overview: reviews
- Analyst → Saved segments: manages
- Company search → API client: requests
- Company detail → API client: requests
- Geographic views → API client: requests
- County overview → API client: requests
- Sweden overview → API client: requests
- Saved segments → API client: requests
- API client → API application: calls
- API application → Company routes: dispatches
- API application → Geography routes: dispatches
- API application → Sweden routes: dispatches
- API application → Profile routes: dispatches
- Company search → API connections: queries
- County analytics → API connections: queries
- API connections → PostgreSQL: reads
- SCB → SCB client: supplies data
- SCB client → SCB imports: serves requests
- SCB imports → Company resolution: imports records
- Bolagsverket → Bulk imports: supplies files
- Bolagsverket → Statistics import: supplies files
- Bulk imports → Company resolution: imports records
- Company resolution → Worker connections: persists
- Statistics import → Statistics persistence: stores snapshots
- Statistics persistence → Worker connections: uses connection
- Worker connections → PostgreSQL: writes
