# unb-mds/2026-2-followw architecture

> Architecture diagram of the GitHub repository unb-mds/2026-2-followw, 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/unb-mds/2026-2-followw
- Repository: https://github.com/unb-mds/2026-2-followw

## Overview

Followw UnB is an independent web client for SIGAA UnB and related campus services. The main workflow is a student using the web app to request academic or RU information from the API; authenticated requests use SIGAA-backed services, while public menu and calendar functionality has separate integration modules. Login authenticates with SIGAA, sets session cookies, and enqueues an account-sync job. The graph reflects documented routes and sampled wiring; service internals and several frontend connections were not sampled, so uncertain call edges are omitted.

Main entry points: [`apps/api/api/main.py`](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/main.py) (API router), [`apps/api/api/modules/auth/main.py`](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/auth/main.py) (SIGAA auth), [`apps/web/src/router.tsx`](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/router.tsx) (Web experience), [`apps/web/src/queries/client.ts`](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/queries/client.ts) (API queries)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web app"]
  node_webapp["Web experience<br/>[router.tsx]"]
  node_webqueries["API queries<br/>[client.ts]"]
  node_webclass["Classroom views<br/>[turmas.tsx]"]
  node_webprofile["Profile view<br/>[perfil.tsx]"]
  node_webrestaurant["RU view<br/>[ru.tsx]"]
end

subgraph group_api["API product"]
  node_apientry["API router<br/>[main.py]"]
  node_auth["SIGAA auth<br/>[main.py]"]
  node_classrooms["Classrooms<br/>[main.py]"]
  node_profile["Student profile<br/>[main.py]"]
  node_news["Class news<br/>[main.py]"]
  node_restaurant["RU menu and account<br/>[main.py]"]
  node_classservice["Classroom service<br/>[classroom.py]"]
  node_profileservice["Profile service<br/>[profile.py]"]
  node_newsservice["News service<br/>[news.py]"]
  node_restaurantservice["Restaurant service<br/>[restaurant.py]"]
end

subgraph group_data["Persistence and sync"]
  node_database[("Application database<br/>[main.py]")]
  node_sync["Account sync<br/>[sync.py]"]
  node_jobendpoint["Job receiver<br/>[main.py]"]
end

subgraph group_integrations["Campus integrations"]
  node_sigaa["SIGAA client<br/>[client.py]"]
  node_unbbrowser["UnB browser<br/>[browser.py]"]
end

node_student(("Student"))
node_qstash["QStash"]
node_sigaaexternal{{"SIGAA / CAS"}}
node_campus{{"RU and campus calendar"}}

node_student -->|"uses"| node_webapp
node_webapp -->|"requests data"| node_webqueries
node_webqueries -->|"calls API"| node_apientry
node_apientry -->|"dispatches"| node_auth
node_apientry -->|"dispatches"| node_classrooms
node_apientry -->|"dispatches"| node_profile
node_apientry -->|"dispatches"| node_news
node_apientry -->|"dispatches"| node_restaurant
node_classrooms -->|"calls"| node_classservice
node_profile -->|"calls"| node_profileservice
node_news -->|"calls"| node_newsservice
node_restaurant -->|"calls"| node_restaurantservice
node_auth -->|"authenticates"| node_sigaa
node_auth -->|"enqueues sync"| node_qstash
node_qstash -->|"delivers job"| node_jobendpoint
node_jobendpoint -->|"runs"| node_sync
node_sigaa -->|"requests data"| node_sigaaexternal
node_unbbrowser -->|"reads public data"| node_campus

click node_webapp "https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/router.tsx"
click node_webqueries "https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/queries/client.ts"
click node_webclass "https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/routes/turmas.tsx"
click node_webprofile "https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/routes/perfil.tsx"
click node_webrestaurant "https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/routes/ru.tsx"
click node_apientry "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/main.py"
click node_auth "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/auth/main.py"
click node_classrooms "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/classrooms/main.py"
click node_profile "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/me/main.py"
click node_news "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/news/main.py"
click node_restaurant "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/restaurant/main.py"
click node_classservice "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/classroom.py"
click node_profileservice "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/profile.py"
click node_newsservice "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/news.py"
click node_restaurantservice "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/restaurant.py"
click node_database "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/db/main.py"
click node_sync "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/sync.py"
click node_jobendpoint "https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/jobs/main.py"
click node_sigaa "https://github.com/unb-mds/2026-2-followw/blob/main/packages/sigaa-client/sigaa_client/client.py"
click node_unbbrowser "https://github.com/unb-mds/2026-2-followw/blob/main/packages/unb-browser/unb_browser/browser.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_webapp,node_webqueries,node_webclass,node_webprofile,node_webrestaurant toneBlue
class node_apientry,node_auth,node_classrooms,node_profile,node_news,node_restaurant,node_classservice,node_profileservice,node_newsservice,node_restaurantservice toneAmber
class node_database,node_sync,node_jobendpoint toneMint
class node_sigaa,node_unbbrowser toneRose
class node_student,node_qstash,node_sigaaexternal,node_campus toneIndigo
```

## Components

### Web app

- [Web experience](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/router.tsx): `apps/web/src/router.tsx`
- [API queries](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/queries/client.ts): `apps/web/src/queries/client.ts`
- [Classroom views](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/routes/turmas.tsx): `apps/web/src/routes/turmas.tsx`
- [Profile view](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/routes/perfil.tsx): `apps/web/src/routes/perfil.tsx`
- [RU view](https://github.com/unb-mds/2026-2-followw/blob/main/apps/web/src/routes/ru.tsx): `apps/web/src/routes/ru.tsx`

### API product

- [API router](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/main.py): `apps/api/api/main.py`
- [SIGAA auth](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/auth/main.py): `apps/api/api/modules/auth/main.py`
- [Classrooms](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/classrooms/main.py): `apps/api/api/modules/classrooms/main.py`
- [Student profile](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/me/main.py): `apps/api/api/modules/me/main.py`
- [Class news](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/news/main.py): `apps/api/api/modules/news/main.py`
- [RU menu and account](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/restaurant/main.py): `apps/api/api/modules/restaurant/main.py`
- [Classroom service](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/classroom.py): `apps/api/api/services/classroom.py`
- [Profile service](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/profile.py): `apps/api/api/services/profile.py`
- [News service](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/news.py): `apps/api/api/services/news.py`
- [Restaurant service](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/restaurant.py): `apps/api/api/services/restaurant.py`

### Persistence and sync

- [Application database](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/db/main.py): `apps/api/api/db/main.py`
- [Account sync](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/services/sync.py): `apps/api/api/services/sync.py`
- [Job receiver](https://github.com/unb-mds/2026-2-followw/blob/main/apps/api/api/modules/jobs/main.py): `apps/api/api/modules/jobs/main.py`

### Campus integrations

- [SIGAA client](https://github.com/unb-mds/2026-2-followw/blob/main/packages/sigaa-client/sigaa_client/client.py): `packages/sigaa-client/sigaa_client/client.py`
- [UnB browser](https://github.com/unb-mds/2026-2-followw/blob/main/packages/unb-browser/unb_browser/browser.py): `packages/unb-browser/unb_browser/browser.py`

### Other components

- **Student**
- **QStash**
- **SIGAA / CAS**
- **RU and campus calendar**

## Connections

- Student → Web experience: uses
- Web experience → API queries: requests data
- API queries → API router: calls API
- API router → SIGAA auth: dispatches
- API router → Classrooms: dispatches
- API router → Student profile: dispatches
- API router → Class news: dispatches
- API router → RU menu and account: dispatches
- Classrooms → Classroom service: calls
- Student profile → Profile service: calls
- Class news → News service: calls
- RU menu and account → Restaurant service: calls
- SIGAA auth → SIGAA client: authenticates
- SIGAA auth → QStash: enqueues sync
- QStash → Job receiver: delivers job
- Job receiver → Account sync: runs
- SIGAA client → SIGAA / CAS: requests data
- UnB browser → RU and campus calendar: reads public data
