Osiris is a Java backend built with Spring Boot, MySQL, and other technologies. Is example backend!
README
Backend REST API built with Spring Boot 3. Covers authentication, product catalogue, categories, shopping cart, and order management.

| Layer | Technology | |---|---| | Runtime | Java 17 | | Framework | Spring Boot 3.5 | | Database | MySQL 8.4 + Flyway | | Cache / Token store | Redis 7.4 | | Auth | JWT (access + refresh tokens) | | Docs | SpringDoc OpenAPI 3 | | Email (dev) | MailHog | | Build | Gradle (Kotlin DSL) |
# 1. Start infrastructure
docker compose up -d
# 2. Run the app (default profile reads localhost env vars)
./gradlew bootRun
The API is available at http://localhost:8080.
Swagger UI: http://localhost:8080/swagger-ui.html
MailHog UI (email preview): http://localhost:8025
All variables have defaults that work with the Docker Compose setup out of the box.
| Variable | Default | Description |
|---|---|---|
| DB_URL | jdbc:mysql://localhost:3306/osiris | JDBC connection URL |
| DB_USERNAME | root | Database user |
| DB_PASSWORD | (empty) | Database password |
| REDIS_HOST | localhost | Redis host |
| REDIS_PORT | 6379 | Redis port |
| JWT_SECRET | (dev key) | Base64-encoded secret ā change in production |
| JWT_EXPIRATION | 3600000 | Access token TTL in ms (1 hour) |
| MAIL_HOST | localhost | SMTP host |
| MAIL_PORT | 1025 | SMTP port |
| MAIL_FROM | noreply@osiris.dev | Sender address |
| APP_BASE_URL | http://localhost:8080 | Used in email links |
| CORS_ALLOWED_ORIGINS | http://localhost:3000,http://localhost:5173 | Comma-separated allowed origins |
/auth| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /auth/register | Public | Register a new user |
| POST | /auth/login | Public | Login, returns access + refresh tokens |
| POST | /auth/refresh | Public | Rotate refresh token |
| POST | /auth/logout | Bearer | Invalidate current session |
| POST | /auth/logout-all | Bearer | Invalidate all sessions for the user |
| POST | /auth/forgot-password | Public | Send password reset email |
| POST | /auth/reset-password | Public | Reset password with token |
| GET | /auth/verify-email | Public | Verify email address with token |
/users| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /users/me | Bearer | Get current user profile |
| PUT | /users/me | Bearer | Update current user profile |
| DELETE | /users/me | Bearer | Delete account |
/categories| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /categories | Bearer | List all categories (paginated) |
| GET | /categories/{id} | Bearer | Get category by ID |
| POST | /categories | Admin | Create category |
| PUT | /categories/{id} | Admin | Update category |
| DELETE | /categories/{id} | Admin | Delete category |
/products| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /products | Bearer | List products (paginated, supports ?search=) |
| GET | /products/{id} | Bearer | Get product by ID |
| POST | /products | Admin | Create product |
| PUT | /products/{id} | Admin | Update product |
| DELETE | /products/{id} | Admin | Delete product |
/cart| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /cart | Bearer | Get current user's cart with total |
| POST | /cart/items | Bearer | Add item (merges quantity if product already in cart) |
| PUT | /cart/items/{itemId} | Bearer | Update item quantity |
| DELETE | /cart/items/{itemId} | Bearer | Remove item |
| DELETE | /cart | Bearer | Clear cart |
/orders| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /orders/checkout | Bearer | Create order from cart (validates stock, deducts inventory) |
| GET | /orders | Bearer | List my orders (paginated, newest first) |
| GET | /orders/{id} | Bearer | Get order detail |
| DELETE | /orders/{id}/cancel | Bearer | Cancel order (only if status is PENDING) |
/admin| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /admin/users | Admin | List all users (paginated) |
| PUT | /admin/users/{id}/role | Admin | Change user role |
| GET | /admin/orders | Admin | List all orders (paginated, newest first) |
| PUT | /admin/orders/{id}/status | Admin | Update order status |
Order statuses: PENDING ā PROCESSING ā SHIPPED ā DELIVERED / CANCELLED
POST /auth/register ā { accessToken, refreshToken }
POST /auth/login ā { accessToken, refreshToken }
Authorization: Bearer <accessToken> (on every protected request)
POST /auth/refresh ā { accessToken, refreshToken } (rotate before expiry)
POST /auth/logout ā 204 (blacklists access token)
Access tokens are short-lived (1 h by default). Refresh tokens are stored in the database and can be revoked individually or in bulk via /auth/logout-all.
Flyway runs automatically on startup. Migration files live in src/main/resources/db/migration/.
| Version | Description | |---|---| | V1 | users, refresh_tokens, products | | V2 | categories table + image_url column on products | | V3 | carts, cart_items, orders, order_items |
./gradlew test
Tests use an H2 in-memory database and MockMvc. No external services required.
src/main/java/dev/alexissdev/osiris/
āāā auth/ # JWT, refresh tokens, email verification, password reset
āāā user/ # User entity, profile management
āāā admin/ # Admin-only user and role management
āāā category/ # Product categories
āāā product/ # Product catalogue
āāā cart/ # Shopping cart
āāā order/ # Order lifecycle
āāā config/ # OpenAPI, cache, MDC logging filter
āāā exception/ # Global exception handler