# hi-day/multi_tower architecture

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

- Interactive diagram: https://gitdiagram.com/hi-day/multi_tower
- Repository: https://github.com/hi-day/multi_tower

## Overview

#### Purpose and entry points
Multi-Tower is a Python 3.12 event recommendation engine intended to learn user and event representations and return top-N recommendations. It exposes both online and offline-facing interface shells:
- FastAPI application: `src/multi_tower/interfaces/api/main.py`
- CLI application: `src/multi_tower/interfaces/cli/main.py`
- Standalone inference/proof-of-concept scripts: `infer.py`, `poc_multi_tower.py`

#### Architectural style
The repository follows Clean Architecture with dependency direction from interfaces and infrastructure toward application/domain. The domain is intended to remain framework-independent; application defines orchestration contracts; infrastructure supplies model and storage implementations; interfaces adapt requests/commands.
- Domain boundary: `src/multi_tower/domain/entities`, `src/multi_tower/domain/repositories`
- Application boundary: `src/multi_tower/application/use_cases`, `src/multi_tower/application/ports`
- Adapters: `src/multi_tower/infrastructure`, `src/multi_tower/interfaces`

#### Data ingestion and quality gate
Raw recommendation inputs are maintained as bronze CSV data: student profiles, majors, events, and interactions. The data module loads, validates, schemas, and constants before downstream training/inference should consume records.
- Source data: `data/bronze/student_profile.csv`, `data/bronze/event_master.csv`, `data/bronze/interaction.csv`
- Data pipeline components: `src/multi_tower/data/loader.py`, `src/multi_tower/data/validator.py`, `src/multi_tower/data/schemas.py`
- Synthetic-data path: `scripts/generate_dummy_data.py`, `src/multi_tower/data/generator.py`

#### Domain and application orchestration
Core business concepts are Users, Events, and Interactions, represented through entities/value objects and abstract repository contracts. Application use cases coordinate these concepts through DTOs and ports rather than directly coupling API or model code to storage.
- Domain model locations: `src/multi_tower/domain/entities`, `src/multi_tower/domain/value_objects`
- Repository abstractions: `src/multi_tower/domain/repositories`
- Use-case and boundary definitions: `src/multi_tower/application/use_cases`, `src/multi_tower/application/dtos`, `src/multi_tower/application/ports`

#### Recommendation/model infrastructure
The intended model is a PyTorch multi-tower network: separate learned representations for users and events are jointly used for relevance scoring/ranking. Infrastructure owns concrete ML and persistence concerns and should implement application-defined ports, keeping model lifecycle out of interfaces.
- Model boundary: `src/multi_tower/infrastructure/model`
- Persistence boundary: `src/multi_tower/infrastructure/persistence`
- Prototype model implementation: `poc_multi_tower.py`
- Inference invocation: `infer.py`

#### Serving and execution flow
For online serving, requests enter FastAPI routes, are validated by API schemas, dispatched to application use cases, then resolved through infrastructure implementations to retrieve data and score/rank events. The CLI provides a parallel non-HTTP entry point for offline evaluation or operations.
- API composition: `src/multi_tower/interfaces/api/main.py`, `src/multi_tower/interfaces/api/routes`
- API request/response boundary: `src/multi_tower/interfaces/api/schemas`
- Offline command entry: `src/multi_tower/interfaces/cli/main.py`

#### Material runtime and storage choices
The runtime is Python with PyTorch for neural recommendation and Polars-oriented data handling, especially Parquet-capable persistence at scale. Configuration is expected through environment variables and Pydantic Settings; `.env.example` documents the environment boundary. No deployed cloud, database, queue, or external recommendation service is represented in the repository tree.
- Environment template: `.env.example`
- Package/runtime declaration: `pyproject.toml`
- Data/persistence implementation area: `src/multi_tower/infrastructure/persistence`

Main entry points: [`src/multi_tower/application/use_cases`](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/application/use_cases) (Recommendation use cases), [`src/multi_tower/data/loader.py`](https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/loader.py) (Data loader), [`src/multi_tower/infrastructure/model`](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/infrastructure/model) (Multi-tower model), [`src/multi_tower/interfaces/api/routes`](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/interfaces/api/routes) (API routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Entry points"]
  node_api["FastAPI app<br/>HTTP entry<br/>[main.py]"]
  node_routes["API routes<br/>route adapters"]
  node_api_schemas["API schemas<br/>request/response DTOs"]
  node_cli["CLI app<br/>command entry<br/>[main.py]"]
  node_inference["Inference script<br/>standalone inference<br/>[infer.py]"]
end

subgraph group_data["Data quality pipeline"]
  node_bronze_profiles["Student profiles<br/>bronze CSV"]
  node_bronze_events["Event catalog<br/>bronze CSV<br/>[event_master.csv]"]
  node_bronze_interactions["Interactions<br/>bronze CSV<br/>[interaction.csv]"]
  node_data_loader["Data loader<br/>ingestion<br/>[loader.py]"]
  node_validation["Validation &amp; schemas<br/>quality gate<br/>[validator.py]"]
  node_generator["Synthetic data generator<br/>data generation<br/>[generator.py]"]
end

subgraph group_core["Clean Architecture core"]
  node_domain["Users, events &amp; interactions<br/>domain entities"]
  node_repositories["Repository contracts<br/>domain abstractions"]
  node_use_cases{{"Recommendation use cases<br/>application orchestration"}}
  node_ports["Application ports<br/>implementation contracts"]
end

subgraph group_infra["Infrastructure"]
  node_model["Multi-tower model<br/>PyTorch recommender"]
  node_persistence[("Persistence adapters<br/>data storage")]
  node_prototype["Model prototype<br/>proof of concept<br/>[poc_multi_tower.py]"]
end

node_api -->|"mounts"| node_routes
node_routes -->|"validates with"| node_api_schemas
node_routes -->|"dispatches"| node_use_cases
node_cli -->|"invokes"| node_use_cases
node_use_cases -->|"coordinates"| node_domain
node_use_cases -->|"uses"| node_repositories
node_use_cases -->|"depends on"| node_ports
node_persistence -.->|"implements"| node_repositories
node_model -.->|"implements"| node_ports
node_use_cases -->|"scores and ranks via"| node_model
node_use_cases -->|"retrieves through"| node_persistence
node_bronze_profiles -->|"loads"| node_data_loader
node_bronze_events -->|"loads"| node_data_loader
node_bronze_interactions -->|"loads"| node_data_loader
node_data_loader -->|"records"| node_validation
node_validation -->|"validated data"| node_model
node_generator -->|"produces inputs for"| node_data_loader
node_inference -->|"runs"| node_model
node_prototype -.->|"prototypes"| node_model

click node_api "https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/interfaces/api/main.py"
click node_routes "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/interfaces/api/routes"
click node_api_schemas "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/interfaces/api/schemas"
click node_cli "https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/interfaces/cli/main.py"
click node_bronze_profiles "https://github.com/hi-day/multi_tower/blob/main/data/bronze/student_profile.csv"
click node_bronze_events "https://github.com/hi-day/multi_tower/blob/main/data/bronze/event_master.csv"
click node_bronze_interactions "https://github.com/hi-day/multi_tower/blob/main/data/bronze/interaction.csv"
click node_data_loader "https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/loader.py"
click node_validation "https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/validator.py"
click node_domain "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/domain/entities"
click node_repositories "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/domain/repositories"
click node_use_cases "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/application/use_cases"
click node_ports "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/application/ports"
click node_model "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/infrastructure/model"
click node_persistence "https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/infrastructure/persistence"
click node_inference "https://github.com/hi-day/multi_tower/blob/main/infer.py"
click node_prototype "https://github.com/hi-day/multi_tower/blob/main/poc_multi_tower.py"
click node_generator "https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/generator.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_api,node_routes,node_api_schemas,node_cli,node_inference toneBlue
class node_bronze_profiles,node_bronze_events,node_bronze_interactions,node_data_loader,node_validation,node_generator toneAmber
class node_domain,node_repositories,node_use_cases,node_ports toneMint
class node_model,node_persistence,node_prototype toneRose
```

## Components

### Entry points

- [FastAPI app](https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/interfaces/api/main.py): HTTP entry · `src/multi_tower/interfaces/api/main.py`
- [API routes](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/interfaces/api/routes): route adapters · `src/multi_tower/interfaces/api/routes`
- [API schemas](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/interfaces/api/schemas): request/response DTOs · `src/multi_tower/interfaces/api/schemas`
- [CLI app](https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/interfaces/cli/main.py): command entry · `src/multi_tower/interfaces/cli/main.py`
- [Inference script](https://github.com/hi-day/multi_tower/blob/main/infer.py): standalone inference · `infer.py`

### Data quality pipeline

- [Student profiles](https://github.com/hi-day/multi_tower/blob/main/data/bronze/student_profile.csv): bronze CSV · `data/bronze/student_profile.csv`
- [Event catalog](https://github.com/hi-day/multi_tower/blob/main/data/bronze/event_master.csv): bronze CSV · `data/bronze/event_master.csv`
- [Interactions](https://github.com/hi-day/multi_tower/blob/main/data/bronze/interaction.csv): bronze CSV · `data/bronze/interaction.csv`
- [Data loader](https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/loader.py): ingestion · `src/multi_tower/data/loader.py`
- [Validation & schemas](https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/validator.py): quality gate · Validates loaded recommendation records before model consumption. · `src/multi_tower/data/validator.py`
- [Synthetic data generator](https://github.com/hi-day/multi_tower/blob/main/src/multi_tower/data/generator.py): data generation · `src/multi_tower/data/generator.py`

### Clean Architecture core

- [Users, events & interactions](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/domain/entities): domain entities · `src/multi_tower/domain/entities`
- [Repository contracts](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/domain/repositories): domain abstractions · `src/multi_tower/domain/repositories`
- [Recommendation use cases](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/application/use_cases): application orchestration · `src/multi_tower/application/use_cases`
- [Application ports](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/application/ports): implementation contracts · `src/multi_tower/application/ports`

### Infrastructure

- [Multi-tower model](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/infrastructure/model): PyTorch recommender · Builds user and event representations for scoring and ranking. · `src/multi_tower/infrastructure/model`
- [Persistence adapters](https://github.com/hi-day/multi_tower/tree/main/src/multi_tower/infrastructure/persistence): data storage · Concrete Polars/Parquet-capable data access implementations. · `src/multi_tower/infrastructure/persistence`
- [Model prototype](https://github.com/hi-day/multi_tower/blob/main/poc_multi_tower.py): proof of concept · `poc_multi_tower.py`

## Connections

- FastAPI app → API routes: mounts
- API routes → API schemas: validates with
- API routes → Recommendation use cases: dispatches
- CLI app → Recommendation use cases: invokes
- Recommendation use cases → Users, events & interactions: coordinates
- Recommendation use cases → Repository contracts: uses
- Recommendation use cases → Application ports: depends on
- Persistence adapters → Repository contracts: implements
- Multi-tower model → Application ports: implements
- Recommendation use cases → Multi-tower model: scores and ranks via
- Recommendation use cases → Persistence adapters: retrieves through
- Student profiles → Data loader: loads
- Event catalog → Data loader: loads
- Interactions → Data loader: loads
- Data loader → Validation & schemas: records
- Validation & schemas → Multi-tower model: validated data
- Synthetic data generator → Data loader: produces inputs for
- Inference script → Multi-tower model: runs
- Model prototype → Multi-tower model: prototypes
