From 1e8fdec6d6165869e769f01bb10c33bb5a5e7f31 Mon Sep 17 00:00:00 2001 From: mattknatt Date: Thu, 30 Apr 2026 09:31:32 +0200 Subject: [PATCH] Replace manual OpenAPI configuration in `application.properties` with `OpenApiConfig` class using annotations for cleaner API documentation setup. --- README.md | 123 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index cbd9053..bca8671 100644 --- a/README.md +++ b/README.md @@ -1,78 +1,111 @@ -# boka. +# boka. [![Java](https://img.shields.io/badge/Java-25-orange?style=for-the-badge&logo=openjdk)](https://openjdk.org/) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-4.0.2-brightgreen?style=for-the-badge&logo=springboot)](https://spring.io/projects/spring-boot) -[![React](https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)](https://reactjs.org/) +[![React](https://img.shields.io/badge/React-19-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)](https://reactjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white)](https://www.postgresql.org/) [![Fly.io](https://img.shields.io/badge/Fly.io-4433FF?style=for-the-badge&logo=fly.io&logoColor=white)](https://fly.io/) -**boka.** is a high-performance, full-stack gym class booking application. It demonstrates a modern architectural approach to building scalable web applications with a focus on developer experience, modular design, and cloud-native deployment. +**boka.** is a full-stack gym class booking platform built with Spring Boot 4 and React 19. It demonstrates production-grade backend patterns โ€” hexagonal architecture, pessimistic locking, transactional booking flows โ€” combined with a polished, responsive frontend. ---- +**[Live demo](https://boka.fly.dev) ยท [API docs](https://boka.fly.dev/swagger-ui.html)** -## ๐Ÿš€ Technical Highlights +--- -This project showcases a robust engineering foundation: +## Architecture + +```mermaid +flowchart TD + subgraph Frontend["Frontend โ€” React 19 + Vite"] + UI["ClassSearch ยท MyBookings ยท AdminDashboard ยท Settings"] + end + + subgraph Backend["Backend โ€” Spring Boot 4"] + direction TB + GymClass["gymclass module\n(domain + port)"] + Booking["booking module\n(domain + adapter)"] + User["user module\n(domain + adapter)"] + Security["Spring Security\n(JWT ยท OAuth2 ยท BCrypt)"] + GymClass <-->|BookingProviderPort| Booking + GymClass <-->|InstructorProviderPort| User + end + + subgraph Data["Data Layer"] + DB[(PostgreSQL\nNeon serverless)] + Flyway["Flyway migrations"] + end + + Frontend -->|HTTP / JSON| Backend + Backend -->|JDBC / JPA| Data +``` -- **State-of-the-Art Java:** Leverages **Java 25 (LTS)** features for modern, efficient backend logic. -- **Hexagonal Architecture Principles:** Utilizes **Ports and Adapters** to decouple core business logic from infrastructure, ensuring high testability and maintainability. -- **Unified Development Workflow:** A root-level orchestration setup using `concurrently` that manages Spring Boot, Vite, and Dockerized Postgres with a single `npm start` command. -- **Secure Authentication:** Seamless integration of **Google OAuth2** and local **BCrypt-hashed** credentials, handled securely via Spring Security with custom session management. -- **Type-Safe Frontend:** A **React 19** application built with **TypeScript** and **Vite**, featuring a dynamic view-state management system. -- **Optimized SQL Performance:** Custom JPQL queries with grouped aggregations to eliminate N+1 problems during data enrichment. +Cross-module dependencies flow through explicit **ports** (interfaces), keeping the `gymclass`, `booking`, and `user` modules decoupled. Infrastructure adapters (`BookingProviderAdapter`, `InstructorProviderAdapter`) implement the ports and live at the boundary. --- -## โœจ Core Features +## Technical Highlights + +**Backend** +- **Pessimistic locking** on the booking path (`SELECT ... FOR UPDATE`) prevents overbooking under concurrent load โ€” the lock is acquired at the DB row level, capacity is checked inside the transaction, and `PessimisticLockingFailureException` is caught for a graceful user-facing error +- **Hexagonal / Ports & Adapters** architecture with Spring Modulith โ€” each module exposes a typed port interface; no cross-module repository access +- **Schema-first with Flyway** โ€” `ddl-auto=validate` in all environments; every schema change is a versioned migration +- **Admin booking cascade** โ€” cancelling a class atomically cancels all confirmed bookings within the same transaction +- **Secure admin bootstrap** โ€” admin credentials are injected via environment variables at startup; a force-sync flag controls password rotation; startup fails fast in production if credentials are absent + +**Frontend** +- **React Router v6** deep-linking โ€” every view has a stable URL; Spring Boot forwards unknown paths to `index.html` via a `SpaController` +- **Global toast system** โ€” `ToastProvider` + `useToast` hook replaces all `alert()`/`window.confirm()` calls with styled, auto-dismissing notifications +- **Admin dashboard** โ€” paginated class list with status filter tabs, inline cancel confirmation, and a create/edit modal with timezone-safe datetime handling +- **Google OAuth2** sign-in/sign-up alongside local credentials -- **Intuitive Discovery:** Dual entry points for searching specific **Classes** or exploring local **Gyms**. -- **Atomic Booking System:** Robust reservation engine with server-side validation to prevent overbooking and double-bookings. -- **Personal Schedule Management:** A dedicated **"My Bookings"** dashboard for users to track and cancel their upcoming sessions. -- **Account Customization:** Integrated **Settings** portal for managing profile information. -- **Immersive UI/UX:** Modern, responsive design featuring a fixed parallax-style background and instant visual feedback for all user actions. +**API** +- Interactive docs at `/swagger-ui.html` โ€” all endpoints grouped by domain (Auth, Classes, Bookings, Gyms, Users, Admin) +- `GlobalExceptionHandler` maps Bean Validation errors to `{"message": "..."}` so clients get readable field error messages --- -## โ˜๏ธ Cloud Architecture & Deployment +## Features -**boka.** is built for the modern cloud, utilizing a serverless and containerized ecosystem: +| | | +|---|---| +| Browse gym classes with filters | Book a class with real-time availability | +| Cancel bookings with confirmation | Admin CRUD for gym classes | +| Assign instructors to classes | Cancel class + cascade-cancel all bookings | +| Google OAuth2 + local auth | Settings: update profile, delete account | -### ๐ŸŒ Hosting & Compute -- **Platform:** [Fly.io](https://fly.io/) -- **Strategy:** Multi-stage **Docker** build that bundles optimized React production assets directly into the Spring Boot executable, resulting in a single, high-performance deployment unit. +--- -### ๐Ÿ’พ Database -- **Provider:** [Neon](https://neon.tech/) -- **Type:** Serverless Postgres -- **Benefit:** Provides instant scalability and zero-cold-start performance, perfectly suited for modern web workloads. +## Cloud & CI/CD -### ๐Ÿค– CI/CD Pipeline -- **Tool:** **GitHub Actions** -- **Integration & Deployment:** Automated build, test, and deploy pipelines (`ci.yml`, `fly-deploy.yml`) ensure every commit is production-ready. +| Concern | Solution | +|---|---| +| Hosting | [Fly.io](https://fly.io/) โ€” single Docker image (Spring Boot + React static assets) | +| Database | [Neon](https://neon.tech/) โ€” serverless PostgreSQL | +| CI | GitHub Actions โ€” build, test, frontend compile on every push | +| Deploy | GitHub Actions โ€” `fly deploy` on merge to `main` | --- -## ๐Ÿšฆ Getting Started - -### Prerequisites -- JDK 25 -- Node.js 20+ -- Docker (for local database) +## Getting Started -### Local Startup -Clone the repository and run the following in the root directory: +**Prerequisites:** JDK 25, Node.js 20+, Docker ```bash -npm run install:all # Setup dependencies -npm start # Launch the full stack +npm run install:all # install all dependencies +npm start # starts Postgres (Docker), Spring Boot, and Vite concurrently ``` -**Local Dev Credentials:** -- Admin: `admin@boka.se` / `password123` -- Member: `karl@example.com` / `password123` +**Local credentials** +| Role | Email | Password | +|---|---|---| +| Admin | `admin@boka.se` | `password123` | +| Member | `karl@example.com` | `password123` | + +Local API docs: `http://localhost:8080/swagger-ui.html` --- -## ๐Ÿ“„ License -This project is licensed under the MIT License. +## License + +MIT