diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..73c61fd --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +MIT Licence + +Copyright (c) 2026 OnixByte + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..13455ae --- /dev/null +++ b/README.md @@ -0,0 +1,150 @@ +# Delta Force Guide Server + +REST API backend for managing **Delta Force** game firearm builds and modifications. Provides endpoints to browse, create, and share weapon configurations including attachments, tuning setups, tags, and build reviews. + + +## Tech Stack + +| Layer | Technology | +|-----------|------------------------------------------------------------| +| Language | Java 21 (Amazon Corretto) | +| Framework | Spring Boot 3.x (Web, Security, Data JPA, Cache, Actuator) | +| Build | Gradle (Kotlin DSL) | +| Database | PostgreSQL (Flyway migrations, JSONB columns) | +| Cache | Redis (2-hour TTL) | +| Auth | Custom JWT via httpOnly cookies + BCrypt | +| API Docs | springdoc-openapi (Swagger UI, dev profile only) | +| Container | Multi-stage Docker image (Amazon Corretto 21 → Alpine) | +| CI/CD | GitHub Actions — builds on release publish | + + +## Quick Start + +### Prerequisites + +- JDK 21 (Amazon Corretto recommended) +- PostgreSQL +- Redis + +### Configure + +Copy and customise the development config: + +```bash +cp config/application-prod.yaml.example \ + config/application-dev.yaml +``` + +Fill in your datasource and Redis connection details, then place the production config at `config/`, then enable it by environment variable `SPRING_PROFILES_ACTIVE`. + +### Build + +```bash +# Compile (skip tests) +./gradlew build -x test + +# Run all tests +./gradlew test + +# Build executable JAR +./gradlew bootJar +``` + +### Run + +```bash +SPRING_PROFILES_ACTIVE=prod java -jar build/libs/delta-force-guide-server-$version.jar +``` + +Swagger UI is available at `http://localhost:8080/swagger-ui.html` when the `dev` profile is active. + +## Data Model + +- **Firearm** — weapon base stats (name, type, level, calibre, fire rate, armour/body damage, review) +- **Modification** — a build attached to a firearm, with name, code, tags (JSONB), accessories including nested tuning objects (JSONB), author notes, and video links +- **App User** — registered user (username, email) with hashed credentials via BCrypt + +Tags and accessories are stored as PostgreSQL JSONB columns using [Hypersistence Utils](https://github.com/vladmihalcea/hypersistence-utils), enabling flexible per-build metadata and filtering with the `@>` operator. + + +## Architecture + +``` +Controller → Service → Manager → Repository / Mapper + (HTTP) (logic) (@Transactional) (data access) +``` + +The call chain is strictly enforced — skipping layers is not permitted. All request/response objects are Java records with static `from()` factory methods for entity-to-DTO conversion. + + +## Docker + +```bash +# Build image +docker pull registry.onixbyte.cn/onixbyte/delta-force-guide-server:latest + +# Run container +docker run -p 8080:8080 \ + -v /path/to/config:/app/config \ + -e SPRING_PROFILES_ACTIVE=$your_active_profiles + delta-force-guide-server +``` + +Pre-built images are published to **Self-hosted GitLab Container Registry** (`registry.onixbyte.cn/onixbyte/delta-force-guide-server`) on every release. + + +## CI/CD + +GitLab CI triggers on **tags**. The pipeline: + +1. Builds the boot JAR with the release tag as the version +2. Uploads the JAR as a release asset +3. Builds and pushes a multi-arch Docker image to GHCR tagged with both `:latest` and `:` + +No tests are run in CI by design — tests are expected to pass locally before a release is cut. + + +## Profiles + +| Profile | Purpose | +|---------|-----------------------------------------------------------------------| +| `dev` | Enables Swagger UI, connects to dev DB/Redis at `dfguide.onixbyte.cn` | +| default | Production mode, no Swagger, uses production datasource | + + +## Project Structure + +``` +src/main/java/com/onixbyte/deltaforceguide/ +├── client/ External service HTTP clients +├── config/ Spring bean definitions (Security, CORS, Cache, Jackson, MyBatis) +├── controller/ REST controllers +├── domain/ +│ ├── converter/ JPA attribute converters +│ ├── dto/ Request/response records +│ └── entity/ JPA entities +├── enumeration/ Enums (FirearmType) +├── exception/ Custom BizException with HTTP status mapping +├── filter/ TokenAuthenticationFilter (JWT through OncePerRequestFilter) +├── manager/ @Transactional wrappers around repositories +├── mapper/ MyBatis mapper interfaces (reserved for future use) +├── properties/ @ConfigurationProperties records +├── repository/ Spring Data JPA repositories +├── security/ +│ ├── authentication/ Custom UsernamePasswordAuthentication +│ └── provider/ UsernamePasswordAuthenticationProvider +├── service/ Business logic +├── shared/ Constants and utility classes +└── utils/ General-purpose helpers +``` + + +## Versioning + +The application exposes its version at `/versions` (GET). + + +## Licence + +This project is licensed under the [MIT Licence](LICENCE). Copyright © 2026 OnixByte. + diff --git a/config/application-prod.yaml.example b/config/application-prod.yaml.example new file mode 100644 index 0000000..ae00f78 --- /dev/null +++ b/config/application-prod.yaml.example @@ -0,0 +1,55 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5432/dfguide_dev + username: postgres + password: 123456 + driver-class-name: org.postgresql.Driver + data: + redis: + host: localhost + port: 6379 + database: 0 + # password: 6hLFVqfGPviTYukn # Uncomment if password is necessary + +logging: + pattern: + # dateformat: dd MMM yyyy HH:mm:ss.SSS # Modify this for custom date format. + +app: + common: + version: 1.3.0.8-dev # Application version, you can change to any version you like, used for communication with frontend. + cors: + allowed-origins: # Cross-origin allowed origins + - "http://localhost:5173" # Dev server for vite. + - "http://localhost:4173" # Preview server for vite. + allow-credentials: true # Must be set to `true` since we are using cookie. You can change it only when you have modified how this application executing authentication. + allow-private-network: false + allowed-headers: + - "Content-Type" + - "Authorization" + allowed-methods: + - GET + - POST + - PUT + - PATCH + - DELETE + exposed-headers: + - "Content-Type" + - "Authorization" + max-age: PT2H + jwt: + issuer: dfguide.local # Issuer host + secret: qwertyuiopasdfghjklzxcvbnm123456 # JWT singing secret, a 32-byte long or longer string is recommended + valid-time: PT2H # JWT valid duration + cookie: # Cookie settings. + http-only: true + secure: false + same-site: lax + path: '/' + max-age: PT2H + +springdoc: + api-docs: + enabled: true # Set to `false` if you do not need api docs (recommended in production mode). + swagger-ui: + enabled: true # Set to `false` if you do not need swagger ui (recommended in production mode). \ No newline at end of file diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 1235085..0000000 --- a/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -artefactVersion = 1.2.0 \ No newline at end of file