Skip to content

Latest commit

 

History

History
111 lines (84 loc) · 6.43 KB

CLAUDE.md

File metadata and controls

111 lines (84 loc) · 6.43 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Vaadin Flow 25.1 web application template using Java 26, packaged as a WAR, deployed on Jetty 12.1. Uses vaadin-core (free components only, Hilla disabled). Parent POM is com.svenruppert:dependencies:06.02.02 which provides plugin and dependency version management. pom.xml is the authoritative version reference — see "Source of truth" at the end of this file.

Build & Run Commands

# Run dev server (default goal is jetty:run)
./mvnw

# Compile only
./mvnw compile

# Run unit tests
./mvnw test

# Run a single test
./mvnw test -Dtest=ClassName#methodName

# Production build (optimized frontend bundle)
./mvnw package -Pproduction

# Mutation testing with PiTest + per-package coverage gate
./mvnw -P_mutation-gate \
       org.pitest:pitest-maven:mutationCoverage \
       verify

# Standalone fat-jar (java -jar target/application.jar)
./mvnw -P_shadejar -DskipTests package

# Check for dependency updates
./mvnw versions:display-dependency-updates

Architecture

  • AppShell (com.svenruppert.flow.AppShell) - App shell configurator. Sets viewport, PWA metadata, the my-theme Lumo theme, and enables @Push (server push via WebSocket).
  • AppServlet (com.svenruppert.flow.AppServlet) - Custom VaadinServlet. Mapped + configured via src/main/webapp/WEB-INF/web.xml, where the critical i18n.provider init-param points at com.svenruppert.flow.i18n.AppI18NProvider (Vaadin V25 ignores META-INF/services for I18NProvider).
  • MainLayout (com.svenruppert.flow.views.MainLayout) - AppLayout with brand mark + role-gated drawer + locale/theme switchers + auth-action button. All routed views use this as their parent layout.
  • Views are in com.svenruppert.flow.views (and .views.main). Each view declares a public static final String PATH (or NAV) constant used for routing and nav links.
  • i18n - Translation bundles in src/main/resources/vaadin-i18n/translations*.properties. Views implement I18nSupport and call tr(K_KEY, "English fallback"). Custom AppI18NProvider defeats the JVM-default-locale ResourceBundle fallback bug.
  • Storage paths - Single point of truth: com.svenruppert.flow.security.storage.AppStoragePaths. Production defaults to ./data/; tests fork with -Dapp.storage.dir=target/test-data via Surefire <systemPropertyVariables>.
  • Frontend - Custom theme at src/main/frontend/themes/my-theme/, view-specific CSS in src/main/frontend/styles/. The generated/ directory is auto-generated by Vaadin and should not be edited.

Key Configuration

  • .mvn/maven.config forces -U (update snapshots), strict test failures, verbose plugin validation.
  • .mvn/jvm.config sets heap limits and --enable-native-access=ALL-UNNAMED.
  • Maven enforcer requires Maven >= 3.9.9.
  • PiTest targets com.svenruppert.* prod classes and junit.com.svenruppert.* test classes.
  • Test convention: test classes go under junit.com.svenruppert.* package (not the standard com.svenruppert.*).
  • Surefire passes -Dapp.storage.dir=${project.build.directory}/test-data so tests never touch the repo-rooted ./data/ tree.
  • Surefire also passes -Dapp.hibp.enabled=false so PasswordPreflight skips the Have-I-Been-Pwned k-anonymity range call. Production runs leave this unset (default = true); the HIBP layer is fail-open on network errors (CWE-359), so a network outage never blocks legitimate password changes.

Profiles

  • production - Vaadin production frontend build with optimized bundle.
  • _java - Additional compiler setup with newer ASM (9.8) for Java 26 support.
  • _shadejar - Builds a standalone Jetty fat-jar named application.jar (uses nano-vaadin-jetty 04.00.00).
  • _mutation-gate - Runs PIT mutation coverage + tools/pit-gate.sh to enforce per-package floors (build fails on regression).

Source of truth

pom.xml is the authoritative version reference for: parent POM version, JDK version, Vaadin version, Jetty version, jSentinel version, nano-vaadin-jetty version. Update it first, then mirror values into CLAUDE.md and AGENTS.md. Cross-check with:

./mvnw versions:display-dependency-updates

The current versions snapshot is:

Property Value
Parent (com.svenruppert:dependencies) 06.02.02
JDK / maven.compiler.release 26
vaadin.version 25.1.1
jetty.version 12.1.8
jsentinel.version 00.74.00
nano-vaadin-jetty.version 04.00.00

Implementierungszyklus

Follow the global implementation-cycle skill. Project-pluggable slots:

  • Tracker = ClickUp (workspace 2443039, folder svenruppert 90150380304).
    • Plan + per-issue: list publikationsverwaltung (901524338583)
    • Concepts: publikationsverwaltung-concepts (901524338584), Open → deployed
    • Features: publikationsverwaltung-features (901524338585)
  • Status mapping: Open (not started) → in progress → Closed (completed). Concept task: Open → deployed. (review/on-hold/testing/bugfixing/release prepared/skipped also exist.)
  • Sync mechanic: ClickUp status field + a ## Completion log appended to the task's markdown_description (date, commit hash, what shipped, acceptance result). Parent gets status only.
  • Build/test: ./mvnw test; acceptance per issue = module test green + full ./mvnw clean verify when a shared/parent file changed.
  • Mutation gate: ./mvnw -P_mutation-gate org.pitest:pitest-maven:mutationCoverage verify (floors in tools/pit-baselines.txt; add a line per new package).
  • Publish/deploy: WAR via ./mvnw clean package -Pproduction → target/ROOT.war; optional fat-jar via _shadejar. Tag scheme v<X.Y.Z>.
  • Version/modules: single-module WAR, -SNAPSHOT working line, finalize-strip before release. Domain code lives in com.svenruppert.publications; views stay under com.svenruppert.flow.views.
  • Standards pass: /java-standards-pass (haslogger, httpstatus, mediatype, result, vaadin-i18n).
  • Commit/branch: work on the integration branch directly; push is the human's decision; never an AI-attribution / "generated with" footer.

Non-negotiable status discipline: every issue moves to in progress when work begins and to Closed only when done — no issue stays Open while worked on, and none jumps Open → Closed directly. The board reflects the real state of work at all times.