# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Boxit (also called "Remsly" in CI) is a box/inventory management app: - **backend/** — Spring Boot 2.6 (Kotlin, Java 17, Jersey + Spring MVC), PostgreSQL via jOOQ, Elasticsearch for search, Keycloak for auth. Runs on port **5050**. - **frontend/** — Angular 13 app (port **4200**), proxies `/api` to the backend via `proxy-conf.json`. - **JooqHelper/** — small Gradle module providing `BoxitNamingStrategy` used by jOOQ code generation. - **deploy/localDev/boxit/** — docker-compose for local infrastructure (Postgres on 6543, Keycloak on 8081, Apache OIDC proxy, Elasticsearch, Prometheus). - **deploy/prod/** — production docker-compose + Let's Encrypt scripts. - **clients/** — IntelliJ HTTP client files for the REST API, Keycloak, and Elasticsearch (env in `http-client.private.env.json`, template provided). ## Commands ### Backend (Gradle, from repo root) ```bash ./gradlew build # build + tests (requires running Postgres, see below) ./gradlew test # tests only (JUnit 5; integration tests use Testcontainers) ./gradlew generateJooq # run Flyway migrations, then regenerate jOOQ classes ./gradlew lintKotlin # kotlinter lint ./gradlew formatKotlin # kotlinter autoformat ./gradlew bootRun # run the backend ``` Run a single test class: `./gradlew test --tests "ch.boxi.boxit.SomeTestClass"` DB connection for Flyway/jOOQ codegen is parameterized via Gradle properties `-PDB_HOST_PORT -PDB_USER -PDB_PASSWD -PDB_NAME` (defaults: `localhost:6543`, `gradle`/`gradlepw`/`gradle` — matches the localDev docker-compose Postgres). ### Frontend (from frontend/) ```bash npm start # dev server on :4200 with /api proxy to :5050 npm run build # dev build npm run buildProd # production build (also copies index.html -> 404.html) npm test # Karma/Jasmine tests npm run lint # ng lint ``` ### Local infrastructure ```bash cd deploy/localDev/boxit && docker compose up -d ``` Provides Postgres (port 6543, multiple DBs: `boxit`, `keycloak`, `gradle`, `test`), Keycloak (8081), Apache OIDC proxy, and Elasticsearch. `backend/src/main/resources/application.properties` is not committed — create it from `application.properties-Template`. ## Architecture ### Backend data flow: Flyway → jOOQ codegen The DB schema is the source of truth. Migrations live in `backend/src/main/resources/db/migration` (Flyway, `V*.sql`). `generateJooq` depends on `flywayMigrate` and generates records/POJOs/DAOs into `backend/src/gen/java` (package `ch.boxi.boxit.gen`, deleted on `clean`, regenerated on compilation). Naming is customized by `JooqHelper`'s `BoxitNamingStrategy`. **After changing a migration, re-run `./gradlew generateJooq` against a running Postgres.** ### Backend layers (`ch.boxi.boxit`) - `restapi/` — REST controllers, DTOs, mappers, pagination (`Paged`, `PaginationDto`, infinite scroll support). Organized by feature (folder, note, task, user, search). - `domain/` — business logic per feature (attachment, folder, location, note, task, user). Uses a Visitor pattern (`Visitable`/`Visitor`) and `Augmentor` abstractions. - `db/` — jOOQ-based repositories built on `SimpleCrudRepository` / `AbstractSimpleCrudRepositoryImpl` plus composable `JooqFilter` classes (`CombinedAndFilter`, `CombinedOrFilter`, ...). - `searchindex/` — Elasticsearch index per feature (folder, note, task) with its own migration support; `db/elasticsearchSync` + `domain/elasticSearchSync` implement DB→ES synchronization. - `clientapi/` — outbound HTTP clients (e.g. OpenStreetMap geocoding). - `security/` — Keycloak/OIDC config and SSL client config (`SSLClientConfig` pins outbound HTTPS to TLS 1.2; trust uses the JVM default cacerts — no custom truststore). ### Frontend layers (`frontend/src/app`) - `api/` — `boxit.api.ts` + DTOs + HTTP error interceptor (mirror of the backend REST API). - `business/` — services/models per feature (item, attachment, location, user), notification and global error handling. - `gui/` — components (header, page, search, filters, item, location, responsive helpers). - `auth/` — `auth.service.ts` (Keycloak-based login). ### Testing Backend integration tests (`BoxitIntegrationTest`) use Testcontainers. For container reuse, add `testcontainers.reuse.enabled=true` to `~/.testcontainers.properties`. ### CI Gitea Actions (`.gitea/workflows/`) builds on push to `main`: Gradle build with a Postgres service container, then builds/pushes Docker images (`*-backend`, `*-frontend`) to `gitea.tail276105.ts.net` and triggers a prod compose redeploy. `bitbucket-pipelines.yml` and `.space.kts` are legacy.