# dinmukhamad/puls architecture

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

- Interactive diagram: https://gitdiagram.com/dinmukhamad/puls
- Repository: https://github.com/dinmukhamad/puls

## Overview

#### Purpose and Entry Points
Puls is an internal call-center operator motivation/gamification platform: roles, KPI ratings, coin economy, rewards, learning missions, and operational reporting. FastAPI serves both the JSON API and the vanilla-JS SPA.
- `app/main.py`
- `app/api/router.py`
- `index.html`

#### Application Composition
`app/main.py` assembles the application: configuration, middleware, lifespan startup/shutdown work, API router, health/readiness endpoints, and static SPA delivery. Domain routers are centrally mounted once rather than independently exposed.
- `app/core/config.py`
- `app/core/lifespan.py`
- `app/core/static.py`

#### Security and Request Boundary
Authentication is JWT-backed HttpOnly cookie auth. Middleware enforces CORS, compression, and CSRF/origin protections; authorization is implemented at domain API boundaries for operator, supervisor, manager, and admin scopes. Production startup rejects unsafe configuration.
- `app/modules/auth/router.py`
- `app/core/security.py`
- `app/core/middleware.py`

#### Persistence, Schema, and Startup
PostgreSQL is the production system of record, accessed through the database layer and shared ORM entities. Alembic owns schema evolution; startup can verify schema/readiness and seed initial/admin/economy data. Local tests use temporary SQLite, but production requires PostgreSQL/psycopg.
- `app/database/db.py`
- `app/models/entities.py`
- `migrations/env.py`
- `app/services/database_readiness.py`

#### Reporting-to-Analytics Pipeline
Period-report uploads are parsed, validated, persisted, and used as the durable basis for ratings and analytics rather than transient JSON data. Analytics repositories/calculators produce KPI summaries, operator tables, group comparisons, and cached results; ratings add nomination and ranking logic.
- `app/modules/reports/service.py`
- `app/modules/reports/excel_parser.py`
- `app/modules/analytics/service.py`
- `app/modules/rating/service.py`

#### Engagement and Economy Domains
The core gamification flow connects operators and groups to levels/achievements, coin balances and transactions, seasonal shop purchases, raffles, Wheel of WOW eligibility/spins, notifications, and weekly accruals. These modules expose APIs while service layers contain transaction and rule orchestration.
- `app/modules/wallet/service.py`
- `app/modules/economy/service.py`
- `app/modules/wheel/service.py`
- `app/modules/weekly_results/accrual_service.py`
- `app/modules/missions/service.py`

#### Frontend and Delivery
The client is an HTML/CSS/vanilla-JS SPA served by FastAPI. Editable source fragments are concatenated in numeric filename order into committed browser bundles; API domain wrappers call the backend and view modules render major workflows.
- `js/src/app/00-core-shell.js`
- `js/src/api/client/00-client-auth.js`
- `js/app.js`
- `css/styles.css`
- `scripts/build-frontend.mjs`

#### Runtime and Deployment
Python 3.13/FastAPI runs under Uvicorn. Deployment targets Railway and can use Docker/Compose plus Nginx; `start.sh` applies Alembic migrations before serving. Required external infrastructure is PostgreSQL; no Node backend is used.
- `start.sh`
- `Dockerfile`
- `deploy/docker-compose.yml`
- `railway.toml`

Main entry points: [`app/api/router.py`](https://github.com/dinmukhamad/puls/blob/main/app/api/router.py) (Central API router), [`app/database/db.py`](https://github.com/dinmukhamad/puls/blob/main/app/database/db.py) (Database layer), [`app/main.py`](https://github.com/dinmukhamad/puls/blob/main/app/main.py) (Application composition), [`app/modules/economy/service.py`](https://github.com/dinmukhamad/puls/blob/main/app/modules/economy/service.py) (Wallet and economy)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["FastAPI backend"]
  node_main["Application composition<br/>FastAPI app<br/>[main.py]"]
  node_api_router["Central API router<br/>router registry<br/>[router.py]"]
  node_auth["Cookie JWT auth<br/>auth router<br/>[router.py]"]
  node_security["Security middleware<br/>security layer<br/>[middleware.py]"]
  node_lifespan["Startup lifecycle<br/>lifespan<br/>[lifespan.py]"]
  node_static_delivery["SPA static delivery<br/>static handler<br/>[static.py]"]
end

subgraph group_data["Data and analytics"]
  node_db_layer[("Database layer<br/>ORM access<br/>[db.py]")]
  node_entities[("Domain entities<br/>ORM models<br/>[entities.py]")]
  node_migrations["Alembic schema evolution<br/>migration runtime<br/>[env.py]"]
  node_readiness["Database readiness<br/>startup check"]
  node_reports["Report ingestion<br/>report service<br/>[service.py]"]
  node_excel_parser["Excel parser<br/>upload parser<br/>[excel_parser.py]"]
  node_analytics["KPI analytics<br/>analytics service<br/>[service.py]"]
  node_rating["Ratings and rankings<br/>rating service<br/>[service.py]"]
end

subgraph group_engagement["Engagement domains"]
  node_economy["Wallet and economy<br/>economy services<br/>[service.py]"]
  node_wheel["Wheel of WOW<br/>engagement service<br/>[service.py]"]
  node_weekly_accrual["Weekly accruals<br/>accrual service<br/>[accrual_service.py]"]
  node_missions["Learning missions<br/>mission service<br/>[service.py]"]
end

subgraph group_frontend["Browser client"]
  node_spa_source["SPA source modules<br/>vanilla JS source<br/>[00-core-shell.js]"]
  node_frontend_build["Frontend bundler<br/>build script<br/>[build-frontend.mjs]"]
  node_browser_bundle["Committed SPA bundle<br/>browser asset<br/>[app.js]"]
end

subgraph group_deployment["Runtime and deployment"]
  node_startup["Production startup<br/>startup script<br/>[start.sh]"]
  node_container{{"Container deployment<br/>Docker image"}}
end

node_main -->|"mounts"| node_api_router
node_main -->|"installs"| node_security
node_main -->|"runs"| node_lifespan
node_main -->|"serves through"| node_static_delivery
node_api_router -->|"includes"| node_auth
node_api_router -->|"exposes"| node_reports
node_api_router -->|"exposes"| node_analytics
node_api_router -->|"exposes"| node_economy
node_security -->|"protects"| node_auth
node_lifespan -->|"checks"| node_readiness
node_readiness -->|"verifies"| node_db_layer
node_db_layer -->|"persists"| node_entities
node_migrations -->|"evolves schema for"| node_db_layer
node_reports -->|"parses uploads with"| node_excel_parser
node_reports -->|"persists reports"| node_db_layer
node_analytics -->|"queries durable reports"| node_db_layer
node_rating -->|"uses KPI results"| node_analytics
node_economy -->|"records transactions"| node_db_layer
node_wheel -->|"uses reward economy"| node_economy
node_weekly_accrual -->|"awards coins"| node_economy
node_missions -->|"rewards completion"| node_economy
node_frontend_build -->|"concatenates ordered modules"| node_spa_source
node_frontend_build -->|"produces"| node_browser_bundle
node_static_delivery -->|"delivers"| node_browser_bundle
node_browser_bundle -->|"calls JSON API"| node_api_router
node_startup -->|"applies"| node_migrations
node_startup -->|"starts Uvicorn app"| node_main
node_container -->|"runs"| node_startup

click node_main "https://github.com/dinmukhamad/puls/blob/main/app/main.py"
click node_api_router "https://github.com/dinmukhamad/puls/blob/main/app/api/router.py"
click node_auth "https://github.com/dinmukhamad/puls/blob/main/app/modules/auth/router.py"
click node_security "https://github.com/dinmukhamad/puls/blob/main/app/core/middleware.py"
click node_lifespan "https://github.com/dinmukhamad/puls/blob/main/app/core/lifespan.py"
click node_static_delivery "https://github.com/dinmukhamad/puls/blob/main/app/core/static.py"
click node_db_layer "https://github.com/dinmukhamad/puls/blob/main/app/database/db.py"
click node_entities "https://github.com/dinmukhamad/puls/blob/main/app/models/entities.py"
click node_migrations "https://github.com/dinmukhamad/puls/blob/main/migrations/env.py"
click node_readiness "https://github.com/dinmukhamad/puls/blob/main/app/services/database_readiness.py"
click node_reports "https://github.com/dinmukhamad/puls/blob/main/app/modules/reports/service.py"
click node_excel_parser "https://github.com/dinmukhamad/puls/blob/main/app/modules/reports/excel_parser.py"
click node_analytics "https://github.com/dinmukhamad/puls/blob/main/app/modules/analytics/service.py"
click node_rating "https://github.com/dinmukhamad/puls/blob/main/app/modules/rating/service.py"
click node_economy "https://github.com/dinmukhamad/puls/blob/main/app/modules/economy/service.py"
click node_wheel "https://github.com/dinmukhamad/puls/blob/main/app/modules/wheel/service.py"
click node_weekly_accrual "https://github.com/dinmukhamad/puls/blob/main/app/modules/weekly_results/accrual_service.py"
click node_missions "https://github.com/dinmukhamad/puls/blob/main/app/modules/missions/service.py"
click node_spa_source "https://github.com/dinmukhamad/puls/blob/main/js/src/app/00-core-shell.js"
click node_frontend_build "https://github.com/dinmukhamad/puls/blob/main/scripts/build-frontend.mjs"
click node_browser_bundle "https://github.com/dinmukhamad/puls/blob/main/js/app.js"
click node_startup "https://github.com/dinmukhamad/puls/blob/main/start.sh"
click node_container "https://github.com/dinmukhamad/puls/blob/main/Dockerfile"

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_main,node_api_router,node_auth,node_security,node_lifespan,node_static_delivery toneBlue
class node_db_layer,node_entities,node_migrations,node_readiness,node_reports,node_excel_parser,node_analytics,node_rating toneAmber
class node_economy,node_wheel,node_weekly_accrual,node_missions toneMint
class node_spa_source,node_frontend_build,node_browser_bundle toneRose
class node_startup,node_container toneIndigo
```

## Components

### FastAPI backend

Single process serves API, health checks, and SPA assets.

- [Application composition](https://github.com/dinmukhamad/puls/blob/main/app/main.py): FastAPI app · Assembles middleware, lifespan, routers, health endpoints, and static delivery. · `app/main.py`
- [Central API router](https://github.com/dinmukhamad/puls/blob/main/app/api/router.py): router registry · Mounts domain routers under one API boundary. · `app/api/router.py`
- [Cookie JWT auth](https://github.com/dinmukhamad/puls/blob/main/app/modules/auth/router.py): auth router · Authenticates users and enforces role-scoped access. · `app/modules/auth/router.py`
- [Security middleware](https://github.com/dinmukhamad/puls/blob/main/app/core/middleware.py): security layer · Provides JWT, CSRF/origin, CORS, and compression protections. · `app/core/middleware.py`
- [Startup lifecycle](https://github.com/dinmukhamad/puls/blob/main/app/core/lifespan.py): lifespan · Runs startup and shutdown work including readiness and seeding. · `app/core/lifespan.py`
- [SPA static delivery](https://github.com/dinmukhamad/puls/blob/main/app/core/static.py): static handler · Serves the HTML client and browser assets. · `app/core/static.py`

### Data and analytics

PostgreSQL-backed reporting and KPI processing.

- [Database layer](https://github.com/dinmukhamad/puls/blob/main/app/database/db.py): ORM access · Shared PostgreSQL sessions and ORM entities. · `app/database/db.py`
- [Domain entities](https://github.com/dinmukhamad/puls/blob/main/app/models/entities.py): ORM models · `app/models/entities.py`
- [Alembic schema evolution](https://github.com/dinmukhamad/puls/blob/main/migrations/env.py): migration runtime · Owns production schema migrations. · `migrations/env.py`
- [Database readiness](https://github.com/dinmukhamad/puls/blob/main/app/services/database_readiness.py): startup check · Verifies schema and database availability. · `app/services/database_readiness.py`
- [Report ingestion](https://github.com/dinmukhamad/puls/blob/main/app/modules/reports/service.py): report service · Validates and persists uploaded period reports. · `app/modules/reports/service.py`
- [Excel parser](https://github.com/dinmukhamad/puls/blob/main/app/modules/reports/excel_parser.py): upload parser · `app/modules/reports/excel_parser.py`
- [KPI analytics](https://github.com/dinmukhamad/puls/blob/main/app/modules/analytics/service.py): analytics service · Builds summaries, operator tables, comparisons, and cached results. · `app/modules/analytics/service.py`
- [Ratings and rankings](https://github.com/dinmukhamad/puls/blob/main/app/modules/rating/service.py): rating service · Adds nomination and ranking logic over durable reports. · `app/modules/rating/service.py`

### Engagement domains

Gamification rules and economy transactions.

- [Wallet and economy](https://github.com/dinmukhamad/puls/blob/main/app/modules/economy/service.py): economy services · Orchestrates balances, transactions, shop purchases, and rewards. · `app/modules/economy/service.py`
- [Wheel of WOW](https://github.com/dinmukhamad/puls/blob/main/app/modules/wheel/service.py): engagement service · Determines eligibility and records spins. · `app/modules/wheel/service.py`
- [Weekly accruals](https://github.com/dinmukhamad/puls/blob/main/app/modules/weekly_results/accrual_service.py): accrual service · Awards recurring engagement results. · `app/modules/weekly_results/accrual_service.py`
- [Learning missions](https://github.com/dinmukhamad/puls/blob/main/app/modules/missions/service.py): mission service · `app/modules/missions/service.py`

### Browser client

Vanilla-JS SPA source is built into committed assets.

- [SPA source modules](https://github.com/dinmukhamad/puls/blob/main/js/src/app/00-core-shell.js): vanilla JS source · Core shell and API wrappers define browser workflows. · `js/src/app/00-core-shell.js`
- [Frontend bundler](https://github.com/dinmukhamad/puls/blob/main/scripts/build-frontend.mjs): build script · Concatenates ordered source fragments into browser bundles. · `scripts/build-frontend.mjs`
- [Committed SPA bundle](https://github.com/dinmukhamad/puls/blob/main/js/app.js): browser asset · The built client calls API domains and renders workflows. · `js/app.js`

### Runtime and deployment

Production startup migrates PostgreSQL before serving.

- [Production startup](https://github.com/dinmukhamad/puls/blob/main/start.sh): startup script · Applies migrations before starting Uvicorn. · `start.sh`
- [Container deployment](https://github.com/dinmukhamad/puls/blob/main/Dockerfile): Docker image · Supports Docker, Compose, Nginx, and Railway deployment. · `Dockerfile`

## Connections

- Application composition → Central API router: mounts
- Application composition → Security middleware: installs
- Application composition → Startup lifecycle: runs
- Application composition → SPA static delivery: serves through
- Central API router → Cookie JWT auth: includes
- Central API router → Report ingestion: exposes
- Central API router → KPI analytics: exposes
- Central API router → Wallet and economy: exposes
- Security middleware → Cookie JWT auth: protects
- Startup lifecycle → Database readiness: checks
- Database readiness → Database layer: verifies
- Database layer → Domain entities: persists
- Alembic schema evolution → Database layer: evolves schema for
- Report ingestion → Excel parser: parses uploads with
- Report ingestion → Database layer: persists reports
- KPI analytics → Database layer: queries durable reports
- Ratings and rankings → KPI analytics: uses KPI results
- Wallet and economy → Database layer: records transactions
- Wheel of WOW → Wallet and economy: uses reward economy
- Weekly accruals → Wallet and economy: awards coins
- Learning missions → Wallet and economy: rewards completion
- Frontend bundler → SPA source modules: concatenates ordered modules
- Frontend bundler → Committed SPA bundle: produces
- SPA static delivery → Committed SPA bundle: delivers
- Committed SPA bundle → Central API router: calls JSON API
- Production startup → Alembic schema evolution: applies
- Production startup → Application composition: starts Uvicorn app
- Container deployment → Production startup: runs
