Files
gremiumhub/CLAUDE.md

7.5 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
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_1modul_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

# 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

Seed Data Maintenance

The application automatically seeds initial data on first startup:

1. Template Seeding

Seeder: InitialApplicationFormTemplateSeeder File: legalconsenthub-backend/src/main/resources/seed/initial_application_form_template.yaml Condition: Seeds if no templates exist (isTemplate = true) Purpose: Comprehensive IT system approval workflow template

IMPORTANT: Keep this file updated when form structure or validation rules change.

2. Application Form Seeding

Seeder: InitialApplicationFormSeeder File: legalconsenthub-backend/src/main/resources/seed/initial_application_form.yaml Condition: Seeds if no forms exist for empty organizationId (isTemplate = false) Purpose: Realistic SAP S/4HANA application form for development and UI testing organizationId: Empty string (global form visible to all organizations) Content: Pre-filled IT system introduction form based on the template structure with realistic SAP S/4HANA values

IMPORTANT: Keep this file synchronized with template changes. When template structure changes, update the demo form accordingly.

Note:

  • Forms with empty/null organizationId act as "global" forms and are visible to all organizations
  • This allows the demo form to appear regardless of the current organization context
  • The demo form is derived from the template structure with values filled for realistic testing
  • Demonstrates visibility conditions, section spawning, clonable elements, and GDPR compliance features

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 (isTemplate=true)
legalconsenthub-backend/src/main/resources/seed/initial_application_form.yaml SAP S/4HANA demo application form (global, filled with realistic values)
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. Forms with empty/null organizationId are "global" forms visible to all organizations
  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