Commit graph

6 commits

Author SHA1 Message Date
8e495672d3 feat: add user registration flow (backend + frontend)
Implement end-to-end registration: POST /api/auth/register creates a
user, returns a JWT, and the frontend RegisterPage stores the token
and redirects to home.

Backend:
- Add AuthController with POST /api/auth/register endpoint
- Add RegisterRequest record (@Email, @NotBlank, @Size(min=8))
- Add AuthResponse and ErrorResponse DTOs
- Add GlobalExceptionHandler (@RestControllerAdvice with logging)
  - EmailAlreadyExistsException -> 409 (Swedish message)
  - MethodArgumentNotValidException -> 400 (field errors)
  - Generic Exception -> 500 (Swedish message + server-side log)

Frontend:
- Add api/client.ts: centralized fetch wrapper with Bearer token
  interceptor, ApiError class, JSON error parsing
- Add api/auth.ts: register() function
- Add stores/authStore.ts: Pinia store with token persistence via
  localStorage, registerUser/logout/isAuthenticated
- Add pages/RegisterPage.vue: email + password + confirm password
  form with client-side validation, submit handler, error display,
  redirect to home on success
- Add route /registrera pointing to RegisterPage
- Add 'Registrera' link to AppHeader navigation

Infrastructure:
- Add __tests__/setup.ts: localStorage polyfill for jsdom 29
  (jsdom 29 lacks standard Storage method implementations)
- Register polyfill via vitest config setupFiles

Tests (17 new, 2 extended):
- AuthControllerTest (@SpringBootTest + @AutoConfigureMockMvc):
  5 backend tests (success 201, duplicate 409, invalid email 400,
  short password 400, missing email 400)
- authStore.spec.ts: 5 tests (unauthenticated start, localStorage
  restore, register success, register failure, logout)
- RegisterPage.spec.ts: 12 tests (render, validation, submit,
  redirect, error display, login link)
- AppHeader.spec.ts: added 'Registrera' link test
- Router.spec.ts: added /registrera route resolution test

Build: 95 tests pass (57 frontend + 38 backend), lint clean.
2026-05-01 19:37:39 +02:00
4c6094446b feat: add app shell with header, footer, and compose flow
Add AppHeader and AppFooter to give the site a consistent chrome
around the core page content. Add ComposePage stub reachable via
"Skicka ett brev till ägaren" CTA on HomePage after vehicle lookup
succeeds. Add stub pages for about, contact, and privacy.

- Create AppHeader.vue with logo link (BilHälsning) and Hem nav link
- Create AppFooter.vue with 4 links: Om oss, Kontakt, Integritetspolicy, Villkor
- Create ComposePage.vue stub that reads plate from route query params
- Create AboutPage.vue and ContactPage.vue stub pages
- Add 4 new routes: /compose, /om, /kontakt, /integritetspolicy
- Update App.vue to render AppHeader + <main> + AppFooter around RouterView
- Add home__cta RouterLink button to HomePage, visible only when vehicle
  lookup succeeds, linking to /compose?plate=<plate>
- Remove BilHälsning h1 from HomePage (moved to header)
- Add 17 new tests: AppHeader (2), AppFooter (1), ComposePage (3),
  AboutPage (1), ContactPage (1), HomePage rewrite (6), App update (2)
- Update App.spec.ts to verify header/footer components render
2026-05-01 18:19:53 +02:00
210ac87ede feat: extract VehicleInfo component from HomePage
Move vehicle-info display logic out of HomePage into a reusable
VehicleInfo component. The component accepts vehicle, loading,
notFound, and plate props and renders the correct state with
priority: vehicle card > loading > not found. Follows the
small-page-component pattern from CODING_GUIDELINES.md.

- Create VehicleInfo.vue with 3-state v-if chain and scoped styles
- Define and export VehicleInfo interface (make/model/year/color)
- Add VehicleInfo.spec.ts with 7 tests covering all states and
  priority edge cases
- Update HomePage.vue to use VehicleInfo, replacing 3 inline
  v-if/else-if blocks with a single component tag
- Remove 5 unused CSS classes from HomePage (home__status,
  home__vehicle, home__vehicle-text, home__not-found,
  home__not-found p)
- Update AGENTS.md to require thorough commit messages with bullet
  points
2026-05-01 18:06:04 +02:00
078f07f2ac feat: add PlateInput component with Swedish plate validation and fake vehicle lookup 2026-05-01 17:38:28 +02:00
4d449d54d0 feat: add Docker Compose setup with dev and prod configurations
- docker-compose.yml (dev): 3 services — postgres:16, backend (gradle
  bootRun with JDK 21, spring-boot-devtools), frontend (Vite HMR on
  node:24-alpine). Source volume mounts for live editing, Gradle cache
  volume for fast rebuilds, pg_isready healthcheck on postgres.

- docker-compose.prod.yml (prod): same 3 services but with multi-stage
  Dockerfiles. Backend: Gradle bootJar → JRE Alpine, non-root user.
  Frontend: npm ci + vite build → nginx:alpine serving static dist/.
  SSL termination via self-signed cert (auto-generated in entrypoint).
  No source mounts, restart: unless-stopped, separate volumes.

- application-docker.yml: Spring profile overriding H2 with PostgreSQL
  via env vars. Hostname "postgres" resolved by Docker Compose DNS.

- Vite proxy /api → backend:8080 for dev. nginx nginx.conf handles
  /api proxy + SPA fallback + gzip + SSL in prod.

- AGENTS.md, README.md: architecture diagram, dev vs prod comparison
  table, Spring profiles docs, file reference updates.
2026-05-01 01:45:07 +02:00
9931061cb6 feat: scaffold Vue 3 + Vite frontend with TypeScript, Router, Pinia, Vitest, ESLint, Prettier
- Scaffold via npm create vite@latest --template vue-ts (create-vue interactive
  prompts require manual selection; create-vite supports non-interactive flags)
- Dependencies: vue-router (SPA routing, createWebHistory for clean URLs),
  pinia (centralised state management), vitest + @vue/test-utils + jsdom
  (unit testing with browser DOM simulation)
- Dev tooling: eslint (v10 flat config) + eslint-plugin-vue + @vue/eslint-config-typescript
  + @vue/eslint-config-prettier (ESLint-Prettier integration via vueTsConfigs),
  prettier (semi: false, singleQuote, trailingComma: all), jiti (bridges ESLint
  with TypeScript config files)
- vite.config.ts: dev server on port 3000, @ alias resolving to src/, vitest
  with jsdom environment
- eslint.config.ts: defineConfigWithVueTs wraps tseslint.config with Vue SFC
  support (vue-eslint-parser, <script setup lang="ts">), vue/multi-word off
- tsconfig.app.json: path alias @/* -> src/* for TypeScript module resolution
- src/router/index.ts: single route mapping / to HomePage
- src/pages/HomePage.vue: minimal <script setup lang="ts"> placeholder
- src/main.ts: bootstraps app with Pinia plugin + Vue Router
- src/App.vue: delegates rendering to <RouterView />
- src/__tests__/HomePage.spec.ts: smoke test verifying component mounts
- Directory structure: src/stores/, src/api/, src/composables/ with .gitkeep
  placeholders matching AGENTS.md convention (PascalCase pages, camelCase stores/composables)
- index.html: lang="sv", title BilHälsning (Swedish UI convention)
- Cleaned up: HelloWorld.vue, style.css, template boilerplate SVGs/PNGs
- Update AGENTS.md + CODING_GUIDELINES.md: .js extensions → .ts across all
  file naming examples (useXxx.ts, authStore.ts, orders.ts, client.ts)
- Verification: npm run dev serves blank page on http://localhost:3000,
  npm run lint passes (0 errors, 0 warnings), npm test passes (1 test, 1 file)
2026-05-01 00:52:38 +02:00