# ajkizzy/nordic-atlas-dpp-prototype architecture

> Architecture diagram of the GitHub repository ajkizzy/nordic-atlas-dpp-prototype, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-21). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ajkizzy/nordic-atlas-dpp-prototype
- Repository: https://github.com/ajkizzy/nordic-atlas-dpp-prototype

## Overview

1. This repository is split into two main runtime boundaries: a NestJS API in `api/` and a React/Vite frontend in `web/`. The app is containerized with Docker and started via `docker compose up --build`, with the frontend served through Nginx in production and the API exposed on port 3000.

2. The backend is the system of record. It uses NestJS modules and controllers for domain areas like `auth`, `users`, `products`, `batches`, `passport`, `evidence`, and `audit`. Prisma is the ORM layer (`api/src/prisma`, `api/prisma/schema.prisma`) and migrations show the database evolves around batch/product passport data, audit logging, and evidence records.

3. The core business object appears to be the batch/product passport. `batches` is the central domain module and includes a `co2-calculator.ts`, which suggests environmental impact values are computed or aggregated there. `products` and `users` likely support the batch/passport administration and lookup flows around that core entity.

4. Public access is token-based. The README’s `/resolve/[batchPublicToken]` route maps to the public passport flow: a QR code or token is resolved by the frontend, then the API returns the public passport view for that batch. This is the main anonymous read path and the primary “scan → resolve → view passport” data flow.

5. Authenticated access is role-based. The backend has a dedicated `auth` module with JWT support, plus `jwt.guard.ts`, `roles.decorator.ts`, and `roles.guard.ts`. That implies the API enforces authorization centrally, with different data exposure for admin, B2B, internal, and regulator roles rather than a single universal passport response.

6. The frontend mirrors those visibility tiers in its component structure. There are separate passport renderers for `PassportPublic`, `PassportB2B`, `PassportInternal`, and `PassportRegulator`, plus `RoleSwitcher` and `FieldVisibilityBadge`. This suggests the UI progressively reveals more fields as role context changes, instead of using distinct applications.

7. The admin experience is isolated from the public passport flow. `AdminDashboard.tsx` and the README’s `/admin` path indicate a privileged operational surface for managing batches/tokens and inspecting data. The frontend likely logs in via `/login`, stores the JWT, and then calls authenticated API endpoints through `web/src/api/client.ts`.

8. Traceability and compliance are first-class subsystems. The `audit` module, together with migrations adding “audit_log_before_after,” indicates the backend records who changed what and captures previous/new values. The `evidence` module and its migration indicate supporting documentation or proof artifacts are attached to passport data, which is important for supply-chain claims.

9. The backend startup/initialization path includes seeding. `api/prisma/seed.ts` and the README’s mention of startup logs printing batch tokens show seeded demo data is part of the expected architecture. That makes the repo a proof-of-concept with deterministic sample entities and public tokens for testing.

10. From a deployment perspective, the frontend is a static SPA built with Vite and Tailwind/PostCSS, while the API is a Node service built with NestJS/TypeScript. The Nginx config in `web/nginx.conf` suggests the compiled SPA is served as static content, and the API is consumed over HTTP from the browser using the shared client in `web/src/api/client.ts`.

11. The key architectural boundary is therefore: browser UI on one side, authenticated REST-style API on the other, with Prisma-backed persistence beneath the API. The UI handles presentation and role-specific rendering; the API owns authorization, business rules, calculations, auditability, and data persistence.

12. For a diagram, the most important flows to show are: QR/token resolution to public passport; user login to JWT issuance; JWT-protected admin/B2B/internal/regulator reads; batch changes writing audit entries and possibly evidence records; and Prisma migrations/seed establishing the database state used by all of the above.

Main entry points: [`api/src/app.module.ts`](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/app.module.ts) (App module), [`web/src/App.tsx`](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/App.tsx) (SPA shell), [`api/src/prisma/prisma.module.ts`](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/prisma/prisma.module.ts) (Prisma), [`api/src/batches/batches.module.ts`](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/batches/batches.module.ts) (Batches)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_infra["Infrastructure"]
  node_docker_compose["Compose<br/>orchestration<br/>[docker-compose.yml]"]
  node_api_dockerfile["API image<br/>container build"]
  node_web_dockerfile["Web image<br/>container build"]
end

subgraph group_api["API"]
  node_api_main(("API bootstrap<br/>nest entrypoint<br/>[main.ts]"))
  node_app_module["App module<br/>nest root module<br/>[app.module.ts]"]
  node_auth_module["Auth<br/>security module<br/>[auth.module.ts]"]
  node_batches_module["Batches<br/>domain module<br/>[batches.module.ts]"]
  node_products_module["Products<br/>domain module<br/>[products.module.ts]"]
  node_users_module["Users<br/>domain module<br/>[users.module.ts]"]
  node_passport_module["Passport<br/>public read module<br/>[passport.module.ts]"]
  node_audit_module["Audit<br/>traceability module<br/>[audit.module.ts]"]
  node_evidence_module["Evidence<br/>compliance module<br/>[evidence.module.ts]"]
  node_prisma_module[("Prisma<br/>data access<br/>[prisma.module.ts]")]
  node_schema["Schema<br/>[schema.prisma]"]
  node_seed["Seed data<br/>bootstrap data<br/>[seed.ts]"]
end

subgraph group_web["Web"]
  node_web_app(("SPA shell<br/>react app<br/>[App.tsx]"))
  node_api_client["API client<br/>http client<br/>[client.ts]"]
  node_login_page["Login<br/>auth page<br/>[LoginPage.tsx]"]
  node_resolve_page["Resolve<br/>public page<br/>[ResolvePage.tsx]"]
  node_admin_dashboard["Admin dashboard<br/>admin surface<br/>[AdminDashboard.tsx]"]
  node_passport_views["Passport views<br/>presentation set<br/>[PassportPublic.tsx]"]
  node_role_ui["Role UI<br/>visibility controls<br/>[RoleSwitcher.tsx]"]
end

node_docker_compose -->|"builds"| node_api_dockerfile
node_docker_compose -->|"builds"| node_web_dockerfile
node_api_dockerfile -->|"runs"| node_api_main
node_web_dockerfile -->|"serves"| node_web_app
node_api_main -->|"loads"| node_app_module
node_app_module -->|"includes"| node_auth_module
node_app_module -->|"includes"| node_batches_module
node_app_module -->|"includes"| node_products_module
node_app_module -->|"includes"| node_users_module
node_app_module -->|"includes"| node_passport_module
node_app_module -->|"includes"| node_audit_module
node_app_module -->|"includes"| node_evidence_module
node_app_module -->|"shares db"| node_prisma_module
node_batches_module -->|"persists via"| node_prisma_module
node_products_module -->|"persists via"| node_prisma_module
node_users_module -->|"persists via"| node_prisma_module
node_passport_module -->|"resolves"| node_batches_module
node_audit_module -->|"records via"| node_prisma_module
node_evidence_module -->|"stores via"| node_prisma_module
node_prisma_module -->|"uses"| node_schema
node_seed -->|"seeds"| node_schema
node_web_app -->|"calls"| node_api_client
node_web_app -->|"routes"| node_login_page
node_web_app -->|"routes"| node_resolve_page
node_web_app -->|"routes"| node_admin_dashboard
node_web_app -->|"renders"| node_passport_views
node_web_app -->|"controls"| node_role_ui
node_login_page -->|"authenticates"| node_api_client
node_resolve_page -->|"loads"| node_passport_views
node_admin_dashboard -->|"admin api"| node_api_client
node_passport_views -->|"adapts"| node_role_ui

click node_docker_compose "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/docker-compose.yml"
click node_api_dockerfile "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/tree/master/api/Dockerfile"
click node_web_dockerfile "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/tree/master/web/Dockerfile"
click node_api_main "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/main.ts"
click node_app_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/app.module.ts"
click node_auth_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/auth/auth.module.ts"
click node_batches_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/batches/batches.module.ts"
click node_products_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/products/products.module.ts"
click node_users_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/users/users.module.ts"
click node_passport_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/passport/passport.module.ts"
click node_audit_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/audit/audit.module.ts"
click node_evidence_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/evidence/evidence.module.ts"
click node_prisma_module "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/prisma/prisma.module.ts"
click node_schema "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/prisma/schema.prisma"
click node_seed "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/prisma/seed.ts"
click node_web_app "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/App.tsx"
click node_api_client "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/api/client.ts"
click node_login_page "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/pages/LoginPage.tsx"
click node_resolve_page "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/pages/ResolvePage.tsx"
click node_admin_dashboard "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/components/AdminDashboard.tsx"
click node_passport_views "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/components/PassportPublic.tsx"
click node_role_ui "https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/components/RoleSwitcher.tsx"

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_docker_compose,node_api_dockerfile,node_web_dockerfile toneBlue
class node_api_main,node_app_module,node_auth_module,node_batches_module,node_products_module,node_users_module,node_passport_module,node_audit_module,node_evidence_module,node_prisma_module,node_schema,node_seed toneAmber
class node_web_app,node_api_client,node_login_page,node_resolve_page,node_admin_dashboard,node_passport_views,node_role_ui toneMint
```

## Components

### Infrastructure

Containerized build and runtime entrypoints

- [Compose](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/docker-compose.yml): orchestration · Starts frontend and API containers together · `docker-compose.yml`
- [API image](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/tree/master/api/Dockerfile): container build · Builds the NestJS service image · `api/Dockerfile`
- [Web image](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/tree/master/web/Dockerfile): container build · Builds the SPA for Nginx serving · `web/Dockerfile`

### API

NestJS backend system of record

- [API bootstrap](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/main.ts): nest entrypoint · Starts the NestJS application and wiring · `api/src/main.ts`
- [App module](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/app.module.ts): nest root module · Composes backend feature modules · `api/src/app.module.ts`
- [Auth](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/auth/auth.module.ts): security module · JWT login and role enforcement · `api/src/auth/auth.module.ts`
- [Batches](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/batches/batches.module.ts): domain module · Core batch and passport business logic · `api/src/batches/batches.module.ts`
- [Products](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/products/products.module.ts): domain module · Product lookup and administration support · `api/src/products/products.module.ts`
- [Users](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/users/users.module.ts): domain module · User management and identity records · `api/src/users/users.module.ts`
- [Passport](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/passport/passport.module.ts): public read module · Token-based public passport resolution · `api/src/passport/passport.module.ts`
- [Audit](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/audit/audit.module.ts): traceability module · Change history and before/after logging · `api/src/audit/audit.module.ts`
- [Evidence](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/evidence/evidence.module.ts): compliance module · Supporting documents and proof records · `api/src/evidence/evidence.module.ts`
- [Prisma](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/src/prisma/prisma.module.ts): data access · Database access layer used by backend modules · `api/src/prisma/prisma.module.ts`
- [Schema](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/prisma/schema.prisma): database schema · Prisma data model and migrations · `api/prisma/schema.prisma`
- [Seed data](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/api/prisma/seed.ts): bootstrap data · Loads demo users, batches, and tokens · `api/prisma/seed.ts`

### Web

React/Vite frontend

- [SPA shell](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/App.tsx): react app · Client-side router and page composition · `web/src/App.tsx`
- [API client](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/api/client.ts): http client · Shared browser client for backend calls · `web/src/api/client.ts`
- [Login](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/pages/LoginPage.tsx): auth page · User login entry for JWT access · `web/src/pages/LoginPage.tsx`
- [Resolve](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/pages/ResolvePage.tsx): public page · Scans or resolves public batch tokens · `web/src/pages/ResolvePage.tsx`
- [Admin dashboard](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/components/AdminDashboard.tsx): admin surface · Privileged management view for batches and data · `web/src/components/AdminDashboard.tsx`
- [Passport views](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/components/PassportPublic.tsx): presentation set · Role-specific passport renderers for public, B2B, internal, and regulator access · `web/src/components/PassportPublic.tsx`
- [Role UI](https://github.com/ajkizzy/nordic-atlas-dpp-prototype/blob/master/web/src/components/RoleSwitcher.tsx): visibility controls · Switches and badges for role-based field exposure · `web/src/components/RoleSwitcher.tsx`

## Connections

- Compose → API image: builds · Compose builds the backend image
- Compose → Web image: builds · Compose builds the frontend image
- API image → API bootstrap: runs · Container starts the NestJS entrypoint
- Web image → SPA shell: serves · Compiled SPA is served by Nginx
- API bootstrap → App module: loads · Bootstraps the root Nest module
- App module → Auth: includes · Wires authentication and authorization
- App module → Batches: includes · Wires core batch domain
- App module → Products: includes · Wires product support domain
- App module → Users: includes · Wires user management domain
- App module → Passport: includes · Wires public passport access
- App module → Audit: includes · Wires audit logging domain
- App module → Evidence: includes · Wires evidence records domain
- App module → Prisma: shares db · Provides database access to all feature modules
- Batches → Prisma: persists via · Batch logic reads and writes through Prisma
- Products → Prisma: persists via · Product data flows through Prisma
- Users → Prisma: persists via · User data flows through Prisma
- Passport → Batches: resolves · Public passport view is derived from batch data
- Audit → Prisma: records via · Audit entries are stored in the database
- Evidence → Prisma: stores via · Evidence artifacts are persisted
- Prisma → Schema: uses · ORM is backed by Prisma schema and migrations
- Seed data → Schema: seeds · Seed data initializes the modeled tables
- SPA shell → API client: calls · Frontend uses a shared HTTP client
- SPA shell → Login: routes · Login flow is part of the SPA
- SPA shell → Resolve: routes · Public token resolution flow is part of the SPA
- SPA shell → Admin dashboard: routes · Admin surface is part of the SPA
- SPA shell → Passport views: renders · SPA displays role-specific passport variants
- SPA shell → Role UI: controls · UI exposes role switching and field visibility cues
- Login → API client: authenticates · Login exchanges credentials for JWT-backed access
- Resolve → Passport views: loads · Token resolution feeds the public passport view
- Admin dashboard → API client: admin api · Privileged management actions call the API
- Passport views → Role UI: adapts · Rendered passport fields vary by role context
