# CLAUDE.md – peakUp Project Guidelines **Last updated:** 2026-05-15 | Single source of truth. Strict compliance required. ## 1. Core Rules - Never assume. Always read files first with tools. - Validate state before and after changes using terminal commands. - Remove dead/unreachable code immediately (ask first if unsure). - Trivial tasks: Ask "Trivial? Direct edit or full workflow?" ## 2. Mandatory 4-Phase Workflow 1. **PROPOSAL** – Clear plan + impact. Wait for `OK PROPOSAL`. 2. **VALIDATE** – Brutal self-critique (NullAway, layering, regressions). Wait for `OK VALIDATE`. 3. **IMPLEMENT** – One unit at a time. Show exact diff only. 4. **VERIFICATION** – Run relevant tests. Suggest commit message. ## 3. Project Overview - **Backend**: Quarkus (Java 21), Hibernate, PostgreSQL/TimescaleDB - **Frontend**: Vite + React 18 + TS + Tailwind + shadcn/ui - **Model**: Shared domain models - **Tools**: `peakup-maven` – Maven plugin with two mojos: `PackageInfoGeneratorMojo` (generates `package-info.java` with `@NonNull` per package) and `TypeScriptClientGeneratorMojo` (generates TS client from REST endpoints) - **Tools**: `peakup-tools` – standalone dev utilities: - `ModelGeneratorTool` – generates a full domain slice (entity, DAO, service, resource) from a JSON definition file. Schema: `peakup-tools/src/main/resources/model-definition-schema.json` Example: `peakup-tools/src/main/resources/example/example-model-definition.json` Models are stored: `src/main/resources/definitions` Run (from project root): ``` # Normal run — fails if any output file already exists, generates Flyway migration $MVN -f peakup-tools/pom.xml -Dmaven.repo.local=/home/ingo/.m2/peak-repo \ compile exec:java -Dexec.mainClass=com.peakup.tools.generator.ModelGeneratorTool \ "-Dexec.args=path/to/definition.json" # --force — overwrites existing files, skips Flyway migration generation $MVN -f peakup-tools/pom.xml -Dmaven.repo.local=/home/ingo/.m2/peak-repo \ compile exec:java -Dexec.mainClass=com.peakup.tools.generator.ModelGeneratorTool \ "-Dexec.args=--force path/to/definition.json" ``` Output defaults to `peakup-backend/src/main/java/`. Pass a second arg to override output dir, third arg to override Flyway migration dir (default: `peakup-backend/src/main/resources/db/migration/`). Generated service only contains `getDAO()` + domain-specific methods — CRUD is inherited from `AbstractService` as `public final @Transactional`. **Backend Architecture**: - Domain slices: `model` → `dao` → `service` - Connectors: `connector/` with full layer (`model` → `dao` → `service` → `client` → `mapper`) - External mapping logic **must** be in `connector//mapper/` ## 4. Technical Rules **Java / Backend** - Java 21 + Quarkus - Strict NullAway + mandatory `final` where possible - Lombok: `@Data`, `@NoArgsConstructor`, `@AllArgsConstructor`, `@Slf4j` - Checkstyle: 4 spaces, 240 char max line, K&R braces, no star imports - Methods: preferred < 60 lines (blank lines excluded), max 7 parameters - **Type safety is mandatory**: use native types throughout — `Instant`/`LocalDate` for dates, `Long`/`Integer` for IDs and counts, enums for fixed value sets. Never pass dates, IDs, or enums as `String` across layer boundaries. REST DTOs are the only exception — parse to native types immediately at the boundary. - Use `AbstractEntity` and `AbstractTimestampedEntity` - TimescaleDB hypertables via `AbstractTimescaleEntity` **Frontend** - `peakup-frontend/src/types/` and `peakup-frontend/src/api/` are **generated** – never edit manually. - Light mode only (`#FFFFFF`) - Accent: `from-red-500 to-orange-500` only for CTAs & charts - TanStack Query v5 + TanStack Table v8 - Minimize `useEffect` for data fetching - Charts: Recharts (responsive) ## 5. Naming Conventions - Use full, meaningful names everywhere. - No abbreviations: `athleteService`, `intervalCount`, `workplan` (not `svc`, `n`, `w`) - Avoid `e`, `ex`, `obj`, `res`, `tmp`, `data` etc. - Exception: `i`, `j` only in short numeric loops. ## 6. Design Violations (Fix when touching) - Move mapping logic from importers into dedicated mappers - Move `ActivityConnector` implementations into `connector//` - Extract `IntervalsEnrichmentStatusEnum` and `AbstractEnumConverter` ## 7. Useful Commands - `$MVN` = `JAVA_HOME=/home/ingo/.jdks/temurin-21.0.7 mvn -s /home/ingo/.m2/settings_peak.xml` - Backend: `$MVN compile`, `quarkus:dev`, `test -Dtest=ClassName` - Frontend: `npm run dev`, `npm run build`, `npm run lint` --- **Style for Claude**: Be concise. Show **only** changed code + short explanation. Ask before large refactors.