# hoagieclub/mail architecture

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

- Interactive diagram: https://gitdiagram.com/hoagieclub/mail
- Repository: https://github.com/hoagieclub/mail

## Overview

Hoagie Mail is a web app for authenticated campus-wide email, with separate flows for direct sending, scheduled sending, and messages submitted to a recurring digest. The frontend proxies authenticated API requests to the Hoagie API; backend modules cover authentication, mail and digest operations, and email-provider support. The README documents listserv delivery and Auth0/CAS authentication. Source excerpts confirm the proxy and authentication behavior, but not the backend endpoint-to-provider wiring, so those links are omitted.

Main entry points: [`app/api/hoagie/[...path]/route.ts`](https://github.com/hoagieclub/mail/blob/main/app/api/hoagie/%5B...path%5D/route.ts) (API proxy), [`components/MailForm/index.tsx`](https://github.com/hoagieclub/mail/blob/main/components/MailForm/index.tsx) (Mail form selector), [`components/MailForm/SendForm.tsx`](https://github.com/hoagieclub/mail/blob/main/components/MailForm/SendForm.tsx) (Direct send form), [`backend/hoagiemail/api/auth/auth.py`](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/auth/auth.py) (JWT authentication)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web app"]
  node_home["Home and login<br/>[page.tsx]"]
  node_app_page["Mail workspace<br/>[page.tsx]"]
  node_mail_form["Mail form selector<br/>[index.tsx]"]
  node_send_form["Direct send form<br/>[SendForm.tsx]"]
  node_editor["Message editor<br/>[Editor.tsx]"]
  node_scheduled["Scheduled send"]
  node_digest["Digest submission<br/>[index.tsx]"]
  node_api_proxy["API proxy<br/>[route.ts]"]
  node_auth_button["Auth controls<br/>[index.tsx]"]
end

subgraph group_backend["Mail backend"]
  node_backend_api["Backend API"]
  node_mail_api["Mail endpoint<br/>[mail_view.py]"]
  node_stuff_posts["Digest posts"]
  node_stuff_user["Digest user data<br/>[stuff_user_view.py]"]
  node_users[("User records<br/>[user.py]")]
  node_mail_records[("Mail records<br/>[mail.py]")]
  node_stuff_records[("Digest records<br/>[stuff.py]")]
  node_mailjet_client["Mail provider client<br/>[mailjet_client.py]"]
end

subgraph group_identity["Authentication"]
  node_auth["JWT authentication<br/>[auth.py]"]
end

subgraph group_integrations["External services"]
  node_auth_service["Auth0 / CAS"]
  node_hoagie_api["Hoagie API"]
  node_mail_delivery["Campus listservs"]
end

node_visitor(("Email sender"))

node_visitor -->|"opens"| node_home
node_home -->|"offers login"| node_auth_button
node_visitor -->|"opens"| node_app_page
node_app_page -->|"renders"| node_mail_form
node_mail_form -->|"selects direct"| node_send_form
node_mail_form -->|"selects digest"| node_digest
node_send_form -->|"composes in"| node_editor
node_send_form -->|"submits via"| node_api_proxy
node_scheduled -->|"submits via"| node_api_proxy
node_digest -->|"submits via"| node_api_proxy
node_api_proxy -->|"gets access token"| node_auth_service
node_api_proxy -->|"forwards request"| node_hoagie_api
node_hoagie_api -->|"routes requests"| node_backend_api
node_backend_api -->|"authenticates with"| node_auth
node_auth -->|"verifies JWT"| node_auth_service
node_auth -->|"gets or creates"| node_users
node_mail_api --> node_mail_records
node_stuff_posts --> node_stuff_records

click node_home "https://github.com/hoagieclub/mail/blob/main/app/page.tsx"
click node_app_page "https://github.com/hoagieclub/mail/blob/main/app/app/page.tsx"
click node_mail_form "https://github.com/hoagieclub/mail/blob/main/components/MailForm/index.tsx"
click node_send_form "https://github.com/hoagieclub/mail/blob/main/components/MailForm/SendForm.tsx"
click node_editor "https://github.com/hoagieclub/mail/blob/main/components/Editor.tsx"
click node_scheduled "https://github.com/hoagieclub/mail/blob/main/components/MailForm/ScheduledSend/ScheduledMailForm.tsx"
click node_digest "https://github.com/hoagieclub/mail/blob/main/components/MailForm/DigestForm/index.tsx"
click node_api_proxy "https://github.com/hoagieclub/mail/blob/main/app/api/hoagie/%5B...path%5D/route.ts"
click node_auth_button "https://github.com/hoagieclub/mail/blob/main/lib/hoagie-ui/AuthButton/index.tsx"
click node_backend_api "https://github.com/hoagieclub/mail/tree/main/backend/hoagiemail/api"
click node_mail_api "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/mail_view.py"
click node_stuff_posts "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/stuff_posts_view.py"
click node_stuff_user "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/stuff_user_view.py"
click node_auth "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/auth/auth.py"
click node_users "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/models/user.py"
click node_mail_records "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/models/mail.py"
click node_stuff_records "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/models/stuff.py"
click node_mailjet_client "https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/email/mailjet_client.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_home,node_app_page,node_mail_form,node_send_form,node_editor,node_scheduled,node_digest,node_api_proxy,node_auth_button toneBlue
class node_backend_api,node_mail_api,node_stuff_posts,node_stuff_user,node_users,node_mail_records,node_stuff_records,node_mailjet_client toneAmber
class node_auth toneMint
class node_auth_service,node_hoagie_api,node_mail_delivery toneRose
class node_visitor toneIndigo
```

## Components

### Web app

- [Home and login](https://github.com/hoagieclub/mail/blob/main/app/page.tsx): `app/page.tsx`
- [Mail workspace](https://github.com/hoagieclub/mail/blob/main/app/app/page.tsx): `app/app/page.tsx`
- [Mail form selector](https://github.com/hoagieclub/mail/blob/main/components/MailForm/index.tsx): `components/MailForm/index.tsx`
- [Direct send form](https://github.com/hoagieclub/mail/blob/main/components/MailForm/SendForm.tsx): `components/MailForm/SendForm.tsx`
- [Message editor](https://github.com/hoagieclub/mail/blob/main/components/Editor.tsx): `components/Editor.tsx`
- [Scheduled send](https://github.com/hoagieclub/mail/blob/main/components/MailForm/ScheduledSend/ScheduledMailForm.tsx): `components/MailForm/ScheduledSend/ScheduledMailForm.tsx`
- [Digest submission](https://github.com/hoagieclub/mail/blob/main/components/MailForm/DigestForm/index.tsx): `components/MailForm/DigestForm/index.tsx`
- [API proxy](https://github.com/hoagieclub/mail/blob/main/app/api/hoagie/%5B...path%5D/route.ts): `app/api/hoagie/[...path]/route.ts`
- [Auth controls](https://github.com/hoagieclub/mail/blob/main/lib/hoagie-ui/AuthButton/index.tsx): `lib/hoagie-ui/AuthButton/index.tsx`

### Mail backend

- [Backend API](https://github.com/hoagieclub/mail/tree/main/backend/hoagiemail/api): `backend/hoagiemail/api`
- [Mail endpoint](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/mail_view.py): `backend/hoagiemail/api/mail_view.py`
- [Digest posts](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/stuff_posts_view.py): `backend/hoagiemail/api/stuff_posts_view.py`
- [Digest user data](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/stuff_user_view.py): `backend/hoagiemail/api/stuff_user_view.py`
- [User records](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/models/user.py): `backend/hoagiemail/models/user.py`
- [Mail records](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/models/mail.py): `backend/hoagiemail/models/mail.py`
- [Digest records](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/models/stuff.py): `backend/hoagiemail/models/stuff.py`
- [Mail provider client](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/email/mailjet_client.py): `backend/hoagiemail/email/mailjet_client.py`

### Authentication

- [JWT authentication](https://github.com/hoagieclub/mail/blob/main/backend/hoagiemail/api/auth/auth.py): `backend/hoagiemail/api/auth/auth.py`

### External services

- **Auth0 / CAS**
- **Hoagie API**
- **Campus listservs**

### Other components

- **Email sender**

## Connections

- Email sender → Home and login: opens
- Home and login → Auth controls: offers login
- Email sender → Mail workspace: opens
- Mail workspace → Mail form selector: renders
- Mail form selector → Direct send form: selects direct
- Mail form selector → Digest submission: selects digest
- Direct send form → Message editor: composes in
- Direct send form → API proxy: submits via
- Scheduled send → API proxy: submits via
- Digest submission → API proxy: submits via
- API proxy → Auth0 / CAS: gets access token
- API proxy → Hoagie API: forwards request
- Hoagie API → Backend API: routes requests
- Backend API → JWT authentication: authenticates with
- JWT authentication → Auth0 / CAS: verifies JWT
- JWT authentication → User records: gets or creates
- Mail endpoint → Mail records
- Digest posts → Digest records
