# rawanbakrali/egypt-through-the-ages architecture

> Architecture diagram of the GitHub repository rawanbakrali/egypt-through-the-ages, 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/rawanbakrali/egypt-through-the-ages
- Repository: https://github.com/rawanbakrali/egypt-through-the-ages

## Overview

#### Purpose and Runtime
This is a server-rendered Node.js/Express application for exploring historical eras and places, viewing and submitting events, tracking a user’s place status, and posting reviews. It renders EJS pages while exposing route-backed APIs consumed by browser JavaScript. The main bootstrap is `app.js`; dependencies and scripts are defined in `package.json`.

#### HTTP Entry and Request Pipeline
`app.js` mounts feature route modules, configures rendering/static assets, and centralizes application middleware. Routes divide public pages from domain operations:
- Page rendering: `routes/pageRoutes.js`, `controllers/pageController.js`
- Auth: `routes/authRoutes.js`, `controllers/authController.js`
- Domain APIs: `routes/eventsRoutes.js`, `routes/placesRoutes.js`, `routes/reviewsRoutes.js`
Authentication, validation, uploads, and error translation form request boundaries in `middleware/auth.js`, `middleware/validators`, `middleware/upload.js`, and `middleware/errorHandlers.js`.

#### Server-rendered UI and Client Behavior
EJS views are the page composition layer, with reusable partials for navigation, era/event displays, review input, and administrative rows. Core pages include `views/home.ejs`, `views/era.ejs`, `views/events.ejs`, `views/event.ejs`, `views/profile.ejs`, and `views/admin.ejs`. Browser modules invoke feature endpoints and update page state: `public/js/events.js`, `public/js/reviews.js`, `public/js/place-status.js`, `public/js/profile.js`, and `public/js/map.js`. Static styles and media are served from `public/css` and `public/assets`.

#### Identity, Access, and User State
Authentication is handled through `authController` and enforced by `middleware/auth.js`; client-side guards support protected UI flows in `public/js/auth-guard.js`. User persistence and user-place relationship state are represented separately:
- `models/User.js`
- `models/UserPlaceStatus.js`
- `controllers/userPlaceStatusController.js`
This separation supports per-user tracking of places independently from globally defined place records.

#### Historical Content Domain
The core content model centers on eras, places, events, and reviews. Persistent model definitions are in `models/Event.js`, `models/Place.js`, and `models/Reviews.js`; their API orchestration lives in `controllers/eventsController.js`, `controllers/placesController.js`, and `controllers/reviewsController.js`. Era-oriented presentation is driven by `views/era.ejs` and `public/js/era.js`, while events have both listing and detail views.

#### Administrative Submission and Media Flow
Event submission and administration are distinct workflow surfaces, indicated by `views/partials/event-submission-modal.ejs`, `views/admin.ejs`, and `public/js/admin.js`. Upload requests pass through `routes/uploadRoutes.js`, `controllers/uploadController.js`, and `middleware/upload.js`, isolating file handling from normal content mutation. Validation modules such as `middleware/validators/eventsValidators.js` guard incoming domain payloads before controller/model processing.

#### Data Initialization and External Boundaries
The repository includes static/source datasets under `data`, plus operational scripts `migrate-data.js` and `seed-admin.js` for initial migration and administrative account setup. The model layer is the database boundary; its exact database provider is not identifiable from the supplied tree. Mapping is browser-side (`public/js/map.js`); the README indicates map tiles are visually grayscaled using a CSS filter rather than a paid grayscale tile provider.

Main entry points: [`app.js`](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/app.js) (Application bootstrap), [`views/home.ejs`](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/views/home.ejs) (EJS pages and partials), [`migrate-data.js`](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/migrate-data.js) (Migration and admin setup), [`controllers/userPlaceStatusController.js`](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/userPlaceStatusController.js) (User place status)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_server["Express server"]
  node_app["Application bootstrap<br/>Express bootstrap<br/>[app.js]"]
  node_routes["Feature routes<br/>Express routes"]
  node_middleware["Request boundaries<br/>middleware<br/>[auth.js]"]
end

subgraph group_ui["Rendered UI"]
  node_page_controller["Page controller<br/>[pageController.js]"]
  node_views["EJS pages and partials<br/>server-rendered views<br/>[home.ejs]"]
  node_browser["Browser feature modules<br/>browser JavaScript<br/>[events.js]"]
  node_static["Static assets<br/>styles and media"]
end

subgraph group_domain["Content domain"]
  node_content_controllers["Content controllers"]
  node_content_models[("Historical content models<br/>[Event.js]")]
end

subgraph group_identity["Identity and status"]
  node_auth_controller["Auth controller<br/>[authController.js]"]
  node_auth_guard["Client auth guard<br/>browser guard<br/>[auth-guard.js]"]
  node_user_model[("User records<br/>model<br/>[User.js]")]
  node_place_status["User place status<br/>controller and model"]
  node_status_model[("User-place state<br/>model<br/>[UserPlaceStatus.js]")]
end

subgraph group_operations["Operations"]
  node_upload_flow["Media upload flow<br/>upload endpoint<br/>[uploadRoutes.js]"]
  node_admin_submission["Admin and event submission<br/>workflow UI<br/>[admin.ejs]"]
  node_source_data["Source datasets<br/>data files"]
  node_initialization["Migration and admin setup<br/>operational scripts<br/>[migrate-data.js]"]
end

node_app -->|"mounts"| node_routes
node_app -->|"applies"| node_middleware
node_app -->|"renders"| node_views
node_app -->|"serves"| node_static
node_routes -->|"page requests"| node_page_controller
node_routes -->|"auth requests"| node_auth_controller
node_routes -->|"domain APIs"| node_content_controllers
node_routes -->|"status APIs"| node_place_status
node_routes -->|"upload endpoint"| node_upload_flow
node_middleware -->|"guards requests"| node_routes
node_page_controller -->|"selects pages"| node_views
node_views -->|"loads modules"| node_browser
node_views -->|"uses"| node_static
node_browser -->|"calls APIs"| node_routes
node_auth_guard -.->|"supports protected flows"| node_auth_controller
node_auth_controller -->|"reads and writes"| node_user_model
node_place_status -->|"reads and writes"| node_status_model
node_place_status -->|"identifies user"| node_user_model
node_content_controllers -->|"reads and writes"| node_content_models
node_upload_flow -->|"uses upload handling"| node_middleware
node_admin_submission -->|"uses admin behavior"| node_browser
node_admin_submission -->|"submits content"| node_routes
node_initialization -->|"imports"| node_source_data
node_initialization -->|"seeds administrator"| node_user_model
node_initialization -->|"migrates content"| node_content_models

click node_app "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/app.js"
click node_middleware "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/middleware/auth.js"
click node_page_controller "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/pageController.js"
click node_views "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/views/home.ejs"
click node_browser "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/public/js/events.js"
click node_static "https://github.com/rawanbakrali/egypt-through-the-ages/tree/main/public/css"
click node_auth_controller "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/authController.js"
click node_auth_guard "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/public/js/auth-guard.js"
click node_user_model "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/models/User.js"
click node_place_status "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/userPlaceStatusController.js"
click node_status_model "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/models/UserPlaceStatus.js"
click node_content_controllers "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/eventsController.js"
click node_content_models "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/models/Event.js"
click node_upload_flow "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/routes/uploadRoutes.js"
click node_admin_submission "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/views/admin.ejs"
click node_source_data "https://github.com/rawanbakrali/egypt-through-the-ages/tree/main/data"
click node_initialization "https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/migrate-data.js"

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_middleware toneBlue
class node_page_controller,node_views,node_browser,node_static toneAmber
class node_content_controllers,node_content_models toneMint
class node_auth_controller,node_auth_guard,node_user_model,node_place_status,node_status_model toneRose
class node_upload_flow,node_admin_submission,node_source_data,node_initialization toneIndigo
```

## Components

### Express server

- [Application bootstrap](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/app.js): Express bootstrap · Configures rendering, static assets, middleware, and route mounts. · `app.js`
- **Feature routes**: Express routes · Page, auth, event, place, review, and upload endpoints.
- [Request boundaries](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/middleware/auth.js): middleware · Authentication, validation, uploads, and error translation. · `middleware/auth.js`

### Rendered UI

- [Page controller](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/pageController.js): controller · `controllers/pageController.js`
- [EJS pages and partials](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/views/home.ejs): server-rendered views · Composes home, era, event, profile, admin, and reusable UI. · `views/home.ejs`
- [Browser feature modules](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/public/js/events.js): browser JavaScript · Calls APIs and updates event, review, status, profile, era, and map UI. · `public/js/events.js`
- [Static assets](https://github.com/rawanbakrali/egypt-through-the-ages/tree/main/public/css): styles and media · `public/css`

### Content domain

- [Content controllers](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/eventsController.js): controllers · Orchestrates event, place, and review APIs. · `controllers/eventsController.js`
- [Historical content models](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/models/Event.js): models · Persistent events, places, and reviews; database provider is unspecified. · `models/Event.js`

### Identity and status

- [Auth controller](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/authController.js): controller · `controllers/authController.js`
- [Client auth guard](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/public/js/auth-guard.js): browser guard · `public/js/auth-guard.js`
- [User records](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/models/User.js): model · `models/User.js`
- [User place status](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/controllers/userPlaceStatusController.js): controller and model · Stores each user's status independently of global places. · `controllers/userPlaceStatusController.js`
- [User-place state](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/models/UserPlaceStatus.js): model · `models/UserPlaceStatus.js`

### Operations

- [Media upload flow](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/routes/uploadRoutes.js): upload endpoint · Separates file handling from normal content mutation. · `routes/uploadRoutes.js`
- [Admin and event submission](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/views/admin.ejs): workflow UI · `views/admin.ejs`
- [Source datasets](https://github.com/rawanbakrali/egypt-through-the-ages/tree/main/data): data files · `data`
- [Migration and admin setup](https://github.com/rawanbakrali/egypt-through-the-ages/blob/main/migrate-data.js): operational scripts · `migrate-data.js`

## Connections

- Application bootstrap → Feature routes: mounts
- Application bootstrap → Request boundaries: applies
- Application bootstrap → EJS pages and partials: renders
- Application bootstrap → Static assets: serves
- Feature routes → Page controller: page requests
- Feature routes → Auth controller: auth requests
- Feature routes → Content controllers: domain APIs
- Feature routes → User place status: status APIs
- Feature routes → Media upload flow: upload endpoint
- Request boundaries → Feature routes: guards requests
- Page controller → EJS pages and partials: selects pages
- EJS pages and partials → Browser feature modules: loads modules
- EJS pages and partials → Static assets: uses
- Browser feature modules → Feature routes: calls APIs
- Client auth guard → Auth controller: supports protected flows
- Auth controller → User records: reads and writes
- User place status → User-place state: reads and writes
- User place status → User records: identifies user
- Content controllers → Historical content models: reads and writes
- Media upload flow → Request boundaries: uses upload handling
- Admin and event submission → Browser feature modules: uses admin behavior
- Admin and event submission → Feature routes: submits content
- Migration and admin setup → Source datasets: imports
- Migration and admin setup → User records: seeds administrator
- Migration and admin setup → Historical content models: migrates content
