169 lines
5.8 KiB
Markdown
169 lines
5.8 KiB
Markdown
# 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
|
|
|
|
---
|
|
|
|
## Composables
|
|
|
|
| Composable | Purpose |
|
|
|------------|---------|
|
|
| `useFormElementVisibility` | Evaluate visibility conditions |
|
|
| `useSectionSpawning` | Process spawn triggers, clone templates |
|
|
| `useClonableElements` | Clone elements with reference generation |
|
|
| `useFormElementValueClearing` | Clear values when elements become hidden |
|
|
| `useTableCrossReferences` | Resolve table column/row references |
|
|
| `useApplicationFormValidator` | Form validation rules |
|
|
| `useLogger` | Consola logger instance |
|
|
|
|
---
|
|
|
|
## API Endpoints
|
|
|
|
```
|
|
# Forms
|
|
GET/POST /application-forms
|
|
GET/PUT/DELETE /application-forms/{id}
|
|
POST /application-forms/{id}/submit
|
|
|
|
# Templates
|
|
GET/POST /application-form-templates
|
|
GET/PUT/DELETE /application-form-templates/{id}
|
|
|
|
# Versions
|
|
GET /application-forms/{id}/versions
|
|
GET /application-forms/{id}/versions/{n}
|
|
POST /application-forms/{id}/versions/{n}/restore
|
|
GET /application-forms/{id}/versions/{n}/pdf
|
|
|
|
# Comments
|
|
GET /application-forms/{id}/comments
|
|
POST /application-forms/{id}/form-elements/{elementId}/comments
|
|
PUT/DELETE /comments/{id}
|
|
|
|
# Notifications
|
|
GET /notifications?organizationId=
|
|
GET /notifications/unread/count?userId=&organizationId= (public)
|
|
PUT /notifications/{id}/mark-read
|
|
PUT /notifications/mark-all-read
|
|
DELETE /notifications/clear-all
|
|
```
|
|
|
|
---
|
|
|
|
## Roles (Keycloak-managed)
|
|
|
|
`CHIEF_EXECUTIVE_OFFICER`, `BUSINESS_DEPARTMENT`, `IT_DEPARTMENT`, `HUMAN_RESOURCES`, `HEAD_OF_WORKS_COUNCIL`, `WORKS_COUNCIL`, `EMPLOYEE`
|
|
|
|
---
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Frontend (port 3001)
|
|
cd legalconsenthub && pnpm install && pnpm run dev
|
|
|
|
# Backend (port 8080)
|
|
cd legalconsenthub-backend && ./gradlew bootRun
|
|
|
|
# Generate API clients
|
|
pnpm run api:generate # Frontend
|
|
./gradlew generate_legalconsenthub_server # Backend
|
|
```
|
|
|
|
---
|
|
|
|
## Key Files
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `api/legalconsenthub.yml` | OpenAPI spec (source of truth) |
|
|
| `legalconsenthub-backend/src/main/resources/templates/application_form_latex_template.tex` | PDF template |
|
|
| `legalconsenthub-backend/src/main/resources/seed/initial_application_form_template.yaml` | Initial form template |
|
|
| `legalconsenthub-backend/src/main/resources/db/changelog/` | Liquibase migrations |
|
|
| `.github/workflows/pipeline.yaml` | CI/CD workflow |
|
|
|
|
---
|
|
|
|
## Rules for AI
|
|
|
|
1. **Never auto-generate SQL migrations** - Liquibase migrations are manual
|
|
2. **Use mapper classes** for all DTO↔Entity conversions (never in services/controllers)
|
|
3. **No hardcoded UI strings** - Use i18n (`de.json`, `en.json`)
|
|
4. **API-first** - Modify OpenAPI spec, then regenerate clients
|
|
5. **Organization context** - Always consider `organizationId` for multi-tenancy
|
|
6. **Form structure is 3-level** - Section → SubSection → Element
|
|
7. **Roles managed in Keycloak** - Not in application database
|
|
8. **Nuxt UI 4** - For any UI-related questions, use the Nuxt UI MCP server to get current component docs and examples
|
|
|
|
### PDF Export Validation
|
|
After changes to form elements, visibility, or spawning:
|
|
- Test both HTML and PDF export for real form instances
|
|
- Verify all element types render correctly
|
|
- Ensure template sections excluded, spawned sections included
|
|
- Hotspots: `ApplicationFormFormatService.kt`, `application_form_latex_template.tex`
|
|
|
|
### Code Style
|
|
- Order functions top-down by abstraction (public API first, helpers below)
|
|
- Keep `CLAUDE.md` updated when introducing architectural changes
|