# barryvl/ct-werktool architecture

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

- Interactive diagram: https://gitdiagram.com/barryvl/ct-werktool
- Repository: https://github.com/barryvl/ct-werktool

## Overview

#### Purpose and deployment shape
CT Werktool is an internal portal for customer requests, projects, employees, and HRM access. It is a React single-page frontend backed by an ASP.NET Core Web API and PostgreSQL. In combined mode, the backend serves the built React assets and API from one origin; Cloudflare Tunnel can expose that host externally.
- `Start-Werktool.ps1`
- `backend/Program.cs`
- `frontend/src/main.tsx`

#### Backend host and request boundary
The ASP.NET Core application is the runtime composition root: it configures API handling, database access, access-gate behavior, and likely static-file hosting for the built frontend. Local development can separate Vite and API, while production/tunnel traffic reaches the backend host directly.
- `backend/Program.cs`
- `backend/appsettings.json`
- `backend/Properties/launchSettings.json`

#### Shared test access gate
External access is protected by a shared Basic Authentication-style gate, configured with `AccessGate:Password` through .NET User Secrets. Requests from non-local clients are rejected if this password is absent. This is explicitly a temporary perimeter mechanism, not employee identity or authorization.
- `backend/Program.cs`
- `backend/appsettings.Development.json`

#### Customer-request domain and API
Customer requests are the primary persisted workflow. The request model is paired with submitted answers, and the controller forms the API boundary used by the portal. EF migrations establish these tables and evolve their relationship.
- `backend/Controllers/KlantaanvragenController.cs`
- `backend/Models/Klantaanvraag.cs`
- `backend/Models/AanvraagAntwoord.cs`

#### Employee and HRM domain
Employee records support the employee and HRM portions of the portal. Stored roles/permissions are not yet enforced server-side, so clients must not be treated as an authorization boundary.
- `backend/Controllers/MedewerkersController.cs`
- `backend/Models/Medewerker.cs`
- `frontend/src/MedewerkersPage.tsx`

#### Persistence and schema lifecycle
Entity Framework Core connects the API to PostgreSQL through a configured default connection. `ApplicationDbContext` is the central persistence boundary; schema changes are versioned as migrations and applied before combined startup.
- `backend/Data/ApplicationDbContext.cs`
- `backend/Migrations/20260724075508_InitialCreate.cs`
- `backend/Migrations/ApplicationDbContextModelSnapshot.cs`

#### Frontend application flow
The React/Vite application selects portal, employee, and HRM views. A centralized API module is the frontend-to-backend integration point; Vite proxies API calls locally, avoiding cross-origin behavior during development.
- `frontend/src/App.tsx`
- `frontend/src/Api.ts`
- `frontend/src/PortalPage.tsx`
- `frontend/src/HrmPage.tsx`

#### Infrastructure and external dependencies
Material runtimes are .NET 10, Node.js/npm, React 19, TypeScript, Vite, PostgreSQL, and EF Core. Cloudflare Tunnel forwards the public hostname to the single local backend listener without inbound router ports. The current public-access design requires secret management through .NET User Secrets and Cloudflare administration.
- `backend/backend.csproj`
- `frontend/package.json`
- `frontend/vite.config.ts`

Main entry points: [`backend/Program.cs`](https://github.com/barryvl/ct-werktool/blob/main/backend/Program.cs) (ASP.NET Core host), [`frontend/src/Api.ts`](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/Api.ts) (API client), [`frontend/src/App.tsx`](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/App.tsx) (React portal app), [`backend/Data/ApplicationDbContext.cs`](https://github.com/barryvl/ct-werktool/blob/main/backend/Data/ApplicationDbContext.cs) (ApplicationDbContext)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Frontend"]
  node_react["React portal app<br/>React/Vite SPA<br/>[App.tsx]"]
  node_entry["Frontend entry<br/>TypeScript entrypoint<br/>[main.tsx]"]
  node_portal["Customer request view<br/>portal view<br/>[PortalPage.tsx]"]
  node_employees_ui["Employee view"]
  node_hrm["HRM view<br/>[HrmPage.tsx]"]
  node_api_client["API client<br/>frontend integration<br/>[Api.ts]"]
  node_vite_proxy["Vite API proxy<br/>development proxy<br/>[vite.config.ts]"]
end

subgraph group_backend["Backend API"]
  node_host["ASP.NET Core host<br/>.NET composition root<br/>[Program.cs]"]
  node_access_gate{{"Temporary access gate<br/>Basic-auth-style perimeter<br/>[Program.cs]"}}
  node_requests_api["Customer requests API<br/>controller"]
  node_employees_api["Employees API<br/>controller"]
end

subgraph group_data["Persistence"]
  node_request_model["Request and answers<br/>EF entities<br/>[Klantaanvraag.cs]"]
  node_employee_model["Employee record<br/>EF entity<br/>[Medewerker.cs]"]
  node_db_context["ApplicationDbContext<br/>EF Core context"]
  node_migrations["Schema migrations<br/>EF migrations"]
  node_postgres[("PostgreSQL<br/>database")]
end

subgraph group_edge["External Access"]
  node_cloudflare{{"Cloudflare Tunnel<br/>public tunnel"}}
  node_user_secrets{{"User Secrets<br/>secret store"}}
end

node_startup["Combined startup<br/>PowerShell launcher<br/>[Start-Werktool.ps1]"]

node_startup -->|"starts"| node_host
node_cloudflare -->|"public traffic"| node_host
node_entry -->|"mounts"| node_react
node_react -->|"renders"| node_portal
node_react -->|"renders"| node_employees_ui
node_react -->|"renders"| node_hrm
node_portal -->|"uses"| node_api_client
node_employees_ui -->|"uses"| node_api_client
node_hrm -->|"uses"| node_api_client
node_api_client -.->|"local development"| node_vite_proxy
node_vite_proxy -.->|"proxies /api"| node_host
node_api_client -->|"combined mode"| node_host
node_host -->|"applies"| node_access_gate
node_user_secrets -.->|"password"| node_access_gate
node_host -->|"routes"| node_requests_api
node_host -->|"routes"| node_employees_api
node_requests_api -->|"handles"| node_request_model
node_employees_api -->|"handles"| node_employee_model
node_request_model -->|"mapped by"| node_db_context
node_employee_model -->|"mapped by"| node_db_context
node_db_context -->|"EF Core connection"| node_postgres
node_migrations -->|"evolves schema"| node_postgres

click node_startup "https://github.com/barryvl/ct-werktool/blob/main/Start-Werktool.ps1"
click node_react "https://github.com/barryvl/ct-werktool/blob/main/frontend/src/App.tsx"
click node_entry "https://github.com/barryvl/ct-werktool/blob/main/frontend/src/main.tsx"
click node_portal "https://github.com/barryvl/ct-werktool/blob/main/frontend/src/PortalPage.tsx"
click node_employees_ui "https://github.com/barryvl/ct-werktool/blob/main/frontend/src/MedewerkersPage.tsx"
click node_hrm "https://github.com/barryvl/ct-werktool/blob/main/frontend/src/HrmPage.tsx"
click node_api_client "https://github.com/barryvl/ct-werktool/blob/main/frontend/src/Api.ts"
click node_vite_proxy "https://github.com/barryvl/ct-werktool/blob/main/frontend/vite.config.ts"
click node_host "https://github.com/barryvl/ct-werktool/blob/main/backend/Program.cs"
click node_access_gate "https://github.com/barryvl/ct-werktool/blob/main/backend/Program.cs"
click node_requests_api "https://github.com/barryvl/ct-werktool/blob/main/backend/Controllers/KlantaanvragenController.cs"
click node_employees_api "https://github.com/barryvl/ct-werktool/blob/main/backend/Controllers/MedewerkersController.cs"
click node_request_model "https://github.com/barryvl/ct-werktool/blob/main/backend/Models/Klantaanvraag.cs"
click node_employee_model "https://github.com/barryvl/ct-werktool/blob/main/backend/Models/Medewerker.cs"
click node_db_context "https://github.com/barryvl/ct-werktool/blob/main/backend/Data/ApplicationDbContext.cs"
click node_migrations "https://github.com/barryvl/ct-werktool/blob/main/backend/Migrations/20260724075508_InitialCreate.cs"
click node_user_secrets "https://github.com/barryvl/ct-werktool/blob/main/backend/appsettings.Development.json"

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_react,node_entry,node_portal,node_employees_ui,node_hrm,node_api_client,node_vite_proxy toneBlue
class node_host,node_access_gate,node_requests_api,node_employees_api toneAmber
class node_request_model,node_employee_model,node_db_context,node_migrations,node_postgres toneMint
class node_cloudflare,node_user_secrets toneRose
class node_startup toneNeutral
```

## Components

### Frontend

- [React portal app](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/App.tsx): React/Vite SPA · Selects portal, employee, and HRM views. · `frontend/src/App.tsx`
- [Frontend entry](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/main.tsx): TypeScript entrypoint · `frontend/src/main.tsx`
- [Customer request view](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/PortalPage.tsx): portal view · `frontend/src/PortalPage.tsx`
- [Employee view](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/MedewerkersPage.tsx): employee view · `frontend/src/MedewerkersPage.tsx`
- [HRM view](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/HrmPage.tsx): HRM view · `frontend/src/HrmPage.tsx`
- [API client](https://github.com/barryvl/ct-werktool/blob/main/frontend/src/Api.ts): frontend integration · Centralized browser-to-API boundary. · `frontend/src/Api.ts`
- [Vite API proxy](https://github.com/barryvl/ct-werktool/blob/main/frontend/vite.config.ts): development proxy · Proxies local API calls to avoid cross-origin behavior. · `frontend/vite.config.ts`

### Backend API

- [ASP.NET Core host](https://github.com/barryvl/ct-werktool/blob/main/backend/Program.cs): .NET composition root · Serves API and built frontend assets in combined mode. · `backend/Program.cs`
- [Temporary access gate](https://github.com/barryvl/ct-werktool/blob/main/backend/Program.cs): Basic-auth-style perimeter · Rejects non-local requests when the User Secrets password is absent. · `backend/Program.cs`
- [Customer requests API](https://github.com/barryvl/ct-werktool/blob/main/backend/Controllers/KlantaanvragenController.cs): controller · `backend/Controllers/KlantaanvragenController.cs`
- [Employees API](https://github.com/barryvl/ct-werktool/blob/main/backend/Controllers/MedewerkersController.cs): controller · Stored roles and permissions are not server-enforced. · `backend/Controllers/MedewerkersController.cs`

### Persistence

- [Request and answers](https://github.com/barryvl/ct-werktool/blob/main/backend/Models/Klantaanvraag.cs): EF entities · A request is persisted with submitted answers. · `backend/Models/Klantaanvraag.cs`
- [Employee record](https://github.com/barryvl/ct-werktool/blob/main/backend/Models/Medewerker.cs): EF entity · `backend/Models/Medewerker.cs`
- [ApplicationDbContext](https://github.com/barryvl/ct-werktool/blob/main/backend/Data/ApplicationDbContext.cs): EF Core context · Central database persistence boundary. · `backend/Data/ApplicationDbContext.cs`
- [Schema migrations](https://github.com/barryvl/ct-werktool/blob/main/backend/Migrations/20260724075508_InitialCreate.cs): EF migrations · Versioned schema lifecycle applied before combined startup. · `backend/Migrations/20260724075508_InitialCreate.cs`
- **PostgreSQL**: database

### External Access

- **Cloudflare Tunnel**: public tunnel · Forwards the public hostname to the backend listener.
- [User Secrets](https://github.com/barryvl/ct-werktool/blob/main/backend/appsettings.Development.json): secret store · Supplies AccessGate:Password. · `backend/appsettings.Development.json`

### Other components

- [Combined startup](https://github.com/barryvl/ct-werktool/blob/main/Start-Werktool.ps1): PowerShell launcher · `Start-Werktool.ps1`

## Connections

- Combined startup → ASP.NET Core host: starts
- Cloudflare Tunnel → ASP.NET Core host: public traffic
- Frontend entry → React portal app: mounts
- React portal app → Customer request view: renders
- React portal app → Employee view: renders
- React portal app → HRM view: renders
- Customer request view → API client: uses
- Employee view → API client: uses
- HRM view → API client: uses
- API client → Vite API proxy: local development
- Vite API proxy → ASP.NET Core host: proxies /api
- API client → ASP.NET Core host: combined mode
- ASP.NET Core host → Temporary access gate: applies
- User Secrets → Temporary access gate: password
- ASP.NET Core host → Customer requests API: routes
- ASP.NET Core host → Employees API: routes
- Customer requests API → Request and answers: handles
- Employees API → Employee record: handles
- Request and answers → ApplicationDbContext: mapped by
- Employee record → ApplicationDbContext: mapped by
- ApplicationDbContext → PostgreSQL: EF Core connection
- Schema migrations → PostgreSQL: evolves schema
