# tezay/mariam architecture

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

- Interactive diagram: https://gitdiagram.com/tezay/mariam
- Repository: https://github.com/tezay/mariam

## Overview

1. **Overall shape**
   - MARIAM is a two-tier application: a **React/Vite frontend** in `client/` and a **Flask REST backend** in `server/`.
   - The frontend serves both **public menu consumption** and **admin management**, while the backend owns authentication, business rules, persistence, and file storage.

2. **Frontend boundary**
   - `client/src/pages/public/*` contains the unauthenticated experience: menu display, notifications page, mobile and TV variants.
   - `client/src/pages/admin/*` contains the authenticated back-office: weekly planner, calendar views, events, gallery, users, settings, closures, and installation/transfer flows.
   - Shared UI is concentrated in `client/src/components/` plus a local UI kit in `client/src/components/ui/`.

3. **Frontend data access and session state**
   - `client/src/lib/api.ts` is the main API client boundary; it centralizes HTTP calls to the backend.
   - `AuthContext` manages login/session state, while `ThemeProvider` and `PwaInstallContext` handle cross-cutting client concerns.
   - The client also includes push/PWA support via `client/src/lib/push.ts` and `client/src/sw-push.js`, which ties into browser notifications.

4. **Backend domain boundary**
   - The Flask app is organized by feature under `server/app/routes/`, with modules for `auth`, `menus`, `events`, `gallery`, `users`, `restaurant`, `categories`, `closures`, `imports`, `notifications`, `audit`, and `taxonomy`.
   - `server/app/models/` contains the persistence model layer for those same business concepts.
   - `server/app/schemas/` provides request/response validation and serialization, which separates API contracts from ORM models.

5. **Core business flows**
   - **Menu authoring flow:** admins create/edit weekly and daily menus in the frontend, which maps to backend menu/category/event endpoints and persists to PostgreSQL.
   - **Publication flow:** once content is ready, the backend exposes it to public menu pages without authentication.
   - **Event and closure flow:** special events and exceptional closures are managed separately from standard menus and shown in public display views.
   - **Gallery flow:** uploaded images are stored in S3-compatible storage and reused across menu items and events.

6. **Authentication and security model**
   - Admin access is protected by JWT-based API auth plus stronger identity features: **MFA/TOTP** and **passkeys** are both present in the model and routes.
   - Account lifecycle includes activation and password reset paths on the client (`Activate`, `ResetPassword`) and corresponding backend routes.
   - `server/app/security.py` plus the auth routes are the main security boundary; `server/app/models/audit_log.py` supports traceability of sensitive actions.

7. **Storage and persistence**
   - **PostgreSQL** is the primary system of record for users, restaurant configuration, menus, events, closures, imports, audit logs, passkeys, and subscriptions.
   - **S3-compatible object storage** is a second persistence tier for images and uploaded assets; `server/app/services/storage.py` encapsulates bucket management, upload, and deletion.
   - The README and file structure indicate separate prefixes for gallery images, event images, menu images, and restaurant logos, which is important when drawing the storage boundary.

8. **Taxonomy and content metadata**
   - The repo treats food tags/certifications as structured domain data rather than free text.
   - `server/app/data/taxonomy.py` and `server/app/models/taxonomy.py` back a controlled vocabulary used by the frontend for labels, icons, and filtering.
   - This taxonomy is central to the public menu UX because the menus surface dietary tags and certifications as first-class metadata.

9. **Notifications and PWA behavior**
   - `server/app/models/push_subscription.py` and `server/app/services/notification_service.py` support browser push notifications.
   - The client includes install and push-related contexts/pages, indicating a PWA-style experience for admins and/or students.
   - Public notification pages are part of the frontend, but actual delivery is driven by backend subscriptions and notification service logic.

10. **Deployment topology**
   - Development is containerized with **Docker Compose** at the repository root.
   - Production is split under `deploy/`, with Nginx configuration, install/run scripts, and a separate compose setup.
   - The README shows the intended runtime stack: frontend on port 5173, Flask API on 5000, PostgreSQL on 5432, and MinIO/S3 on 9000/9001 in development.

11. **Schema evolution and maintenance**
   - `server/migrations/` uses Alembic for database versioning, which is the durable contract for schema changes.
   - `server/app/commands/` and `server/app/scripts/` contain operational commands such as seeding, demo data, and migration execution.
   - This means operational setup is not just “run the app”; there is an explicit provisioning path for the first restaurant/admin account and for database initialization.

12. **Quality and test boundaries**
   - The backend has pytest coverage in `server/tests/`, focused on auth, categories, menus, public menu behavior, restaurant, and users.
   - The frontend has unit tests under `client/src/__tests__/`.
   - CI/CD is split into quality and publish workflows in `.github/workflows/`, so code quality and container publishing are part of the delivery architecture.

13. **How to draw the diagram**
   - Show **public clients** and **admin clients** as the same frontend application with different route groups and capabilities.
   - Draw the **Flask API** as the central business layer, with separate feature modules behind it.
   - Connect the API to **PostgreSQL** for structured data and to **S3/MinIO** for images and uploads.
   - Mark **auth/MFA**, **push notifications**, and **taxonomy** as cross-cutting subdomains rather than separate apps.

Main entry points: [`client/src/pages/admin`](https://github.com/tezay/mariam/tree/main/client/src/pages/admin) (Admin pages), [`server/app/models`](https://github.com/tezay/mariam/tree/main/server/app/models) (Models), [`server/app/schemas`](https://github.com/tezay/mariam/tree/main/server/app/schemas) (Schemas), [`client/src/App.tsx`](https://github.com/tezay/mariam/blob/main/client/src/App.tsx) (Client app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Client app"]
  node_client_app["Client app<br/>react/vite<br/>[App.tsx]"]
  node_public_pages["Public pages<br/>public UX"]
  node_admin_pages["Admin pages<br/>back-office UX"]
  node_shared_components["Shared UI<br/>ui/components"]
  node_client_state["Client state<br/>contexts/lib"]
  node_push_clients(("Browser push<br/>PWA delivery<br/>[push.ts]"))
end

subgraph group_backend["Flask API"]
  node_auth_routes["Auth API<br/>security<br/>[auth.py]"]
  node_menu_routes["Menu API<br/>content API<br/>[menus.py]"]
  node_calendar_routes["Calendar API<br/>scheduling API<br/>[events.py]"]
  node_content_routes["Content API<br/>catalog API<br/>[gallery.py]"]
  node_admin_routes["Admin API<br/>management API<br/>[users.py]"]
  node_models["Models"]
  node_schemas["Schemas<br/>contracts"]
  node_security["Security<br/>authz/authn<br/>[security.py]"]
  node_services["Services"]
  node_taxonomy_data["Taxonomy data<br/>controlled vocabulary<br/>[taxonomy.py]"]
end

subgraph group_ops["Delivery"]
  node_deployment["Deploy stack<br/>docker/nginx<br/>[docker-compose.yml]"]
  node_migrations["Migrations<br/>alembic"]
end

subgraph group_storage["External systems"]
  node_database[("PostgreSQL<br/>relational db")]
  node_object_storage[("S3 storage<br/>object store")]
end

node_client_app -->|"routes"| node_public_pages
node_client_app -->|"routes"| node_admin_pages
node_client_app -->|"uses"| node_shared_components
node_client_app -->|"state"| node_client_state
node_public_pages -->|"reads"| node_menu_routes
node_admin_pages -->|"auth"| node_auth_routes
node_admin_pages -->|"edits"| node_menu_routes
node_admin_pages -->|"manages"| node_calendar_routes
node_admin_pages -->|"manages"| node_content_routes
node_admin_pages -->|"admin"| node_admin_routes
node_client_state -->|"push"| node_push_clients
node_auth_routes -->|"enforces"| node_security
node_auth_routes -->|"persists"| node_models
node_menu_routes -->|"persists"| node_models
node_calendar_routes -->|"persists"| node_models
node_content_routes -->|"persists"| node_models
node_admin_routes -->|"persists"| node_models
node_schemas -->|"validates"| node_auth_routes
node_schemas -->|"validates"| node_menu_routes
node_schemas -->|"validates"| node_calendar_routes
node_schemas -->|"validates"| node_content_routes
node_schemas -->|"validates"| node_admin_routes
node_models -->|"stores"| node_database
node_services -->|"uploads"| node_object_storage
node_services -->|"delivers"| node_push_clients
node_taxonomy_data -->|"feeds"| node_content_routes
node_deployment -.->|"runs"| node_client_app
node_deployment -.->|"runs"| node_auth_routes
node_deployment -.->|"depends"| node_database
node_deployment -.->|"depends"| node_object_storage
node_migrations -->|"upgrades"| node_database

click node_client_app "https://github.com/tezay/mariam/blob/main/client/src/App.tsx"
click node_public_pages "https://github.com/tezay/mariam/tree/main/client/src/pages/public"
click node_admin_pages "https://github.com/tezay/mariam/tree/main/client/src/pages/admin"
click node_shared_components "https://github.com/tezay/mariam/tree/main/client/src/components"
click node_client_state "https://github.com/tezay/mariam/tree/main/client/src/contexts"
click node_auth_routes "https://github.com/tezay/mariam/blob/main/server/app/routes/auth.py"
click node_menu_routes "https://github.com/tezay/mariam/blob/main/server/app/routes/menus.py"
click node_calendar_routes "https://github.com/tezay/mariam/blob/main/server/app/routes/events.py"
click node_content_routes "https://github.com/tezay/mariam/blob/main/server/app/routes/gallery.py"
click node_admin_routes "https://github.com/tezay/mariam/blob/main/server/app/routes/users.py"
click node_models "https://github.com/tezay/mariam/tree/main/server/app/models"
click node_schemas "https://github.com/tezay/mariam/tree/main/server/app/schemas"
click node_security "https://github.com/tezay/mariam/blob/main/server/app/security.py"
click node_services "https://github.com/tezay/mariam/tree/main/server/app/services"
click node_taxonomy_data "https://github.com/tezay/mariam/blob/main/server/app/data/taxonomy.py"
click node_push_clients "https://github.com/tezay/mariam/blob/main/client/src/lib/push.ts"
click node_deployment "https://github.com/tezay/mariam/blob/main/deploy/docker-compose.yml"
click node_migrations "https://github.com/tezay/mariam/tree/main/server/migrations"

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_client_app,node_public_pages,node_admin_pages,node_shared_components,node_client_state,node_push_clients toneBlue
class node_auth_routes,node_menu_routes,node_calendar_routes,node_content_routes,node_admin_routes,node_models,node_schemas,node_security,node_services,node_taxonomy_data toneAmber
class node_deployment,node_migrations toneMint
class node_database,node_object_storage toneRose
```

## Components

### Client app

React/Vite frontend for public menu viewing and admin operations.

- [Client app](https://github.com/tezay/mariam/blob/main/client/src/App.tsx): react/vite · Single-page frontend with public and admin route groups. · `client/src/App.tsx`
- [Public pages](https://github.com/tezay/mariam/tree/main/client/src/pages/public): public UX · Unauthenticated menu, notifications, mobile, and TV experiences. · `client/src/pages/public`
- [Admin pages](https://github.com/tezay/mariam/tree/main/client/src/pages/admin): back-office UX · Authenticated management for menus, calendar, users, settings, and setup flows. · `client/src/pages/admin`
- [Shared UI](https://github.com/tezay/mariam/tree/main/client/src/components): ui/components · Reusable layouts, editors, pickers, and the local UI kit. · `client/src/components`
- [Client state](https://github.com/tezay/mariam/tree/main/client/src/contexts): contexts/lib · Auth, theme, PWA install state, API access, and push helpers. · `client/src/contexts`
- [Browser push](https://github.com/tezay/mariam/blob/main/client/src/lib/push.ts): PWA delivery · Client-side notification and install surfaces tied to push subscriptions. · `client/src/lib/push.ts`

### Flask API

Server-side API, domain logic, persistence, and services.

- [Auth API](https://github.com/tezay/mariam/blob/main/server/app/routes/auth.py): security · Login, activation, password reset, MFA, and passkey flows. · `server/app/routes/auth.py`
- [Menu API](https://github.com/tezay/mariam/blob/main/server/app/routes/menus.py): content API · Weekly and daily menu publishing and editing endpoints. · `server/app/routes/menus.py`
- [Calendar API](https://github.com/tezay/mariam/blob/main/server/app/routes/events.py): scheduling API · Events, closures, and calendar-oriented content endpoints. · `server/app/routes/events.py`
- [Content API](https://github.com/tezay/mariam/blob/main/server/app/routes/gallery.py): catalog API · Gallery, categories, taxonomy, restaurant, and import endpoints. · `server/app/routes/gallery.py`
- [Admin API](https://github.com/tezay/mariam/blob/main/server/app/routes/users.py): management API · Users, audit logging, notifications, and operational administration endpoints. · `server/app/routes/users.py`
- [Models](https://github.com/tezay/mariam/tree/main/server/app/models): ORM models · Persistence layer for users, menus, events, closures, gallery, taxonomy, and subscriptions. · `server/app/models`
- [Schemas](https://github.com/tezay/mariam/tree/main/server/app/schemas): contracts · Request and response validation plus serialization boundaries. · `server/app/schemas`
- [Security](https://github.com/tezay/mariam/blob/main/server/app/security.py): authz/authn · Shared security boundary for JWT auth, MFA/TOTP, and passkeys. · `server/app/security.py`
- [Services](https://github.com/tezay/mariam/tree/main/server/app/services): domain services · Notification delivery and object storage integration. · `server/app/services`
- [Taxonomy data](https://github.com/tezay/mariam/blob/main/server/app/data/taxonomy.py): controlled vocabulary · Structured tags and certifications used for menu labeling and filtering. · `server/app/data/taxonomy.py`

### Delivery

Deployment, migrations, scripts, and CI/CD surfaces.

- [Deploy stack](https://github.com/tezay/mariam/blob/main/deploy/docker-compose.yml): docker/nginx · Compose, Nginx, and production scripts for running the system. · `deploy/docker-compose.yml`
- [Migrations](https://github.com/tezay/mariam/tree/main/server/migrations): alembic · Database schema versioning and upgrade history. · `server/migrations`

### External systems

Runtime persistence and infrastructure dependencies.

- **PostgreSQL**: relational db · Primary system of record for business entities and audit history.
- **S3 storage**: object store · Image and asset storage for gallery, menu, event, and logo uploads.

## Connections

- Client app → Public pages: routes · Public navigation and unauthenticated experiences.
- Client app → Admin pages: routes · Authenticated back-office routes and views.
- Client app → Shared UI: uses · Shared UI and editor primitives.
- Client app → Client state: state · Auth, theme, install, API, and session helpers.
- Public pages → Menu API: reads · Fetches published menus and public content.
- Admin pages → Auth API: auth · Login, activation, reset, MFA, and passkey flows.
- Admin pages → Menu API: edits · Creates and updates menus and weekly planning data.
- Admin pages → Calendar API: manages · Schedules events and closures through calendar workflows.
- Admin pages → Content API: manages · Uses gallery, category, taxonomy, restaurant, and import APIs.
- Admin pages → Admin API: admin · User, audit, notification, and setup operations.
- Client state → Browser push: push · Install and browser notification support.
- Auth API → Security: enforces · Shared authentication and authorization boundary.
- Auth API → Models: persists · Users, activation links, passkeys, and audit-related state.
- Menu API → Models: persists · Menus, categories, and publication state.
- Calendar API → Models: persists · Events and exceptional closures.
- Content API → Models: persists · Gallery, restaurant, taxonomy, category, and import data.
- Admin API → Models: persists · Users, notifications, audit logs, and subscriptions.
- Schemas → Auth API: validates · API contracts for auth endpoints.
- Schemas → Menu API: validates · API contracts for menu endpoints.
- Schemas → Calendar API: validates · API contracts for events and closures.
- Schemas → Content API: validates · API contracts for gallery, restaurant, taxonomy, and imports.
- Schemas → Admin API: validates · API contracts for users, audit, and notifications.
- Models → PostgreSQL: stores · Primary relational persistence.
- Services → S3 storage: uploads · Image and asset bucket management.
- Services → Browser push: delivers · Notification service supports browser push.
- Taxonomy data → Content API: feeds · Controlled vocabulary exposed through taxonomy APIs.
- Deploy stack → Client app: runs · Frontend container and Nginx delivery.
- Deploy stack → Auth API: runs · Backend container and API runtime.
- Deploy stack → PostgreSQL: depends · PostgreSQL runtime dependency.
- Deploy stack → S3 storage: depends · S3-compatible storage dependency.
- Migrations → PostgreSQL: upgrades · Schema versioning for PostgreSQL.
