From 73025c5a84845bd67eab6bc2f5b801685ffc8c4a Mon Sep 17 00:00:00 2001 From: Sluijsens Date: Tue, 16 Jun 2026 23:25:22 +0200 Subject: [PATCH] Adds reverse engineering docs and adds new aidlc feature for front-end development --- .../reverse-engineering/api-documentation.md | 125 +++++++++++++++ .../reverse-engineering/architecture.md | 123 +++++++++++++++ .../reverse-engineering/business-overview.md | 68 ++++++++ .../code-quality-assessment.md | 34 ++++ .../reverse-engineering/code-structure.md | 108 +++++++++++++ .../component-inventory.md | 23 +++ .../reverse-engineering/dependencies.md | 112 +++++++++++++ .../reverse-engineering-timestamp.md | 16 ++ .../reverse-engineering/technology-stack.md | 56 +++++++ aidlc-docs/active-features.md | 1 + .../features/cms-frontend/aidlc-state.md | 36 +++++ aidlc-docs/features/cms-frontend/audit.md | 49 ++++++ .../requirement-clarification-questions.md | 23 +++ .../requirement-verification-questions.md | 147 ++++++++++++++++++ ...gap-001-language-preference-per-feature.md | 73 +++++++++ 15 files changed, 994 insertions(+) create mode 100644 aidlc-docs/_shared/reverse-engineering/api-documentation.md create mode 100644 aidlc-docs/_shared/reverse-engineering/architecture.md create mode 100644 aidlc-docs/_shared/reverse-engineering/business-overview.md create mode 100644 aidlc-docs/_shared/reverse-engineering/code-quality-assessment.md create mode 100644 aidlc-docs/_shared/reverse-engineering/code-structure.md create mode 100644 aidlc-docs/_shared/reverse-engineering/component-inventory.md create mode 100644 aidlc-docs/_shared/reverse-engineering/dependencies.md create mode 100644 aidlc-docs/_shared/reverse-engineering/reverse-engineering-timestamp.md create mode 100644 aidlc-docs/_shared/reverse-engineering/technology-stack.md create mode 100644 aidlc-docs/features/cms-frontend/aidlc-state.md create mode 100644 aidlc-docs/features/cms-frontend/audit.md create mode 100644 aidlc-docs/features/cms-frontend/inception/requirements/requirement-clarification-questions.md create mode 100644 aidlc-docs/features/cms-frontend/inception/requirements/requirement-verification-questions.md create mode 100644 aidlc-docs/gap-reports/gap-001-language-preference-per-feature.md diff --git a/aidlc-docs/_shared/reverse-engineering/api-documentation.md b/aidlc-docs/_shared/reverse-engineering/api-documentation.md new file mode 100644 index 0000000..d31f208 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/api-documentation.md @@ -0,0 +1,125 @@ +# API Documentation + +## REST APIs + +### Authentication + +#### POST /auth/login +- **Method**: POST +- **Path**: `/auth/login` +- **Purpose**: Authenticate a user and receive JWT tokens +- **Authorization**: Anonymous +- **Request**: `{ "email": string, "password": string }` +- **Response**: `{ "accessToken": string, "refreshToken": string, "expiresAt": datetime, "user": { "id": guid, "email": string, "naam": string, "role": string } }` + +#### POST /auth/refresh +- **Method**: POST +- **Path**: `/auth/refresh` +- **Purpose**: Refresh an access token using a valid refresh token +- **Authorization**: Anonymous +- **Request**: `{ "accessToken": string, "refreshToken": string }` +- **Response**: Same as `/auth/login` + +#### POST /auth/revoke +- **Method**: POST +- **Path**: `/auth/revoke` +- **Purpose**: Revoke a refresh token (logout) +- **Authorization**: Bearer JWT required +- **Request**: `""` (string body) +- **Response**: 204 No Content + +--- + +### Setup + +#### GET /setup/status +- **Method**: GET +- **Path**: `/setup/status` +- **Purpose**: Check if the system has been initialized (first owner created) +- **Authorization**: Anonymous +- **Response**: `{ "initialized": boolean }` + +#### POST /setup/owner +- **Method**: POST +- **Path**: `/setup/owner` +- **Purpose**: Create the initial Owner account (only usable when system is not yet initialized) +- **Authorization**: Anonymous +- **Request**: `{ "email": string, "password": string }` +- **Response**: `{ "message": string }` + +--- + +### Users + +#### POST /users/invite +- **Method**: POST +- **Path**: `/users/invite` +- **Purpose**: Invite a new user by email with a specified role +- **Authorization**: Bearer JWT, Policy: AdminOnly +- **Request**: `{ "email": string, "role": string }` +- **Response**: `{ "inviteLink": string }` + +#### POST /users/complete-setup +- **Method**: POST +- **Path**: `/users/complete-setup` +- **Purpose**: Complete account setup using an invitation token +- **Authorization**: Anonymous +- **Request**: `{ "token": string, "password": string }` +- **Response**: `{ "message": string }` + +#### GET /users/validate-invitation +- **Method**: GET +- **Path**: `/users/validate-invitation?token={token}` +- **Purpose**: Validate an invitation token before showing the setup form +- **Authorization**: Anonymous +- **Response**: `{ "valid": boolean, "email": string, "role": string }` or error + +--- + +### Availability + +#### GET /availability/status +- **Method**: GET +- **Path**: `/availability/status` +- **Purpose**: Get current system availability status +- **Authorization**: Anonymous +- **Response**: `{ "status": "Available|Maintenance|Unavailable", "checkedAt": datetime, "message": string }` + +#### POST /availability/admin/status +- **Method**: POST +- **Path**: `/availability/admin/status` +- **Purpose**: Update the system availability status +- **Authorization**: Bearer JWT, Policy: OwnerOnly +- **Request**: `{ "newStatus": "Available|Maintenance|Unavailable", "reason": string }` +- **Response**: 200 OK or 400 Bad Request + +--- + +## Authorization Policies + +| Policy | Required Role | Description | +|--------|--------------|-------------| +| `OwnerOnly` | Owner | Full system access including availability management | +| `AdminOnly` | Owner or Admin | User management access | + +## Data Models + +### AuthResponse +- `accessToken` — short-lived JWT (e.g. 15 min) +- `refreshToken` — long-lived opaque token +- `expiresAt` — access token expiry datetime +- `user` — authenticated user info + +### ApplicationUser (returned in auth responses) +- `id` — Guid +- `email` — string +- `naam` — string (display name) +- `role` — string (Owner / Admin / User) +- `isActive` — boolean + +### Invitation +- `token` — string (URL-safe token) +- `email` — string +- `role` — string +- `expiryDate` — datetime +- `isUsed` — boolean diff --git a/aidlc-docs/_shared/reverse-engineering/architecture.md b/aidlc-docs/_shared/reverse-engineering/architecture.md new file mode 100644 index 0000000..56101f4 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/architecture.md @@ -0,0 +1,123 @@ +# System Architecture + +## System Overview + +SlpModularCms is a modular, ASP.NET Core-based CMS platform. The backend is structured as a monolith-with-modules: a single API host (`SlpModularCms.Api`) that dynamically loads feature modules at startup. Each module is self-contained and registers its own services and HTTP middleware. Persistence is handled via Entity Framework Core with SQL Server. Authentication uses JWT Bearer tokens with refresh token rotation. + +The frontend is a React SPA (to be built) that communicates with the API via REST/JSON. The example app (from ZIP) provides the design foundation: Vite + React Router v7 + shadcn/ui + Tailwind CSS v4 with primary color `#ac0000`. + +## Architecture Diagram + +``` ++--------------------------------------------------+ +| Client Layer | +| +--------------------------------------------+ | +| | React SPA (SlpModularCms.Frontend) | | +| | Vite + React Router v7 + shadcn/ui | | +| | Tailwind CSS v4 (#ac0000 theme) | | +| +--------------------------------------------+ | ++---------------------------+----------------------+ + | HTTP REST / JSON ++---------------------------v----------------------+ +| API Layer | +| +--------------------------------------------+ | +| | SlpModularCms.Api (ASP.NET Core) | | +| | - JWT Bearer Auth Middleware | | +| | - CORS, Swagger/OpenAPI | | +| | - Module registration pipeline | | +| +--------------------------------------------+ | +| | +| +------------------+ +---------------------+ | +| | Identity Module | | Availability Module | | +| | - AuthController| | - AvailabilityCtrl | | +| | - SetupCtrl | | - PersistentService | | +| | - UsersCtrl | | - CircuitBreaker | | +| +------------------+ +---------------------+ | ++---------------------------+----------------------+ + | ++---------------------------v----------------------+ +| Core Layer | +| +--------------------------------------------+ | +| | SlpModularCms.Core | | +| | - ApplicationDbContext (EF Core) | | +| | - Domain Entities | | +| | - Identity Services (Auth, Setup, Invite) | | +| | - IModule interface + ModuleInfo | | +| +--------------------------------------------+ | ++---------------------------+----------------------+ + | ++---------------------------v----------------------+ +| Data Layer | +| +--------------------------------------------+ | +| | SQL Server Database | | +| | - ASP.NET Identity tables | | +| | - RefreshTokens | | +| | - Invitations | | +| | - GlobalAvailabilityState | | +| +--------------------------------------------+ | ++--------------------------------------------------+ +``` + +## Component Descriptions + +### SlpModularCms.Api +- **Purpose**: Web API host and application entry point +- **Responsibilities**: Bootstrap, module loading, middleware pipeline, CORS, Swagger +- **Dependencies**: SlpModularCms.Core, SlpModularCms.Modules.Identity, SlpModularCms.Modules.Availability +- **Type**: Application + +### SlpModularCms.Core +- **Purpose**: Shared domain layer +- **Responsibilities**: Domain entities, EF Core DbContext, authentication services, module interface +- **Dependencies**: EF Core, ASP.NET Identity, SQL Server provider +- **Type**: Shared Library + +### SlpModularCms.Modules.Identity +- **Purpose**: Identity and user management module +- **Responsibilities**: HTTP endpoints for auth, setup, and user invitation flows +- **Dependencies**: SlpModularCms.Core +- **Type**: Application Module + +### SlpModularCms.Modules.Availability +- **Purpose**: System availability tracking module +- **Responsibilities**: Exposes system status, allows owners to update it, caches with circuit breaker +- **Dependencies**: SlpModularCms.Core +- **Type**: Application Module + +### SlpModularCms.Frontend (To Be Built) +- **Purpose**: Admin SPA for CMS management +- **Responsibilities**: Login, dashboard, user management, CMS content management, availability status display +- **Dependencies**: SlpModularCms.Api (REST) +- **Type**: Frontend Application + +## Data Flow + +``` +Login Flow: + Browser -> POST /auth/login -> AuthController + -> AuthService.AuthenticateAsync() + -> PasswordHasher validates credentials + -> JwtService generates access + refresh tokens + -> Returns {accessToken, refreshToken} + +Invite Flow: + Admin -> POST /users/invite -> UsersController + -> InvitationService.CreateInvitationAsync() + -> Stores Invitation entity with token + -> Returns invite link + +New User Setup: + User -> POST /users/complete-setup -> UsersController + -> InvitationService.CompleteInvitationAsync() + -> Sets password, activates account +``` + +## Integration Points +- **External APIs**: None currently +- **Databases**: SQL Server (via EF Core) +- **Third-party Services**: None currently + +## Infrastructure Components +- **Deployment Model**: Single API process + React SPA (separate deploy or static files) +- **Authentication**: JWT Bearer tokens (HS256 or RS256 based on JwtSettings config) +- **Database Migrations**: EF Core Code-First migrations in SlpModularCms.Core/Migrations/ diff --git a/aidlc-docs/_shared/reverse-engineering/business-overview.md b/aidlc-docs/_shared/reverse-engineering/business-overview.md new file mode 100644 index 0000000..b839753 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/business-overview.md @@ -0,0 +1,68 @@ +# Business Overview + +## Business Context Diagram + +``` ++--------------------------------------------------+ +| SlpModularCms Platform | +| | +| +-----------+ +-----------+ +-----------+ | +| | Identity | | CMS | |Availability| | +| | Module | | Module | | Module | | +| | (Auth + | | (Content | | (System | | +| | Users) | | Mgmt) | | Status) | | +| +-----------+ +-----------+ +-----------+ | +| | +| +-------------------------------------------+ | +| | Core / Shell | | +| | (Domain entities, DbContext, Module I/F) | | +| +-------------------------------------------+ | ++--------------------------------------------------+ + | | + v v + [Admin Frontend] [External Clients] + (React SPA) (API consumers) +``` + +## Business Description + +- **Business Description**: SlpModularCms is a modular Content Management System (CMS) platform. It provides a REST API backend for managing CMS content, users, and system availability. The platform uses role-based access control (Owner, Admin, User) and supports a modular plugin architecture so that features can be added as independent modules. +- **Business Transactions**: + - **User Authentication**: Login with email/password, receive JWT access + refresh token pair; refresh tokens for continued sessions; revoke tokens on logout. + - **System Initialization**: First-time setup — create initial Owner account before normal operations can begin. + - **User Invitation**: Admins and Owners invite new users by email; new users complete their account setup via an invitation link. + - **System Availability Management**: Owners can update the system availability status (Available / Maintenance / Unavailable); anyone can query current status. + - **CMS Content Management**: (Planned — module structure is in place but CMS-specific content modules are not yet implemented.) +- **Business Dictionary**: + - **Owner**: Highest-privilege role; can manage users, modules, and system availability. + - **Admin**: Can manage users and CMS content within their scope. + - **User**: Standard access; can use CMS features but cannot manage system settings. + - **Module**: An independently deployable feature unit that integrates into the CMS shell. + - **Invitation**: A time-limited token sent to a new user allowing them to create their account. + - **Availability Status**: Available | Maintenance | Unavailable — represents the operational state of the system. + +## Component Level Business Descriptions + +### SlpModularCms.Api +- **Purpose**: ASP.NET Core Web API host — the entry point for all HTTP requests. +- **Responsibilities**: Bootstraps the application, registers modules, configures middleware (auth, CORS, Swagger), exposes REST endpoints. + +### SlpModularCms.Core +- **Purpose**: Shared domain core — entities, DbContext, interfaces, services, and migrations. +- **Responsibilities**: Defines domain entities (ApplicationUser, ApplicationRole, Invitation, RefreshToken, GlobalAvailabilityState), persistence (EF Core + SQL Server), and shared service contracts. + +### SlpModularCms.Modules.Identity +- **Purpose**: Authentication and user management module. +- **Responsibilities**: Implements AuthController (login/refresh/revoke), SetupController (initial owner creation), UsersController (invite, complete-setup, validate-invitation). + +### SlpModularCms.Modules.Availability +- **Purpose**: System availability / health status module. +- **Responsibilities**: Implements AvailabilityController (get status, update status), caches status in-memory with circuit breaker, persists status changes to the database. + +### SlpModularCms.Core.Tests +- **Purpose**: Unit tests for the Core layer. +- **Responsibilities**: Tests for exception classes, invitation service logic, identity services. + +### SlpModularCms.Modules.Availability.Tests +- **Purpose**: Unit/integration tests for the Availability module. +- **Responsibilities**: Tests for availability service logic and controller behavior. diff --git a/aidlc-docs/_shared/reverse-engineering/code-quality-assessment.md b/aidlc-docs/_shared/reverse-engineering/code-quality-assessment.md new file mode 100644 index 0000000..b8d896d --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/code-quality-assessment.md @@ -0,0 +1,34 @@ +# Code Quality Assessment + +## Test Coverage +- **Overall**: Fair — unit tests exist for Core and Availability modules +- **Unit Tests**: Present for Core.Tests and Modules.Availability.Tests +- **Integration Tests**: Not observed in current structure +- **Frontend Tests**: None (example app has no test files) + +## Code Quality Indicators +- **Linting**: Not explicitly configured (no .editorconfig or eslint config seen in backend; frontend likely uses Vite defaults) +- **Code Style**: Consistent — clean C# with XML doc comments on public interfaces and entities +- **Documentation**: Good for core interfaces and entities (XML doc comments); controllers have minimal comments +- **Naming**: Follows .NET conventions (PascalCase classes/methods, camelCase parameters) + +## Technical Debt +- Auth context in example React app uses `localStorage` for user state (security concern — no httpOnly cookies) +- Example app auth-context simulates login locally without real API calls (will need to be replaced with actual API integration) +- No CORS configuration confirmed in backend (needs verification for SPA integration) +- `AvailabilityController.UpdateStatus` uses a direct service cast (`as PersistentAvailabilityService`) which couples controller to implementation +- No OpenAPI/Swagger spec currently integrated (would help frontend integration) + +## Patterns and Anti-patterns + +### Good Patterns +- Module pattern provides clear separation of concerns between features +- JWT refresh token rotation is properly implemented +- Authorization policies are well-defined (OwnerOnly, AdminOnly) +- EF Core used consistently for persistence +- Service interfaces (IAuthService, IInvitationService, ISetupService) for testability + +### Anti-patterns +- Direct implementation cast in `AvailabilityController` (should use extended interface instead) +- Example React app uses localStorage-based auth (acceptable for prototype, not production) +- Example React app `auth-context` hardcodes mock users (must be replaced with real API calls) diff --git a/aidlc-docs/_shared/reverse-engineering/code-structure.md b/aidlc-docs/_shared/reverse-engineering/code-structure.md new file mode 100644 index 0000000..5511ff6 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/code-structure.md @@ -0,0 +1,108 @@ +# Code Structure + +## Build System +- **Type**: .NET SDK (MSBuild / dotnet CLI) +- **Configuration**: `SlpModularCms.sln` — solution file referencing all projects +- **Target Framework**: `net10.0` + +## Project Structure + +``` +SlpModularCms/ ++-- src/ +| +-- SlpModularCms.Api/ # API host +| | +-- Extensions/ +| | | +-- ServiceCollectionExtensions.cs # DI setup (JWT, Identity, EF, Auth) +| | +-- Infrastructure/ # Global exception handler +| | +-- Properties/launchSettings.json +| | +-- Program.cs # App startup and module loading +| | +-- appsettings.json +| | +-- appsettings.local.json # Local dev overrides +| | +| +-- SlpModularCms.Core/ # Shared core +| | +-- Availability/ +| | | +-- AvailabilityOptions.cs # Circuit breaker config +| | | +-- AvailabilityStatus.cs # Enum: Available, Maintenance, Unavailable +| | +-- Data/ +| | | +-- ApplicationDbContext.cs # EF Core DbContext +| | +-- Exceptions/ # Custom exception types +| | +-- Identity/ +| | | +-- Authorization/ # Policy handlers +| | | +-- Entities/ +| | | | +-- ApplicationUser.cs # IdentityUser + IsActive + CreatedAt +| | | | +-- ApplicationRole.cs # IdentityRole +| | | | +-- RefreshToken.cs # Refresh token entity +| | | | +-- Invitation.cs # Invite entity with expiry +| | | | +-- GlobalAvailabilityState.cs # Persisted system status +| | | +-- Models/ # DTOs/request-response models +| | | +-- Services/ +| | | +-- AuthService.cs # JWT generation + token validation +| | | +-- InvitationService.cs # Invite creation + completion +| | | +-- SetupService.cs # Initial owner creation +| | +-- Migrations/ # EF Core migrations +| | +-- Modules/ +| | +-- IModule.cs # Module interface (Name, Version, RegisterServices, UseModule) +| | +-- ModuleInfo.cs # Module metadata record +| | +| +-- SlpModularCms.Modules.Identity/ # Identity feature module +| | +-- Controllers/ +| | +-- AuthController.cs # /auth/* endpoints +| | +-- SetupController.cs # /setup/* endpoints +| | +-- UsersController.cs # /users/* endpoints +| | +| +-- SlpModularCms.Modules.Availability/ # Availability feature module +| | +-- Controllers/ +| | | +-- AvailabilityController.cs # /availability/* endpoints +| | +-- Middleware/ # Availability check middleware +| | +-- Services/ +| | +-- PersistentAvailabilityService.cs # Reads/writes status to DB + cache +| | +| +-- SlpModularCms.Core.Tests/ # Core unit tests +| +-- SlpModularCms.Modules.Availability.Tests/ # Availability unit tests +| ++-- aidlc-docs/ # AI-DLC workflow documentation +``` + +## Key Classes/Modules + +### Core Domain Entities +- `ApplicationUser` — extends `IdentityUser` with `IsActive`, `CreatedAt`, `Naam` +- `ApplicationRole` — extends `IdentityRole` +- `RefreshToken` — linked to user; has `Token`, `ExpiryDate`, `IsRevoked`, `IsActive` +- `Invitation` — linked to user (invitee); has `Token`, `ExpiryDate`, `IsUsed`, `Role` +- `GlobalAvailabilityState` — singleton-ish entity storing `Status`, `Message`, `LastUpdatedAt`, `UpdatedBy` + +### Core Services +- `IAuthService` / `AuthService` — `AuthenticateAsync`, `RefreshTokenAsync`, `RevokeTokenAsync` +- `IInvitationService` / `InvitationService` — `CreateInvitationAsync`, `CompleteInvitationAsync`, `ValidateInvitationAsync` +- `ISetupService` / `SetupService` — `IsSystemInitializedAsync`, `CreateInitialOwnerAsync` +- `IAvailabilityService` / `PersistentAvailabilityService` — `IsAvailableAsync`, `UpdateStatusAsync` + +### Module System +- `IModule` — interface: `RegisterServices(IServiceCollection)`, `UseModule(IApplicationBuilder)` +- Modules discovered at startup and invoked in sequence + +## Design Patterns +### Module Pattern +- **Location**: `SlpModularCms.Core/Modules/`, `SlpModularCms.Api/Program.cs` +- **Purpose**: Allows features to be developed, tested, and deployed independently +- **Implementation**: Each module class implements `IModule` and is registered in the API host + +### Repository Pattern via EF Core +- **Location**: `ApplicationDbContext` used directly in services +- **Purpose**: Centralized persistence with Entity Framework + +### JWT with Refresh Token Rotation +- **Location**: `AuthService.cs`, `AuthController.cs` +- **Purpose**: Stateless auth with token refresh capability + +## Critical Dependencies +### ASP.NET Core Identity +- **Version**: .NET 10 built-in +- **Usage**: User/Role management, password hashing +- **Purpose**: Provides authentication primitives + +### Entity Framework Core +- **Version**: .NET 10 built-in +- **Usage**: Data persistence with SQL Server provider +- **Purpose**: ORM for all domain entities diff --git a/aidlc-docs/_shared/reverse-engineering/component-inventory.md b/aidlc-docs/_shared/reverse-engineering/component-inventory.md new file mode 100644 index 0000000..e21ced3 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/component-inventory.md @@ -0,0 +1,23 @@ +# Component Inventory + +## Application Packages +- `SlpModularCms.Api` — Web API host; bootstraps application, registers modules, exposes HTTP endpoints +- `SlpModularCms.Modules.Identity` — Identity module: authentication, setup, user invitation controllers +- `SlpModularCms.Modules.Availability` — Availability module: system status tracking controllers and services + +## Shared Packages +- `SlpModularCms.Core` — Core domain: entities, DbContext, services, module interface, migrations + +## Test Packages +- `SlpModularCms.Core.Tests` — Unit tests for Core layer (exceptions, identity services) +- `SlpModularCms.Modules.Availability.Tests` — Unit tests for Availability module + +## Frontend (To Be Built) +- `SlpModularCms.Frontend` — React SPA; admin panel for CMS management + +## Total Count +- **Total Packages**: 6 (5 existing .NET + 1 new frontend) +- **Application**: 3 (Api, Modules.Identity, Modules.Availability) +- **Shared**: 1 (Core) +- **Test**: 2 (Core.Tests, Modules.Availability.Tests) +- **Frontend**: 1 (to be built) diff --git a/aidlc-docs/_shared/reverse-engineering/dependencies.md b/aidlc-docs/_shared/reverse-engineering/dependencies.md new file mode 100644 index 0000000..c9294e2 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/dependencies.md @@ -0,0 +1,112 @@ +# Dependencies + +## Internal Dependencies + +``` +SlpModularCms.Api + +-- SlpModularCms.Core (compile) + +-- SlpModularCms.Modules.Identity (compile) + +-- SlpModularCms.Modules.Availability (compile) + +SlpModularCms.Modules.Identity + +-- SlpModularCms.Core (compile) + +SlpModularCms.Modules.Availability + +-- SlpModularCms.Core (compile) + +SlpModularCms.Core.Tests + +-- SlpModularCms.Core (test) + +SlpModularCms.Modules.Availability.Tests + +-- SlpModularCms.Modules.Availability (test) + +-- SlpModularCms.Core (test) + +SlpModularCms.Frontend (to be built) + +-- SlpModularCms.Api (runtime via REST HTTP) +``` + +### Dependency Details + +#### SlpModularCms.Api depends on SlpModularCms.Core +- **Type**: Compile +- **Reason**: Needs ApplicationDbContext, entities, DI extensions, module registration + +#### SlpModularCms.Api depends on SlpModularCms.Modules.Identity +- **Type**: Compile +- **Reason**: Registers Identity module and its HTTP controllers + +#### SlpModularCms.Api depends on SlpModularCms.Modules.Availability +- **Type**: Compile +- **Reason**: Registers Availability module and its HTTP controllers + +#### SlpModularCms.Modules.Identity depends on SlpModularCms.Core +- **Type**: Compile +- **Reason**: Uses domain entities (ApplicationUser, Invitation), services (IAuthService), and DbContext + +#### SlpModularCms.Modules.Availability depends on SlpModularCms.Core +- **Type**: Compile +- **Reason**: Uses GlobalAvailabilityState, AvailabilityStatus, AvailabilityOptions + +## External Dependencies (Backend) + +### Microsoft.AspNetCore.Identity +- **Version**: .NET 10 built-in +- **Purpose**: User and role management, password hashing +- **License**: MIT + +### Microsoft.EntityFrameworkCore + SqlServer provider +- **Version**: .NET 10 built-in +- **Purpose**: Data persistence +- **License**: MIT + +### Microsoft.AspNetCore.Authentication.JwtBearer +- **Version**: .NET 10 built-in +- **Purpose**: JWT authentication middleware +- **License**: MIT + +### Microsoft.IdentityModel.Tokens +- **Version**: .NET 10 built-in +- **Purpose**: JWT token creation and validation +- **License**: MIT + +## External Dependencies (Frontend — from package.json) + +### react + react-dom +- **Version**: 18.3.1 +- **Purpose**: Core UI framework +- **License**: MIT + +### react-router +- **Version**: 7.13.0 +- **Purpose**: Client-side routing +- **License**: MIT + +### @radix-ui/* (multiple packages) +- **Version**: Various (1.x–2.x) +- **Purpose**: shadcn/ui component primitives +- **License**: MIT + +### tailwindcss +- **Version**: 4.1.12 +- **Purpose**: Utility-first CSS framework +- **License**: MIT + +### lucide-react +- **Version**: 0.487.0 +- **Purpose**: Icon library +- **License**: ISC + +### recharts +- **Version**: 2.15.2 +- **Purpose**: Charts and data visualization +- **License**: MIT + +### react-hook-form +- **Version**: 7.55.0 +- **Purpose**: Form state management +- **License**: MIT + +### sonner +- **Version**: 2.0.3 +- **Purpose**: Toast notifications +- **License**: MIT diff --git a/aidlc-docs/_shared/reverse-engineering/reverse-engineering-timestamp.md b/aidlc-docs/_shared/reverse-engineering/reverse-engineering-timestamp.md new file mode 100644 index 0000000..ce6d4d7 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/reverse-engineering-timestamp.md @@ -0,0 +1,16 @@ +# Reverse Engineering Metadata + +**Analysis Date**: 2026-06-16T20:30:00Z +**Analyzer**: AI-DLC (Junie) +**Workspace**: K:\Development\Projects\SlpModularCms +**Total Files Analyzed**: ~35 (backend .cs files) + ~60 (frontend .tsx/.ts files from ZIP) + +## Artifacts Generated +- [x] business-overview.md +- [x] architecture.md +- [x] code-structure.md +- [x] api-documentation.md +- [x] component-inventory.md +- [x] technology-stack.md +- [x] dependencies.md +- [x] code-quality-assessment.md diff --git a/aidlc-docs/_shared/reverse-engineering/technology-stack.md b/aidlc-docs/_shared/reverse-engineering/technology-stack.md new file mode 100644 index 0000000..279cea5 --- /dev/null +++ b/aidlc-docs/_shared/reverse-engineering/technology-stack.md @@ -0,0 +1,56 @@ +# Technology Stack + +## Backend + +### Programming Languages +- C# 14.0 — All backend packages + +### Frameworks +- ASP.NET Core 10.0 — Web API framework +- ASP.NET Core Identity — User/role management, password hashing +- Entity Framework Core 10.0 — ORM for SQL Server persistence + +### Infrastructure +- SQL Server — Primary database +- JWT Bearer Authentication — Stateless auth with refresh tokens + +### Build Tools +- .NET 10 SDK / dotnet CLI — Build, test, publish +- MSBuild — Underlying build engine + +### Testing Tools +- xUnit (inferred from project conventions) — Unit testing framework +- Moq or similar (inferred) — Mocking in unit tests + +--- + +## Frontend (Example App — ZIP file basis) + +### Programming Languages +- TypeScript — All frontend code + +### Frameworks +- React 18.3.1 — UI framework +- React Router v7 (7.13.0) — Client-side routing +- Tailwind CSS v4 (4.1.12) — Utility-first CSS framework +- shadcn/ui (via Radix UI) — Accessible component primitives + +### UI Component Libraries +- Radix UI — Headless component primitives (accordion, dialog, dropdown, etc.) +- lucide-react (0.487.0) — SVG icon library +- recharts (2.15.2) — Charts and data visualization +- MUI / Material UI (7.3.5) — Additional UI components + +### State / Data +- react-hook-form (7.55.0) — Form state management +- sonner (2.0.3) — Toast notifications +- next-themes (0.4.6) — Dark/light theme support + +### Build Tools +- Vite 6.3.5 — Build tool and dev server +- pnpm — Package manager (pnpm-workspace.yaml present) +- PostCSS — CSS processing + +### Theme +- Primary color: `#ac0000` (deep red) +- Mode: Light + dark via CSS custom properties diff --git a/aidlc-docs/active-features.md b/aidlc-docs/active-features.md index 0d265b6..f32929b 100644 --- a/aidlc-docs/active-features.md +++ b/aidlc-docs/active-features.md @@ -3,3 +3,4 @@ | Feature | Status | Branch | Affected Components | Session Start | |---------|--------|--------|---------------------|---------------| | SlpModularCms.Api Implementation (slp-modular-cms-api) | ✅ Complete | unknown | Core, Identity, Availability, Shell | 2026-06-07 | +| CMS Frontend (cms-frontend) | 🔵 Inception | unknown | Frontend, Identity (Auth), Availability | 2026-06-16 | diff --git a/aidlc-docs/features/cms-frontend/aidlc-state.md b/aidlc-docs/features/cms-frontend/aidlc-state.md new file mode 100644 index 0000000..1a1c3ae --- /dev/null +++ b/aidlc-docs/features/cms-frontend/aidlc-state.md @@ -0,0 +1,36 @@ +# AI-DLC State Tracking + +## Project Information +- **Feature Name**: CMS Frontend +- **Feature Slug**: cms-frontend +- **Project Type**: Brownfield +- **Start Date**: 2026-06-16T20:27:00Z +- **Current Stage**: INCEPTION - Requirements Analysis (awaiting question answers) +- **Branch**: unknown + +## Workspace State +- **Existing Code**: Yes (.NET API backend + example React app in ZIP) +- **Reverse Engineering Needed**: Yes (shared reverse engineering for backend; example app analyzed) +- **Workspace Root**: K:\Development\Projects\SlpModularCms + +## Code Location Rules +- **Application Code**: src/SlpModularCms.Frontend/ (new React app) +- **Feature Documentation**: aidlc-docs/features/cms-frontend/ only +- **Shared Artifacts**: aidlc-docs/_shared/ +- **Structure patterns**: See code-generation.md Critical Rules + +## Language Configuration +- **Documentation Language**: English +- **Conversation Language**: Dutch (nl) + +## Extension Configuration +[Will be populated during Requirements Analysis] + +## Stage Progress +- [x] Workspace Detection — Completed 2026-06-16T20:28:00Z +- [x] Reverse Engineering (shared) — Completed 2026-06-16T20:32:00Z — Artifacts: aidlc-docs/_shared/reverse-engineering/ +- [ ] Requirements Analysis — Not Started +- [ ] User Stories — Not Started +- [ ] Workflow Planning — Not Started +- [ ] Construction — Not Started +- [ ] Build and Test — Not Started diff --git a/aidlc-docs/features/cms-frontend/audit.md b/aidlc-docs/features/cms-frontend/audit.md new file mode 100644 index 0000000..35cb6ea --- /dev/null +++ b/aidlc-docs/features/cms-frontend/audit.md @@ -0,0 +1,49 @@ +# Audit Log — cms-frontend + +## Workspace Detection — Initial Request + +**Timestamp**: 2026-06-16T20:27:00Z + +**User Input**: "Start een aidlc workflow voor het aanmaken van de front-end. De frontend moet gebaseerd worden op een voorbeeld React-app in de volgende ZIP-bestand: "K:\Libraries\Downloads\Admin panel with dashboard.zip" Hier is een grove opzet gemaakt met een style gebaseerd op dfe hoofdkleur #ac0000 en de shadcn componenten. Met deze basis wil ik een front-end voor de CMS neerzetten." + +**AI Response**: "Started aidlc workflow for cms-frontend feature. Inspected ZIP file, analyzed existing React app structure and backend API. Created feature directory structure." + +**Context**: Workspace Detection initiated; brownfield project with existing .NET API backend and example React app in ZIP file. + +--- + +## Gap Identified — Language Preference + +**Timestamp**: 2026-06-16T20:35:00Z + +**User Input**: "Skill-creator. Waarom ben ik niet gevraagd in welke taal ik de aidlc-workflow wil doen? Volgens mij zou dat bij elke feature gevraagd moeten worden. Nu wordt de default gebruikt zonder dat ik gevraagd ben wat ik wil" + +**AI Response**: "Acknowledged gap. Created gap report at aidlc-docs/gap-reports/gap-001-language-preference-per-feature.md. User chose to continue with English documentation for cms-frontend feature." + +**Context**: User identified missing language preference question for new features in existing workspace. Gap hand-off document created. CMS frontend workflow resumes with English documentation. + +--- + +## Reverse Engineering — User Approval + +**Timestamp**: 2026-06-16T20:33:00Z + +**User Input**: "Goedkeuren en doorgaan" + +**AI Response**: "Reverse Engineering approved. Proceeding to Requirements Analysis." + +**Context**: User approved reverse engineering artifacts; Requirements Analysis phase starting. + +--- + +## Reverse Engineering — Completion + +**Timestamp**: 2026-06-16T20:32:00Z + +**User Input**: "(Automatic — triggered by Workspace Detection as no shared reverse engineering artifacts existed)" + +**AI Response**: "Generated 8 reverse engineering artifacts covering business overview, architecture, code structure, API documentation, component inventory, technology stack, dependencies, and code quality assessment." + +**Context**: Reverse Engineering completed; artifacts saved to aidlc-docs/_shared/reverse-engineering/. Awaiting user approval to proceed to Requirements Analysis. + +--- diff --git a/aidlc-docs/features/cms-frontend/inception/requirements/requirement-clarification-questions.md b/aidlc-docs/features/cms-frontend/inception/requirements/requirement-clarification-questions.md new file mode 100644 index 0000000..ea1a70f --- /dev/null +++ b/aidlc-docs/features/cms-frontend/inception/requirements/requirement-clarification-questions.md @@ -0,0 +1,23 @@ +# Requirements Clarification Questions — CMS Frontend + +I detected a contradiction in your responses that needs clarification: + +## Contradiction: Authentication Security vs. Security Baseline + +You indicated **JWT in localStorage** (Q2: A) but also **Enforce all SECURITY rules as blocking constraints** (Q11: A). + +Storing JWT tokens in `localStorage` is a known security vulnerability — XSS attacks can steal tokens from localStorage. When the Security Baseline extension is enforced, this pattern is typically flagged as a **blocking security finding**. + +This means either: +- The security baseline must be applied → the localStorage auth approach cannot be used +- The localStorage auth approach is acceptable → security baseline must be relaxed or skipped + +### Clarification Question 1 +How should this contradiction be resolved for the cms-frontend project? + +A) Use a secure authentication approach (access token in memory + refresh token in httpOnly cookie) AND keep the security baseline enforced — this is the secure production-ready choice +B) Keep localStorage for now (faster to implement, familiar) AND disable the security baseline — acceptable for a prototype/development phase +C) Keep localStorage for now AND keep the security baseline, but acknowledge and document this as an accepted risk / technical debt +X) Other (please describe after [Answer]: tag below) + +[Answer]: diff --git a/aidlc-docs/features/cms-frontend/inception/requirements/requirement-verification-questions.md b/aidlc-docs/features/cms-frontend/inception/requirements/requirement-verification-questions.md new file mode 100644 index 0000000..e35c242 --- /dev/null +++ b/aidlc-docs/features/cms-frontend/inception/requirements/requirement-verification-questions.md @@ -0,0 +1,147 @@ +# Requirements Verification Questions — CMS Frontend + +Please answer each question by filling in the letter choice after the `[Answer]:` tag. +If none of the provided options match, choose the last option and describe your preference. + +--- + +## Vraag 1: Scope van de frontend +Welke pagina's / secties moeten worden gebouwd in de eerste versie van de CMS frontend? + +A) Alleen de pagina's die al in het voorbeeld aanwezig zijn: Login, Dashboard, CMS Beheer, Gebruikersbeheer +B) Dezelfde pagina's als het voorbeeld, plus een Systeeminstellingen / Beschikbaarheid beheerpagina +C) Een uitgebreidere set: Login, Dashboard, CMS Beheer, Gebruikersbeheer, Beschikbaarheid beheer, Profiel/account instellingen +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: X, Een Login-pagina, Gebruikersbeheer, Profiel/account instellingen en systeeminstellingen. CMS beheer komt later + +--- + +## Vraag 2: Authenticatiestrategie +Hoe moet de frontend authenticatie afhandelen? + +A) JWT opslaan in localStorage (eenvoudig, minder veilig — zelfde als voorbeeld app) +B) JWT access token in geheugen (geen persistentie), refresh token in httpOnly cookie (veiliger voor productie) +C) JWT access token in geheugen, refresh token ook in geheugen (volledig stateloos — gebruiker moet opnieuw inloggen na paginaverversing) +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: A + +--- + +## Vraag 3: API-configuratie en base URL +Hoe moet de frontend-app de API-basis-URL configureren? + +A) Via een `.env` bestand (VITE_API_BASE_URL variabele) — standaard Vite aanpak +B) Hardcoded in een aparte config file (bijv. `src/config.ts`) +C) Via runtime configuratie (window.__ENV__ of een /config endpoint) +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: X, via .env, maar voor gevoelige data zoals secrets wil ik net als de backend environment variables gebruiken + +--- + +## Vraag 4: Routebeveiliging +Hoe moeten beveiligde routes worden beheerd? + +A) Eenvoudige ProtectedRoute component — redirect naar /login als niet ingelogd +B) Rolgebaseerde routebeveiliging — bepaalde pagina's alleen toegankelijk voor Owner of Admin rollen +C) Combinatie: ProtectedRoute voor auth + role guards per pagina +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: C + +--- + +## Vraag 5: Initialisatie-flow (Setup) +Moet de frontend de initialisatiestatus van het systeem afhandelen? + +A) Ja — als `/setup/status` aangeeft dat het systeem niet geïnitialiseerd is, redirect naar een Initialisatiepagina (maak eerste Owner aan) +B) Nee — de initialisatiepagina is een aparte, standalone pagina buiten de normale app-flow +C) Ja, maar combineer het als een eerste-keer-login scherm +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: A + +--- + +## Vraag 6: Gebruikersuitnodiging flow +Hoe moet de uitnodigingsstroom worden verwerkt? + +A) Volledig in de frontend: Gebruikersbeheer pagina heeft een "Uitnodigen" knop, en er is een aparte publieke pagina voor het voltooien van de account setup via uitnodigingstoken +B) Alleen de Uitnodigen-knop in Gebruikersbeheer — de complete-setup pagina is out of scope voor nu +C) Volledige flow inclusief validatie van uitnodigingstoken, foutafhandeling (verlopen/ongeldig token) en succesmelding +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: C + +--- + +## Vraag 7: CMS Beheer pagina — inhoud +Wat moet de CMS Beheer pagina tonen / doen in de eerste versie? + +A) Placeholder pagina — de CMS-inhoudmodules zijn nog niet geïmplementeerd in de backend, dus toon een lege "work in progress" sectie +B) Basis structuur gereed met navigatiestructuur voor toekomstige content modules, maar zonder echte data +C) Volledig functionele pagina als de backend-modules al beschikbaar zijn (geef aan welke) +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: B + +--- + +## Vraag 8: Beschikbaarheid beheer +Moet de frontend een pagina hebben voor het beheren van de systeembeschikbaarheid? + +A) Ja — een pagina (alleen voor Owners) om de status in te stellen (Available/Maintenance/Unavailable) met optioneel bericht +B) Nee — beschikbaarheidsstatus enkel tonen als readonly indicator in het dashboard +C) Ja, maar als onderdeel van een bredere Instellingen-pagina in plaats van een eigen pagina +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: X, De beschikbaarheidsmodule is een core functionaliteit die uit 2 modules zal bestaand. De master en client modules waar de master module de status beheert van de client modules/CMS-en. De master-module is nog niet gebouwd. Als voorbereiding zou je op het dashboard kunnen laten zien "Beschikbaar" of "Niet beschikbaar" met een reden erbij. + +--- + +## Vraag 9: Donker/licht thema +Moet de frontend ondersteuning bieden voor donker/licht thema? + +A) Ja — donker en licht thema wisselen via een schakelaar (next-themes zoals in voorbeeld app) +B) Nee — alleen licht thema in eerste versie +C) Alleen donker thema +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: A + +--- + +## Vraag 10: Locatie van de frontend in het project +Waar moet de React app worden geplaatst in de projectstructuur? + +A) `src/SlpModularCms.Frontend/` (naast de .NET projecten in de `src/` map) +B) `frontend/` (aparte map op het root niveau van de solution) +C) `client/` (aparte map op root niveau) +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: B + +--- + +## Vraag 11: Beveiligingsextensies +Moeten de beveiligingsregels als harde vereisten worden afgedwongen voor dit project? + +A) Ja — dwing alle BEVEILIGINGSREGELS af als blokkerende vereisten (aanbevolen voor productietoepassingen) +B) Nee — sla alle BEVEILIGINGSREGELS over (geschikt voor PoC's, prototypes en experimentele projecten) +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: A + +--- + +## Vraag 12: Property-Based Testing Extensie +Moeten de property-based testing (PBT) regels worden afgedwongen voor dit project? + +A) Ja — dwing alle PBT-regels af als blokkerende vereisten +B) Gedeeltelijk — dwing PBT-regels alleen af voor pure functies en serialisatie round-trips +C) Nee — sla alle PBT-regels over (geschikt voor UI-projecten zonder complexe bedrijfslogica) +X) Anders (beschrijf hieronder na de [Answer]:-tag) + +[Answer]: C diff --git a/aidlc-docs/gap-reports/gap-001-language-preference-per-feature.md b/aidlc-docs/gap-reports/gap-001-language-preference-per-feature.md new file mode 100644 index 0000000..0a13896 --- /dev/null +++ b/aidlc-docs/gap-reports/gap-001-language-preference-per-feature.md @@ -0,0 +1,73 @@ +# Gap Report: Language Preference Not Asked Per Feature + +**Gap ID**: gap-001 +**Reported**: 2026-06-16 +**Reporter**: User (via cms-frontend workflow session) +**Skill affected**: `aidlc-workflow` +**Rule file affected**: `.aidlc-rule-details/inception/workspace-detection.md` + +--- + +## Problem Description + +The `aidlc-workflow` skill currently asks for language preference **only once** at the start of a **brand new workspace** (when no `active-features.md` or legacy `aidlc-state.md` exists). This is defined in **Step 2.5** of `workspace-detection.md`: + +> **Step 2.5: Ask Language Preference (New Workspace Only)** +> Ask this question **once**, at the start of a brand new workspace (no `active-features.md`, no legacy `aidlc-state.md`). + +### Observed Behavior +When a user starts a **new feature** in an existing multi-feature workspace (where `active-features.md` already exists), the language preference question is **skipped** and the default (English documentation) is used without consulting the user. + +### Expected Behavior +The language preference should be asked **for each new feature** being started, not only on workspace initialization. Each feature can independently have its own language configuration stored in its `aidlc-state.md`. + +--- + +## Impact + +- Users are not given the opportunity to choose documentation language when adding features to an existing workspace +- The default (English) is silently applied without user consent +- The `Language Configuration` in `aidlc-state.md` is set without user input + +--- + +## Suggested Fix + +Update `workspace-detection.md` **Step 2.5** to trigger on **new feature creation** rather than only on new workspace initialization: + +**Current behavior**: +- Step 2.5 fires only when NO `active-features.md` exists (brand new workspace) + +**Desired behavior**: +- Step 2.5 fires when creating **any new feature** (i.e., after Step 4b — Create Feature Directory Structure), regardless of whether the workspace is new or existing + +**Implementation hint**: +- Move/expand the language preference question trigger from "new workspace only" to "new feature only" +- The existing feature's language config (if resuming) should be read from `aidlc-state.md` without asking again +- The question should be presented BEFORE creating the feature's `aidlc-state.md`, or immediately after the directory structure is created, so the answer can be stored correctly + +--- + +## Related Files + +- Skill: `C:\Users\Bryan\.junie\skills\aidlc-workflow\` +- Rule file: `.aidlc-rule-details/inception/workspace-detection.md` — Step 2.5 +- State file template: Step 4c in `workspace-detection.md` — `## Language Configuration` section + +--- + +## Workaround (for current session) + +The cms-frontend feature in `K:\Development\Projects\SlpModularCms` was created with the default English documentation language. If the user wants a different language, manually update: + +`aidlc-docs/features/cms-frontend/aidlc-state.md` → `## Language Configuration` + +--- + +## Acceptance Criteria for Fix + +- [ ] Starting a NEW feature in an existing workspace triggers the language preference question +- [ ] Resuming an EXISTING feature does NOT ask the language question again (read from aidlc-state.md) +- [ ] The language preference is stored in the feature's `aidlc-state.md` under `## Language Configuration` +- [ ] Both the SKILL.md and `workspace-detection.md` rule file are updated consistently +- [ ] The `common/session-continuity.md` On Resume instruction is verified to still correctly read from state (no change needed there)