Files
gremiumhub/CLAUDE.md

5.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 (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 MCP

  • When using the Playwright MCP, 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