# wrocoder/hoptrip architecture

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

## Overview

HopTrip is a Poland-first flight-deal discovery product: cached provider prices are ingested and converted into persistent offers and price history, then route statistics and scored deals support a public browsing and affiliate-redirect journey. The API also exposes analytics and protected moderation/affiliate operations. The sampled pipeline and ingestion code establish the data stages; the README documents the broader public, affiliate-policy, session-analytics and moderation capabilities. Several API routes and web pages were not sampled, so their detailed wiring is represented only where the tree or documentation supports it.

Main entry points: [`apps/api/app/jobs/pipeline.py`](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/jobs/pipeline.py) (Ingestion pipeline), [`apps/api/app/main.py`](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/main.py) (API application), [`apps/web/src/app`](https://github.com/wrocoder/hoptrip/tree/master/apps/web/src/app) (Web experience), [`apps/web/src/app/page.tsx`](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/page.tsx) (Home discovery)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_public["Public discovery"]
  node_web["Web experience"]
  node_home["Home discovery<br/>[page.tsx]"]
  node_webapi["Web API client<br/>[api.ts]"]
  node_catalogui["Deal catalog<br/>[catalog.tsx]"]
  node_routeguides["Route guides"]
  node_outbound["Outbound links<br/>[outbound.tsx]"]
end

subgraph group_api["API and operations"]
  node_apiapp["API application<br/>[main.py]"]
  node_catalogapi["Catalog API<br/>[catalog.py]"]
  node_adminapi["Admin operations<br/>[admin.py]"]
end

subgraph group_data["Deal data pipeline"]
  node_jobs["Job orchestration"]
  node_pipeline["Ingestion pipeline<br/>[pipeline.py]"]
  node_provider["Travelpayouts adapter<br/>[travelpayouts.py]"]
  node_ingestion["Offer ingestion<br/>[ingestion.py]"]
  node_dealservices["Deal generation<br/>[deals.py]"]
  node_statistics["Route statistics<br/>[statistics.py]"]
end

subgraph group_affiliate["Affiliate and analytics"]
  node_affiliateapi["Affiliate API<br/>[affiliate.py]"]
  node_analyticsapi["Analytics API<br/>[analytics.py]"]
  node_partnerlinks["Partner link sync<br/>[partner_links.py]"]
  node_affiliatepolicy["Affiliate policy<br/>[affiliate.py]"]
  node_sessionanalytics["Session analytics<br/>[session.ts]"]
end

node_traveler(("Traveler"))
node_database[("PostgreSQL")]
node_providerexternal(("Travelpayouts"))
node_analyticsstore[("Analytics records<br/>[analytics.py]")]

node_traveler -->|"browses"| node_web
node_web -->|"renders"| node_home
node_home -->|"requests data"| node_webapi
node_webapi -->|"calls API"| node_apiapp
node_home -->|"shows deals"| node_catalogui
node_web -->|"presents guides"| node_routeguides
node_catalogui -->|"opens offer"| node_outbound
node_outbound -->|"requests redirect"| node_affiliateapi
node_apiapp -->|"dispatches"| node_catalogapi
node_apiapp -->|"dispatches"| node_affiliateapi
node_apiapp -->|"dispatches"| node_analyticsapi
node_apiapp -->|"dispatches"| node_adminapi
node_sessionanalytics -->|"posts events"| node_analyticsapi
node_analyticsapi -->|"records events"| node_analyticsstore
node_adminapi -->|"checks policy"| node_affiliatepolicy
node_adminapi -->|"reads and writes"| node_database
node_jobs -->|"runs pipeline"| node_pipeline
node_pipeline -->|"searches offers"| node_provider
node_provider -->|"fetches cached prices"| node_providerexternal
node_pipeline -->|"ingests offers"| node_ingestion
node_ingestion -->|"writes offers"| node_database
node_pipeline -->|"recalculates routes"| node_statistics
node_statistics -->|"reads and writes"| node_database
node_pipeline -->|"generates deals"| node_dealservices
node_dealservices -->|"reads and writes"| node_database
node_pipeline -->|"syncs links"| node_partnerlinks
node_partnerlinks -->|"reads and writes"| node_database
node_webapi -->|"requests catalog"| node_catalogapi
node_affiliateapi -->|"applies policy"| node_affiliatepolicy
node_catalogapi -->|"reads catalog"| node_database

click node_web "https://github.com/wrocoder/hoptrip/tree/master/apps/web/src/app"
click node_home "https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/page.tsx"
click node_webapi "https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/lib/api.ts"
click node_catalogui "https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/components/catalog.tsx"
click node_routeguides "https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/lib/destination-guides.ts"
click node_outbound "https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/components/outbound.tsx"
click node_apiapp "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/main.py"
click node_catalogapi "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/catalog.py"
click node_affiliateapi "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/affiliate.py"
click node_analyticsapi "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/analytics.py"
click node_adminapi "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/admin.py"
click node_jobs "https://github.com/wrocoder/hoptrip/tree/master/apps/api/app/jobs"
click node_pipeline "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/jobs/pipeline.py"
click node_provider "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/providers/travelpayouts.py"
click node_partnerlinks "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/partner_links.py"
click node_ingestion "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/ingestion.py"
click node_dealservices "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/deals.py"
click node_statistics "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/statistics.py"
click node_affiliatepolicy "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/affiliate.py"
click node_sessionanalytics "https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/lib/session.ts"
click node_analyticsstore "https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/models/analytics.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_web,node_home,node_webapi,node_catalogui,node_routeguides,node_outbound toneBlue
class node_apiapp,node_catalogapi,node_adminapi,node_database,node_analyticsstore toneAmber
class node_jobs,node_pipeline,node_provider,node_ingestion,node_dealservices,node_statistics toneMint
class node_affiliateapi,node_analyticsapi,node_partnerlinks,node_affiliatepolicy,node_sessionanalytics toneRose
class node_traveler,node_providerexternal toneIndigo
```

## Components

### Public discovery

- [Web experience](https://github.com/wrocoder/hoptrip/tree/master/apps/web/src/app): `apps/web/src/app`
- [Home discovery](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/page.tsx): `apps/web/src/app/page.tsx`
- [Web API client](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/lib/api.ts): `apps/web/src/lib/api.ts`
- [Deal catalog](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/components/catalog.tsx): `apps/web/src/app/components/catalog.tsx`
- [Route guides](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/lib/destination-guides.ts): `apps/web/src/lib/destination-guides.ts`
- [Outbound links](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/app/components/outbound.tsx): `apps/web/src/app/components/outbound.tsx`

### API and operations

- [API application](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/main.py): `apps/api/app/main.py`
- [Catalog API](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/catalog.py): `apps/api/app/api/catalog.py`
- [Admin operations](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/admin.py): `apps/api/app/api/admin.py`

### Deal data pipeline

- [Job orchestration](https://github.com/wrocoder/hoptrip/tree/master/apps/api/app/jobs): `apps/api/app/jobs`
- [Ingestion pipeline](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/jobs/pipeline.py): `apps/api/app/jobs/pipeline.py`
- [Travelpayouts adapter](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/providers/travelpayouts.py): `apps/api/app/providers/travelpayouts.py`
- [Offer ingestion](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/ingestion.py): `apps/api/app/services/ingestion.py`
- [Deal generation](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/deals.py): `apps/api/app/services/deals.py`
- [Route statistics](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/statistics.py): `apps/api/app/services/statistics.py`

### Affiliate and analytics

- [Affiliate API](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/affiliate.py): `apps/api/app/api/affiliate.py`
- [Analytics API](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/api/analytics.py): `apps/api/app/api/analytics.py`
- [Partner link sync](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/partner_links.py): `apps/api/app/services/partner_links.py`
- [Affiliate policy](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/services/affiliate.py): `apps/api/app/services/affiliate.py`
- [Session analytics](https://github.com/wrocoder/hoptrip/blob/master/apps/web/src/lib/session.ts): `apps/web/src/lib/session.ts`

### Other components

- **Traveler**
- **PostgreSQL**
- **Travelpayouts**
- [Analytics records](https://github.com/wrocoder/hoptrip/blob/master/apps/api/app/models/analytics.py): `apps/api/app/models/analytics.py`

## Connections

- Traveler → Web experience: browses
- Web experience → Home discovery: renders
- Home discovery → Web API client: requests data
- Web API client → API application: calls API
- Home discovery → Deal catalog: shows deals
- Web experience → Route guides: presents guides
- Deal catalog → Outbound links: opens offer
- Outbound links → Affiliate API: requests redirect
- API application → Catalog API: dispatches
- API application → Affiliate API: dispatches
- API application → Analytics API: dispatches
- API application → Admin operations: dispatches
- Session analytics → Analytics API: posts events
- Analytics API → Analytics records: records events
- Admin operations → Affiliate policy: checks policy
- Admin operations → PostgreSQL: reads and writes
- Job orchestration → Ingestion pipeline: runs pipeline
- Ingestion pipeline → Travelpayouts adapter: searches offers
- Travelpayouts adapter → Travelpayouts: fetches cached prices
- Ingestion pipeline → Offer ingestion: ingests offers
- Offer ingestion → PostgreSQL: writes offers
- Ingestion pipeline → Route statistics: recalculates routes
- Route statistics → PostgreSQL: reads and writes
- Ingestion pipeline → Deal generation: generates deals
- Deal generation → PostgreSQL: reads and writes
- Ingestion pipeline → Partner link sync: syncs links
- Partner link sync → PostgreSQL: reads and writes
- Web API client → Catalog API: requests catalog
- Affiliate API → Affiliate policy: applies policy
- Catalog API → PostgreSQL: reads catalog
