# Legal Consent Hub - AI Context ## Overview Platform for digital applications, approvals, and discussions with GDPR compliance features. Enables organizations to create, manage, and track application forms with version control and PDF export. --- ## Architecture | Layer | Stack | |-------|-------| | **Frontend** | Nuxt 4.2.0, Vue 3, Nuxt UI 4.3.0, Pinia, TypeScript, i18n (de/en) | | **Backend** | Spring Boot 3.4.2, Kotlin 1.9.25, Java 21, PostgreSQL, Liquibase | | **Auth** | Keycloak (OAuth2/JWT), nuxt-auth-utils | | **PDF** | LaTeX (lualatex) via Thymeleaf templates | | **API** | OpenAPI 3.0.3 spec → auto-generated clients | --- ## Form Structure (3-Level Hierarchy) ``` ApplicationForm └── Section (FormElementSection) ├── title, shortTitle, description ├── isTemplate, templateReference, titleTemplate ← for spawning └── SubSection (FormElementSubSection) └── FormElement ├── id (UUID), reference (string key) ├── type: SELECT | CHECKBOX | RADIOBUTTON | TEXTFIELD | TEXTAREA | SWITCH | RICH_TEXT | DATE | TABLE ├── options: FormOption[] (value, label, processingPurpose, employeeDataCategory, columnConfig) ├── visibilityConditions[] (AND logic) ├── sectionSpawnTriggers[] ├── isClonable, tableRowPreset ``` --- ## Key Features ### Visibility Conditions - Elements shown/hidden based on other element values - Multiple conditions use **AND logic** - Operators: `EQUALS`, `NOT_EQUALS`, `IS_EMPTY`, `IS_NOT_EMPTY` - Reference elements by `reference` key (not ID) - Hidden elements: excluded from validation, PDF export, and values cleared ### Section Spawning - Template sections (`isTemplate: true`) spawn when trigger conditions met - Title interpolation: `{{triggerValue}}` placeholder - Spawned sections linked via `spawnedFromElementReference` - One element can have multiple `sectionSpawnTriggers` ### Clonable Elements - `isClonable: true` shows "Add another" button - Deep cloning with auto-generated references (`modul_1` → `modul_2`) - Values reset on clone (TEXTAREA/TEXTFIELD) ### Table Cross-References - Column references other table's column: `columnConfig.sourceTableReference` - Row presets from source table: `tableRowPreset` - Filter conditions limit available values --- ## Roles (Keycloak-managed) `CHIEF_EXECUTIVE_OFFICER`, `BUSINESS_DEPARTMENT`, `IT_DEPARTMENT`, `HUMAN_RESOURCES`, `HEAD_OF_WORKS_COUNCIL`, `WORKS_COUNCIL`, `EMPLOYEE` --- ## Project Structure ``` legalconsenthub/ # Frontend (Nuxt 4, Vue 3) - see legalconsenthub/CLAUDE.md api/ # OpenAPI spec - see api/CLAUDE.md legalconsenthub-backend/ # Backend (Spring Boot, Kotlin) - see legalconsenthub-backend/CLAUDE.md ``` --- ## Development ```bash # Frontend (port 3001) cd legalconsenthub && pnpm install && pnpm run dev # Backend (port 8080) cd legalconsenthub-backend && ./gradlew bootRun # Generate API clients (REQUIRED after modifying api/legalconsenthub.yml) cd legalconsenthub && pnpm run api:generate # Frontend TypeScript client cd legalconsenthub-backend && ./gradlew generate_legalconsenthub_server # Backend Kotlin server stubs ``` **⚠️ CRITICAL: API Client Regeneration** After ANY change to `api/legalconsenthub.yml`, you MUST regenerate BOTH clients: 1. Frontend: `pnpm run api:generate` (TypeScript client) 2. Backend: `./gradlew generate_legalconsenthub_server` (Kotlin server stubs) Compilation/runtime will fail if clients are out of sync with the OpenAPI spec. --- ## Key Files | File | Purpose | |------|---------| | `api/legalconsenthub.yml` | OpenAPI spec (source of truth) | | `.github/workflows/pipeline.yaml` | CI/CD workflow | See subproject CLAUDE.md files for component-specific key files. --- ## Rules for AI 1. **API-first workflow** - ALWAYS follow this sequence when modifying APIs: a. Modify `api/legalconsenthub.yml` OpenAPI spec first b. Regenerate frontend client: `cd legalconsenthub && pnpm run api:generate` c. Regenerate backend stubs: `cd legalconsenthub-backend && ./gradlew generate_legalconsenthub_server` d. Implement backend controller methods (they implement generated interfaces) e. Use generated client in frontend (never write manual API calls) 2. **Organization context** - Always consider `organizationId` for multi-tenancy. Forms with empty/null organizationId are "global" forms visible to all organizations 3. **Form structure is 3-level** - Section → SubSection → Element 4. **Roles managed in Keycloak** - Not in application database 5. **Subproject-specific rules** - See `CLAUDE.md` files in each subproject directory ### Code Style - Order functions top-down by abstraction (public API first, helpers below) - Keep `CLAUDE.md` files updated when introducing architectural changes ### Playwright CLI - When using the Playwright CLI, an authentication is needed - Use the following credentials for testing: - Username: denis - Password: 123 - The login is 2-step: first submit the username, then the password on the next screen - Prefer the playwright-cli always over the Playwright MCP