# SlpModularCms Een modulaire monolith CMS gebouwd met .NET 10. ## Projectstructuur - `src/SlpModularCms.Api`: De host applicatie en API shell. - `src/SlpModularCms.Core`: Kern functionaliteiten, data modellen en interfaces. - `src/SlpModularCms.Modules.*`: Onafhankelijke functionele modules. - `frontend/`: De CMS admin web-UI (Vite + React + TypeScript). Bewust buiten `src/` gehouden om de .NET solution schoon te houden. ## Development Setup ### Vereisten - .NET 10 SDK - Podman of Docker (voor SQL Server) ### 1. Database opstarten Start een SQL Server container met de volgende opdracht: ```powershell podman run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=MSSQL_s3cr3t_pw!" -p 1433:1433 --name sql-server -d mcr.microsoft.com/mssql/server:2022-latest ``` ### 2. Configuratie De applicatie maakt gebruik van een drie-bestanden patroon voor configuratie: - `appsettings.json`: Productie baseline. - `appsettings.Development.json`: Ontwikkelinstellingen. - `appsettings.local.json`: Lokale overrides (niet in Git). Zorg dat er een `src/SlpModularCms.Api/appsettings.local.json` aanwezig is met de juiste connection string: ```json { "ConnectionStrings": { "DefaultConnection": "Server=127.0.0.1,1433;User ID=sa;Password=MSSQL_s3cr3t_pw!;Database=SlpModularCms;TrustServerCertificate=True;MultipleActiveResultSets=true" } } ``` ### 3. Applicatie starten Voer de applicatie uit vanaf de root: ```powershell dotnet run --project src/SlpModularCms.Api ``` De API is daarna bereikbaar op `https://localhost:7221` (of de geconfigureerde poort). De OpenAPI documentatie (Scalar) is beschikbaar op `/scalar`. ## Initiële Setup (Bootstrapping) ... ## Authenticatie & Security (Unit 0) De API gebruikt een beveiligde flow voor authenticatie: - **Login**: `POST /api/v1/auth/login`. Retourneert een `accessToken` in de body en een `refreshToken` in een beveiligde `httpOnly` cookie. - **Refresh**: `POST /api/v1/auth/refresh`. Gebruikt de `refreshToken` cookie om een nieuwe `accessToken` en `refreshToken` (rotatie) te genereren. - **Revoke**: `POST /api/v1/auth/revoke`. Trekt het token in en wist de cookie. ### Belangrijke NFR Details: - **CORS**: Alleen toegestane origins uit `appsettings.json → Cors:AllowedOrigins` worden geaccepteerd. De frontend moet draaien op een van deze origins. - **Cookies**: De `refreshToken` cookie is `httpOnly`, `SameSite=Strict` en heeft het pad `/api/v1/auth`. - **Rate Limiting**: Login endpoints hebben rate limiting (Fixed window 5/min, Sliding window 20/min). - **Error Handling**: Foutmeldingen volgen de RFC 9457 `ProblemDetails` standaard. ## Frontend Development (CMS Admin UI) De frontend is een Vite + React 19 + TypeScript single-page application in de map `frontend/`. Hij gebruikt TanStack Router, Tailwind v4 (hoofdkleur `#ac0000`) met shadcn/ui-stijl componenten, react-i18next (NL/EN), en MSW voor mocking in tests. ### Vereisten - Node.js 20+ (getest met v24) - pnpm 9+ (getest met v11) ### Snel starten ```powershell cd frontend pnpm install pnpm dev ``` De dev-server draait op `http://localhost:5173`. ### Configuratie De frontend leest de API-basis-URL uit een environment-variabele (zie `frontend/.env.example`): ``` VITE_API_BASE_URL=http://localhost:5000 ``` Kopieer `.env.example` naar `.env.local` en pas de waarde aan indien nodig. Optioneel kan met `VITE_ENABLE_MSW=true` de MSW-mockbackend in de browser worden ingeschakeld voor frontend-ontwikkeling zonder draaiende API. ### Vereiste backend De app verwacht de .NET API (Unit 0) draaiend op de geconfigureerde origin met: - **CORS** die de frontend-origin (`http://localhost:5173`) toestaat met `credentials`. - De `httpOnly` `refreshToken` cookie op pad `/api/v1/auth` (silent refresh bij opstarten). - RFC 9457 `ProblemDetails` foutmeldingen. > Let op: de API-poort in `.env.example` (`5000`) moet overeenkomen met de werkelijke API-poort en de `Cors:AllowedOrigins` configuratie van de backend. ### Scripts ```powershell pnpm dev # ontwikkelserver (HMR) pnpm build # type-check (tsc) + productie-build pnpm preview # productie-build lokaal bekijken pnpm test # unit/integratietests (Vitest + Testing Library + MSW) pnpm test:coverage # tests met coverage-rapport pnpm lint # ESLint pnpm format # Prettier (4-space indent) ``` ## Database Migraties Alle database commando's moeten worden uitgevoerd vanaf de **root** van de projectmap. ### Nieuwe migratie toevoegen Wanneer je wijzigingen aanbrengt in de modellen (in `SlpModularCms.Core`): ```powershell dotnet ef migrations add --project src\SlpModularCms.Core --startup-project src\SlpModularCms.Api ``` ### Database bijwerken Om de migraties toe te passen op de database: ```powershell dotnet ef database update --project src\SlpModularCms.Core --startup-project src\SlpModularCms.Api ``` ## Nieuwe Module Toevoegen Het systeem is ontworpen om eenvoudig uitgebreid te worden met nieuwe functionele modules. Volg deze stappen om een nieuwe module toe te voegen: ### 1. Project aanmaken Maak een nieuw .NET 10 Class Library project aan in de `src/` map. Gebruik de naamconventie `SlpModularCms.Modules.`. ```powershell dotnet new classlib -n SlpModularCms.Modules.MijnNieuweModule -o src\SlpModularCms.Modules.MijnNieuweModule -f net10.0 ``` ### 2. Referenties toevoegen Voeg de benodigde referentie naar `Core` toe en voeg het project toe aan de solution: ```powershell dotnet add src\SlpModularCms.Modules.MijnNieuweModule reference src\SlpModularCms.Core dotnet sln SlpModularCms.sln add src\SlpModularCms.Modules.MijnNieuweModule ``` ### 3. IModule implementeren Maak een class aan die de `IModule` interface implementeert: ```csharp using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using SlpModularCms.Core.Modules; namespace SlpModularCms.Modules.MijnNieuweModule; public class MijnNieuweModule : IModule { public string Name => "MijnNieuweModule"; public string Version => "1.0.0"; public void RegisterServices(IServiceCollection services) { // Registreer hier module-specifieke services } public void UseModule(IApplicationBuilder app) { // Configureer hier middleware of andere pipeline zaken } } ``` ### 4. Registreren in de API Om ervoor te zorgen dat de module tijdens ontwikkeling wordt meegenomen in de build-output van de API (zodat de `ModuleOrchestrator` de DLL kan vinden), voeg je een referentie toe aan het API project: ```powershell dotnet add src\SlpModularCms.Api reference src\SlpModularCms.Modules.MijnNieuweModule ``` De `ModuleOrchestrator` zal de module nu automatisch ontdekken en laden bij het opstarten. ## Productie Setup ### 1. Build & Publish Compileer de applicatie voor productie: ```powershell dotnet publish src/SlpModularCms.Api -c Release -o ./publish ``` ### 2. Runtime Configuratie In productie moeten gevoelige instellingen worden doorgegeven via Environment Variables: - `ConnectionStrings__DefaultConnection` - `JwtSettings__Secret` - `JwtSettings__Issuer` - `JwtSettings__Audience` ### 3. Database Zorg dat de doeltabel bestaat en de migraties zijn uitgevoerd. In productie kan dit via een CI/CD pipeline worden afgehandeld met `dotnet ef migrations script` of door de applicatie bij startup migraties te laten draaien (indien geconfigureerd).