Files
gremiumhub/CLAUDE.md

4.1 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

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 (after modifying api/legalconsenthub.yml)
pnpm run api:generate                    # Frontend client
./gradlew generate_legalconsenthub_server # Backend server stubs

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 modify OpenAPI spec first, then regenerate clients
  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