# psycopathic/gurukul-api architecture

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

- Interactive diagram: https://gitdiagram.com/psycopathic/gurukul-api
- Repository: https://github.com/psycopathic/gurukul-api

## Overview

Gurukul Video API gates playback requests, verifies app attestation and Firebase identity, checks the video catalog and access rule, then returns a short-lived R2 download URL. Operators have a separate authenticated upload-URL endpoint. The graph also captures configuration, Firebase verification, rate limiting, and structured logging. Relationships are limited to calls and routing shown in excerpts or documented in the README; unsampled implementation details are not inferred.

Main entry points: [`src/routes/video.routes.ts`](https://github.com/psycopathic/gurukul-api/blob/main/src/routes/video.routes.ts) (Video Routes), [`src/services/playback.service.ts`](https://github.com/psycopathic/gurukul-api/blob/main/src/services/playback.service.ts) (Playback Orchestrator), [`src/app.ts`](https://github.com/psycopathic/gurukul-api/blob/main/src/app.ts) (Express App), [`src/services/r2.service.ts`](https://github.com/psycopathic/gurukul-api/blob/main/src/services/r2.service.ts) (R2 URL Signer)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["HTTP API"]
  node_app["Express App<br/>[app.ts]"]
  node_routes["Video Routes<br/>[video.routes.ts]"]
  node_controller["Video Controller"]
end

subgraph group_security["Request Security"]
  node_appcheck_mw["App Check Gate"]
  node_appcheck["App Check Verifier"]
  node_auth_mw["User and Operator Auth<br/>[auth.middleware.ts]"]
  node_firebase["Firebase Admin"]
  node_rate["Playback Rate Limit"]
end

subgraph group_playback["Playback Access"]
  node_playback["Playback Orchestrator"]
  node_catalog_service["Catalog Lookup<br/>[catalog.service.ts]"]
  node_catalog["Video Catalog<br/>[video-catalog.ts]"]
  node_entitlement["Access Rules"]
end

subgraph group_storage["R2 Storage"]
  node_video_service["Upload URL Service<br/>[video.service.ts]"]
  node_r2["R2 URL Signer<br/>[r2.service.ts]"]
  node_r2store[("Cloudflare R2")]
end

subgraph group_operations["Configuration and Observability"]
  node_env["Environment Config<br/>[env.ts]"]
  node_buckets["Bucket Registry<br/>[buckets.ts]"]
  node_logger["Structured Logger<br/>[logger.ts]"]
  node_errors["HTTP Errors<br/>[errors.ts]"]
end

node_client(("Flutter App"))
node_operator(("API Operator"))

node_client -->|"HTTP requests"| node_app
node_operator -->|"upload request"| node_app
node_app -->|"mounts routes"| node_routes
node_routes -->|"gates playback"| node_appcheck_mw
node_routes -->|"authenticates"| node_auth_mw
node_routes -->|"limits playback"| node_rate
node_routes -->|"dispatches"| node_controller
node_appcheck_mw -->|"verifies token"| node_appcheck
node_auth_mw -->|"verifies identity"| node_firebase
node_auth_mw -->|"checks operator token"| node_env
node_controller -->|"requests access"| node_playback
node_controller -->|"prepares upload"| node_video_service
node_playback -->|"looks up video"| node_catalog_service
node_catalog_service -->|"reads entries"| node_catalog
node_playback -->|"checks authorization"| node_entitlement
node_playback -->|"requests download URL"| node_r2
node_video_service -->|"requests upload URL"| node_r2
node_r2 -->|"presigns object access"| node_r2store
node_r2 -->|"loads credentials"| node_env
node_env -->|"loads definitions"| node_buckets
node_playback -->|"records outcomes"| node_logger
node_app -->|"logs server errors"| node_logger
node_app -->|"formats HTTP errors"| node_errors

click node_app "https://github.com/psycopathic/gurukul-api/blob/main/src/app.ts"
click node_routes "https://github.com/psycopathic/gurukul-api/blob/main/src/routes/video.routes.ts"
click node_controller "https://github.com/psycopathic/gurukul-api/blob/main/src/controllers/video.controller.ts"
click node_appcheck_mw "https://github.com/psycopathic/gurukul-api/blob/main/src/middleware/app-check.middleware.ts"
click node_appcheck "https://github.com/psycopathic/gurukul-api/blob/main/src/services/app-check.service.ts"
click node_auth_mw "https://github.com/psycopathic/gurukul-api/blob/main/src/middleware/auth.middleware.ts"
click node_firebase "https://github.com/psycopathic/gurukul-api/blob/main/src/services/firebase.service.ts"
click node_rate "https://github.com/psycopathic/gurukul-api/blob/main/src/middleware/rate-limit.middleware.ts"
click node_playback "https://github.com/psycopathic/gurukul-api/blob/main/src/services/playback.service.ts"
click node_catalog_service "https://github.com/psycopathic/gurukul-api/blob/main/src/services/catalog.service.ts"
click node_catalog "https://github.com/psycopathic/gurukul-api/blob/main/src/catalog/video-catalog.ts"
click node_entitlement "https://github.com/psycopathic/gurukul-api/blob/main/src/services/entitlement.service.ts"
click node_video_service "https://github.com/psycopathic/gurukul-api/blob/main/src/services/video.service.ts"
click node_r2 "https://github.com/psycopathic/gurukul-api/blob/main/src/services/r2.service.ts"
click node_env "https://github.com/psycopathic/gurukul-api/blob/main/src/config/env.ts"
click node_buckets "https://github.com/psycopathic/gurukul-api/blob/main/src/config/buckets.ts"
click node_logger "https://github.com/psycopathic/gurukul-api/blob/main/src/services/logger.ts"
click node_errors "https://github.com/psycopathic/gurukul-api/blob/main/src/errors.ts"

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_app,node_routes,node_controller toneBlue
class node_appcheck_mw,node_appcheck,node_auth_mw,node_firebase,node_rate toneAmber
class node_playback,node_catalog_service,node_catalog,node_entitlement,node_operator toneMint
class node_video_service,node_r2,node_r2store toneRose
class node_env,node_buckets,node_logger,node_errors,node_client toneIndigo
```

## Components

### HTTP API

- [Express App](https://github.com/psycopathic/gurukul-api/blob/main/src/app.ts): `src/app.ts`
- [Video Routes](https://github.com/psycopathic/gurukul-api/blob/main/src/routes/video.routes.ts): `src/routes/video.routes.ts`
- [Video Controller](https://github.com/psycopathic/gurukul-api/blob/main/src/controllers/video.controller.ts): `src/controllers/video.controller.ts`

### Request Security

- [App Check Gate](https://github.com/psycopathic/gurukul-api/blob/main/src/middleware/app-check.middleware.ts): `src/middleware/app-check.middleware.ts`
- [App Check Verifier](https://github.com/psycopathic/gurukul-api/blob/main/src/services/app-check.service.ts): `src/services/app-check.service.ts`
- [User and Operator Auth](https://github.com/psycopathic/gurukul-api/blob/main/src/middleware/auth.middleware.ts): `src/middleware/auth.middleware.ts`
- [Firebase Admin](https://github.com/psycopathic/gurukul-api/blob/main/src/services/firebase.service.ts): `src/services/firebase.service.ts`
- [Playback Rate Limit](https://github.com/psycopathic/gurukul-api/blob/main/src/middleware/rate-limit.middleware.ts): `src/middleware/rate-limit.middleware.ts`

### Playback Access

- [Playback Orchestrator](https://github.com/psycopathic/gurukul-api/blob/main/src/services/playback.service.ts): `src/services/playback.service.ts`
- [Catalog Lookup](https://github.com/psycopathic/gurukul-api/blob/main/src/services/catalog.service.ts): `src/services/catalog.service.ts`
- [Video Catalog](https://github.com/psycopathic/gurukul-api/blob/main/src/catalog/video-catalog.ts): `src/catalog/video-catalog.ts`
- [Access Rules](https://github.com/psycopathic/gurukul-api/blob/main/src/services/entitlement.service.ts): `src/services/entitlement.service.ts`

### R2 Storage

- [Upload URL Service](https://github.com/psycopathic/gurukul-api/blob/main/src/services/video.service.ts): `src/services/video.service.ts`
- [R2 URL Signer](https://github.com/psycopathic/gurukul-api/blob/main/src/services/r2.service.ts): `src/services/r2.service.ts`
- **Cloudflare R2**

### Configuration and Observability

- [Environment Config](https://github.com/psycopathic/gurukul-api/blob/main/src/config/env.ts): `src/config/env.ts`
- [Bucket Registry](https://github.com/psycopathic/gurukul-api/blob/main/src/config/buckets.ts): `src/config/buckets.ts`
- [Structured Logger](https://github.com/psycopathic/gurukul-api/blob/main/src/services/logger.ts): `src/services/logger.ts`
- [HTTP Errors](https://github.com/psycopathic/gurukul-api/blob/main/src/errors.ts): `src/errors.ts`

### Other components

- **Flutter App**
- **API Operator**

## Connections

- Flutter App → Express App: HTTP requests (evidence: `README.md`)
- API Operator → Express App: upload request (evidence: `README.md`)
- Express App → Video Routes: mounts routes (evidence: `src/app.ts`)
- Video Routes → App Check Gate: gates playback (evidence: `src/routes/video.routes.ts`)
- Video Routes → User and Operator Auth: authenticates (evidence: `src/routes/video.routes.ts`)
- Video Routes → Playback Rate Limit: limits playback (evidence: `src/routes/video.routes.ts`)
- Video Routes → Video Controller: dispatches (evidence: `src/routes/video.routes.ts`)
- App Check Gate → App Check Verifier: verifies token (evidence: `src/middleware/app-check.middleware.ts`)
- User and Operator Auth → Firebase Admin: verifies identity (evidence: `src/middleware/auth.middleware.ts`)
- User and Operator Auth → Environment Config: checks operator token (evidence: `src/middleware/auth.middleware.ts`)
- Video Controller → Playback Orchestrator: requests access (evidence: `src/controllers/video.controller.ts`)
- Video Controller → Upload URL Service: prepares upload (evidence: `src/controllers/video.controller.ts`)
- Playback Orchestrator → Catalog Lookup: looks up video (evidence: `src/services/playback.service.ts`)
- Catalog Lookup → Video Catalog: reads entries (evidence: `src/services/catalog.service.ts`)
- Playback Orchestrator → Access Rules: checks authorization (evidence: `src/services/playback.service.ts`)
- Playback Orchestrator → R2 URL Signer: requests download URL (evidence: `src/services/playback.service.ts`)
- Upload URL Service → R2 URL Signer: requests upload URL (evidence: `src/services/video.service.ts`)
- R2 URL Signer → Cloudflare R2: presigns object access (evidence: `src/services/r2.service.ts`)
- R2 URL Signer → Environment Config: loads credentials (evidence: `src/services/r2.service.ts`)
- Environment Config → Bucket Registry: loads definitions (evidence: `src/config/env.ts`)
- Playback Orchestrator → Structured Logger: records outcomes (evidence: `src/services/playback.service.ts`)
- Express App → Structured Logger: logs server errors (evidence: `src/app.ts`)
- Express App → HTTP Errors: formats HTTP errors (evidence: `src/app.ts`)
