5.2 KiB
5.2 KiB
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 |
| 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
referencekey (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: trueshows "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
# 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:
- Frontend:
pnpm run api:generate(TypeScript client) - 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
- API-first workflow - ALWAYS follow this sequence when modifying APIs:
a. Modify
api/legalconsenthub.ymlOpenAPI spec first b. Regenerate frontend client:cd legalconsenthub && pnpm run api:generatec. Regenerate backend stubs:cd legalconsenthub-backend && ./gradlew generate_legalconsenthub_serverd. Implement backend controller methods (they implement generated interfaces) e. Use generated client in frontend (never write manual API calls) - Organization context - Always consider
organizationIdfor multi-tenancy. Forms with empty/null organizationId are "global" forms visible to all organizations - Form structure is 3-level - Section → SubSection → Element
- Roles managed in Keycloak - Not in application database
- Subproject-specific rules - See
CLAUDE.mdfiles in each subproject directory
Code Style
- Order functions top-down by abstraction (public API first, helpers below)
- Keep
CLAUDE.mdfiles 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