2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30
2026-04-27 22:36:44 +09:30

MTG Search - Magic The Gathering Card Search Platform

A full-stack web application for searching and exploring Magic The Gathering cards with user authentication, built with Spring Boot, Vue.js, PostgreSQL, and deployed with Docker.

Architecture Overview

├── Backend (Java 21, Spring Boot 3.2.5)
│   ├── REST API with OpenAPI/Swagger documentation
│   ├── JWT-based authentication
│   ├── PostgreSQL database with jOOQ ORM
│   ├── Flyway database migrations
│   ├── Comprehensive logging with Logback
│   └── JUnit 5 and integration tests
│
├── Frontend (Vue 3, TypeScript, Vite)
│   ├── Single Page Application (SPA)
│   ├── Responsive UI with CSS Grid/Flexbox
│   ├── Pinia state management
│   ├── Vue Router with auth guards
│   └── Axios HTTP client with JWT interceptors
│
├── Database (PostgreSQL 16)
│   ├── Schema managed by Flyway migrations
│   ├── jOOQ-generated DTOs and repositories
│   └── Indexed queries for performance
│
└── Deployment
    ├── Docker multi-stage build
    ├── Docker Compose for local dev
    └── GitLab CI/CD pipeline

Prerequisites

  • Java 21 or later
  • Node.js 20+ and npm 10+
  • PostgreSQL 16+
  • Docker & Docker Compose (for containerized setup)
  • Git

Quick Start

# Clone the repository
git clone <repository-url>
cd mtg-search

# Start all services (PostgreSQL, Backend, built Frontend)
docker-compose up --build

# Backend will be available at: http://localhost:8080
# Frontend will be served by the backend

Local Development Setup

1. Database Setup

# Start PostgreSQL (using Docker)
docker run --name mtgsearch-postgres \
  -e POSTGRES_DB=mtgsearch \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  -d postgres:16-alpine

# Or use your local PostgreSQL installation

2. Backend Setup

cd backend

# Build the project
../gradlew build

# Run the application
../gradlew bootRun

# Backend starts on http://localhost:8080
# Swagger UI available at: http://localhost:8080/swagger-ui.html
# API Docs available at: http://localhost:8080/v3/api-docs

3. Frontend Setup

cd frontend

# Install dependencies
npm install

# Start development server
npm run dev

# Frontend starts on http://localhost:5173

API Endpoints

Authentication

  • POST /api/v1/auth/register - Register a new user

    {
      "username": "john_doe",
      "email": "john@example.com",
      "password": "SecurePassword123!"
    }
    
  • POST /api/v1/auth/login - Login and get JWT token

    {
      "username": "john_doe",
      "password": "SecurePassword123!"
    }
    

    Returns:

    {
      "token": "eyJhbGc...",
      "id": 1,
      "username": "john_doe",
      "email": "john@example.com"
    }
    
  • GET /api/v1/auth/health - Health check (no auth required)

Protected Endpoints

All protected endpoints require JWT token in Authorization header:

Authorization: Bearer <token>

Building

Build Backend

./gradlew clean build

# Build outputs to: backend/build/libs/

Build Frontend

cd frontend
npm run build

# Build outputs to: backend/src/main/resources/static/

Build Full Docker Image

docker build -t mtgsearch:latest .

Testing

Backend Unit Tests

./gradlew test

Backend Integration Tests

./gradlew integrationTest

Frontend Tests

cd frontend
npm run test
npm run test:ui  # Opens UI dashboard

All Tests with Coverage

./gradlew test jacocoTestReport

Configuration

Environment Variables

Create a .env file in the project root:

# Database
DB_URL=jdbc:postgresql://localhost:5432/mtgsearch
DB_USER=postgres
DB_PASSWORD=postgres

# JWT
JWT_SECRET=your-secret-key-change-in-production
JWT_EXPIRATION=86400

# Frontend
VITE_API_URL=http://localhost:8080

Application Properties

Backend configuration in backend/src/main/resources/application.yml:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mtgsearch
    username: postgres
    password: postgres
  
  jpa:
    hibernate:
      ddl-auto: validate

app:
  jwt:
    secret: ${JWT_SECRET:your-secret-key}
    expiration: ${JWT_EXPIRATION:86400}

Database Migrations

Migrations are managed by Flyway and located in backend/src/main/resources/db/migration/

Adding a New Migration

  1. Create a new file: V2__Add_new_table.sql
  2. Write SQL migration
  3. Run application - Flyway will auto-apply migrations

Example migration:

-- V2__Add_cards_table.sql
CREATE TABLE IF NOT EXISTS cards (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

Logging

Logs are configured in backend/src/main/resources/logback-spring.xml

  • Log Location: logs/mtg-search.log
  • Error Logs: logs/mtg-search-error.log
  • Max File Size: 100MB
  • Retention: 30 days
  • Compression: Automatic gzip compression

View logs:

tail -f logs/mtg-search.log
tail -f logs/mtg-search-error.log

Development Workflow

Code Generation

The project uses OpenAPI Generator and jOOQ for code generation:

# Generate server stubs from OpenAPI spec
./gradlew openApiGenerate

# Generate jOOQ entities from database schema
./gradlew generateJooqCode

Code Quality

# Format code
./gradlew spotlessApply

# Run static analysis
./gradlew check

# Frontend linting
cd frontend
npm run lint

Deployment

Staging Deployment

git checkout develop
git merge feature-branch
git push origin develop

# GitLab CI will automatically build and deploy to staging

Production Deployment

git tag v0.2.0
git push origin v0.2.0

# GitLab CI will build, test, and deploy to production

Manual Deployment

# Build Docker image
docker build -t mtgsearch:v0.1.0 .
docker tag mtgsearch:v0.1.0 your-registry/mtgsearch:v0.1.0

# Push to registry
docker push your-registry/mtgsearch:v0.1.0

# Pull and run on server
docker pull your-registry/mtgsearch:v0.1.0
docker run -d \
  -e SPRING_DATASOURCE_URL=jdbc:postgresql://db-host:5432/mtgsearch \
  -e SPRING_DATASOURCE_USERNAME=postgres \
  -e SPRING_DATASOURCE_PASSWORD=secure-password \
  -e JWT_SECRET=your-production-secret \
  -p 8080:8080 \
  --name mtgsearch \
  your-registry/mtgsearch:v0.1.0

CI/CD Pipeline

The project includes a comprehensive GitLab CI/CD pipeline (.gitlab-ci.yml):

  1. Build Stage

    • Compiles Java backend
    • Builds Vue.js frontend
    • Caches dependencies
  2. Test Stage

    • Unit tests
    • Integration tests with PostgreSQL
    • Code quality checks
  3. Docker Stage

    • Builds multi-stage Docker image
    • Pushes to registry
  4. Deploy Stage

    • Deploys to staging with manual trigger
    • Deploys to production on version tags

Project Structure

mtg-search/
├── backend/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/net/moustos/mtgsearch/
│   │   │   │   ├── MtgSearchApplication.java
│   │   │   │   ├── config/
│   │   │   │   ├── controller/
│   │   │   │   ├── service/
│   │   │   │   ├── repository/
│   │   │   │   ├── model/
│   │   │   │   └── security/
│   │   │   └── resources/
│   │   │       ├── application.yml
│   │   │       ├── logback-spring.xml
│   │   │       └── db/migration/
│   │   └── test/
│   │       └── java/
│   └── build.gradle.kts
│
├── frontend/
│   ├── src/
│   │   ├── pages/
│   │   ├── components/
│   │   ├── services/
│   │   ├── stores/
│   │   ├── router/
│   │   ├── types/
│   │   ├── main.ts
│   │   └── App.vue
│   ├── public/
│   ├── index.html
│   ├── package.json
│   ├── vite.config.ts
│   └── tsconfig.json
│
├── gradle/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle.properties
├── gradlew
├── gradlew.bat
│
├── Dockerfile
├── docker-compose.yml
├── .gitlab-ci.yml
├── .gitignore
└── README.md

Troubleshooting

Backend won't start

# Check if port 8080 is already in use
lsof -i :8080

# Check PostgreSQL is running
psql -U postgres -h localhost -d mtgsearch -c "SELECT 1;"

# View logs
tail -f logs/mtg-search.log

Frontend connection issues

  • Check backend is running on 8080
  • Check browser console for errors
  • Verify CORS settings in SecurityConfig.java

Database migration failures

# Check migration status
./gradlew flywayInfo

# Repair migrations (use with caution)
./gradlew flywayRepair

# Clean database (WARNING: deletes all data)
./gradlew flywayClean

Docker build fails

# Clear Docker cache
docker system prune -a

# Rebuild with no cache
docker build --no-cache -t mtgsearch:latest .

Performance Optimization

Backend

  • Connection pooling: HikariCP configured with 10 max connections
  • Database indexing on frequently queried columns
  • Flyway async migration setup
  • Request caching headers

Frontend

  • Code splitting with Vite
  • Lazy route loading
  • Production build minification
  • Gzip compression

Database

  • Query result caching
  • Indexed columns for search operations
  • Batch operations optimization

Security

  • Password Hashing: BCrypt with strength 12
  • JWT Tokens: Auth0 library with HMAC256
  • CORS: Configured for development (update for production)
  • HTTPS: Required for production deployment
  • SQL Injection: Protected via parameterized queries with jOOQ
  • CSRF: Disabled for API (JWT-based auth)

Contributing

  1. Create a feature branch: git checkout -b feature/amazing-feature
  2. Commit changes: git commit -m 'Add amazing feature'
  3. Push to branch: git push origin feature/amazing-feature
  4. Open a Pull Request

License

MIT License - see LICENSE file for details

Support

For issues and questions:

  • Open an issue on GitLab
  • Check existing documentation
  • Review API Swagger docs at /swagger-ui.html

Roadmap

  • Card search functionality with filters
  • Deck building feature
  • Social features (friends, sharing)
  • Mobile app
  • Advanced analytics
  • Magic Online API integration
  • Performance tuning for large datasets
S
Description
No description provided
Readme 200 KiB
Languages
Java 51.6%
Vue 23.6%
Shell 8.7%
TypeScript 8.5%
Makefile 5.3%
Other 2.3%