Commit graph

4 commits

Author SHA1 Message Date
c6e2e509eb chore: add JWT secret env config, jjwt deps, and docker-compose prod fixes 2026-05-01 17:38:03 +02:00
c03b5a1401 feat: add User entity, repository, service, and Flyway users table migration
- V1__create_users_table.sql replaces placeholder: creates users table with
  id UUID PK, email UNIQUE NOT NULL, password_hash NOT NULL, subscription
  VARCHAR(20) DEFAULT 'none' with CHECK constraint (none/basic/pro),
  created_at/updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP.
  Compatible with both H2 and PostgreSQL.

- SecurityConfig: minimal @Configuration providing BCryptPasswordEncoder
  bean. Required because Spring Boot 4 no longer auto-configures a
  PasswordEncoder.

- Subscription enum: NONE, BASIC, PRO with string values matching the DB
  CHECK constraint.

- User entity: @PrePersist generates UUID and timestamps in application
  code, @PreUpdate refreshes updated_at. Email setter normalizes to
  lowercase for case-insensitive uniqueness. Explicit getters/setters
  (no Lombok per guidelines).

- UserRepository: Spring Data JPA extending JpaRepository<User, UUID>.
  findByEmail(Optional) and existsByEmail for duplicate checks.

- UserService: @RequiredArgsConstructor with constructor-injected
  UserRepository and PasswordEncoder. createUser normalizes email,
  checks duplicates via existsByEmail, throws EmailAlreadyExistsException,
  hashes password with BCrypt, saves. findByEmail returns Optional<User>.

- EmailAlreadyExistsException: custom RuntimeException for duplicate
  registration attempts. ControllerAdvice handler deferred to auth ticket.

Verification: ./gradlew test passes (Flyway + H2 context loads).
docker compose up -d succeeds, Flyway applies V1 against PostgreSQL 16.
\d users confirms all columns, constraints, defaults, and indexes.
2026-05-01 02:06:24 +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
83b578ca22 feat: scaffold Spring Boot 4 backend with Gradle, Flyway, and H2
- Generate from Spring Initializr with Gradle Groovy DSL, Java 21, Spring Boot 4.0.6
- Dependencies: Web, Security, Data JPA, PostgreSQL Driver, Flyway, Validation, Lombok
- Add H2 runtime dependency for zero-setup local development
- Configure application.yml: H2 in-memory database, port 8080, Flyway with ddl-auto=validate
- Create placeholder Flyway migration V1__init_schema.sql
- Verify ./gradlew test passes and ./gradlew bootRun starts on port 8080
- Update AGENTS.md and README.md: Maven → Gradle commands, Spring Boot 3 → 4
2026-05-01 00:28:10 +02:00