# AGENTS.md — BilHej / Bilhälsning.se Project-specific instructions for OpenCode. Commit this file. --- ## Project Identity BilHej is a web platform letting Swedish residents send physical letters to vehicle owners by entering a registration number. The sender composes a letter, pays 49 SEK, and BilHej prints+mails it via PostNord. The sender never sees the recipient's name or address. **Phase 0 (current):** Manual workflow. No Transportstyrelsen or PostNord API integration yet. Owner address is obtained manually by a human and entered into the admin panel. Tech stack: Vue.js 3 (Vite, Pinia) frontend + Java 21 Spring Boot 4 backend + PostgreSQL 16. Deployed via Docker Compose. --- ## Build, Lint, Test & Run Commands Always run these after making changes to verify nothing is broken. Gradle lives at repo root. All commands below run from the repo root unless noted. ### Quick start (everything) ```bash cp .env.example .env # first time only, then fill in keys docker compose up -d # starts postgres, backend, frontend ./gradlew up # same as above (Gradle wrapper) ``` ### All-in-one ```bash ./gradlew check # frontend lint → frontend test → backend test → integration test ./gradlew up # docker compose up -d ./gradlew down # docker compose down ./gradlew reset # docker compose down -v && docker compose up -d (full DB reset) ``` ### Frontend (Vue.js 3 + Vite) ```bash cd frontend npm install # first time only npm run dev # dev server on :3000 with HMR npm run build # production build npm run lint # ESLint npm run test # vitest ``` ### Backend (Spring Boot 4 + Java 21) ```bash ./gradlew :backend:bootRun # dev server on :8080 ./gradlew :backend:test # JUnit 5 + Mockito (backend only) ``` ### Stripe webhooks (local testing) ```bash stripe listen --forward-to localhost:8080/api/webhooks/stripe ``` ### Database Flyway migrations run automatically on Spring Boot startup. Migration files live in `backend/src/main/resources/db/migration/`. Naming: `V__descriptive_name.sql`. To reset: `docker compose down -v && docker compose up -d`. --- ## Project Structure ``` bilhej/ ├── frontend/ # Vue.js 3 SPA (Vite) │ ├── src/ │ │ ├── pages/ # Route-level page components │ │ ├── components/ # Reusable UI components │ │ ├── composables/ # useXxx.ts shared logic │ │ ├── stores/ # Pinia stores │ │ ├── api/ # API client modules │ │ ├── router/ # Vue Router config │ │ └── assets/ # Static files, CSS │ └── ... ├── backend/ # Spring Boot 4 (Java 21) — Gradle subproject │ ├── build.gradle # Spring Boot plugin, Java deps, test config │ ├── src/main/java/se/bilhalsning/ │ │ ├── config/ # @Configuration classes │ │ ├── controller/ # REST controllers │ │ ├── dto/ # Request/response DTOs │ │ ├── entity/ # JPA entities │ │ ├── repository/ # Spring Data JPA repos │ │ ├── service/ # Business logic │ │ ├── security/ # JWT filter, UserDetailsService │ │ ├── exception/ # Custom exceptions + @ControllerAdvice │ │ └── mapper/ # Entity ↔ DTO mapping │ └── src/main/resources/ │ ├── application.yml # default (H2, IDE dev) │ ├── application-docker.yml # docker profile (PostgreSQL) │ └── db/migration/ # Flyway migrations ├── docker/ # Dockerfiles │ ├── backend.Dockerfile # dev: JDK 21 + gradle :backend:bootRun │ ├── backend.prod.Dockerfile # prod: multi-stage (Gradle build → JRE Alpine, non-root) │ ├── frontend.Dockerfile # dev: Node 24 + vite dev server │ ├── frontend.prod.Dockerfile # prod: multi-stage (Node build → nginx) │ ├── nginx.conf # prod: SPA fallback + /api reverse proxy │ └── entrypoint.sh # prod: self-signed cert generation ├── docker-compose.yml # dev: postgres + backend (bootRun) + frontend (Vite HMR) ├── docker-compose.prod.yml # prod: multi-stage images, no source mounts, restart always ├── gradlew # Gradle wrapper (repo root) ├── gradle/ │ └── wrapper/ ├── settings.gradle # rootProject.name + include 'backend' ├── build.gradle # convenience tasks: check, up, down, reset ├── .env.example ├── AGENTS.md # This file ├── README.md ├── REQUIREMENTS.md └── CODING_GUIDELINES.md ``` --- ## Conventions (Summary) Full details in `@CODING_GUIDELINES.md`. Key rules: ### Both sides - Code and comments in English. User-facing strings in Swedish. - No commented-out code. Delete it. - Functions stay small (<30 lines). ### Git - Create `feature/*`, `fix/*`, or `chore/*` branches from `develop`. - Never commit directly to `master` or `develop`. - Merge strategy: fast-forward or merge — either is fine. - Commit messages must be thorough: describe what changed, why, and list concrete changes as bullet points. Never write single-line "feat: add X" messages. ### Frontend (Vue.js 3) - `