Skip to content

jaganov/forgemaze-api

Repository files navigation

⚡ ForgeMaze API

Backend REST API service for ForgeMaze platform - authentication, maze generation, database operations, and business logic..

Go PostgreSQL MongoDB

✨ Features

  • 🔐 Authentication - JWT + OAuth2 (Google, GitHub)
  • 🎲 Maze Generation - Multiple algorithms with customization
  • 💾 Database - PostgreSQL (metadata) + MongoDB (full mazes)
  • 📤 Export - JSON, XML, Unity, Unreal, Godot formats
  • 🔍 Search - Full-text search with Elasticsearch
  • 📊 Analytics - User activity and maze statistics
  • 🚀 Performance - Redis caching and rate limiting
  • 📝 Documentation - Swagger/OpenAPI 3.0
  • 🐳 Docker - Containerized deployment
  • 🔒 Security - CORS, rate limiting, input validation

🚀 Quick Start

Prerequisites

  • Go 1.21+
  • PostgreSQL 15+
  • MongoDB 6+
  • Redis 7+

Installation

# Clone the repository
git clone https://gitlab.com/forgemaze/fm-api.git
cd fm-api

# Install dependencies
go mod download

# Copy environment variables
cp .env.example .env

# Run database migrations
make migrate-up

# Start the server
make run

API will be available at http://localhost:8080

Using Docker Compose

# Start all services (API + PostgreSQL + MongoDB + Redis)
docker-compose up -d

# View logs
docker-compose logs -f api

# Stop services
docker-compose down

📁 Project Structure

forgemaze-api/
├── cmd/api/             # Main application entry
├── internal/
│   ├── api/             # HTTP handlers, middleware, routing
│   ├── domain/          # Business logic
│   ├── generator/       # Maze generation engine
│   ├── repository/      # Data access layer
│   └── service/         # Business services
├── pkg/                 # Reusable packages
├── migrations/          # Database migrations
├── configs/             # Configuration files
└── docs/                # API documentation

🛠️ Tech Stack

  • Language: Go 1.21+
  • Web Framework: Gin / Echo
  • Databases: PostgreSQL, MongoDB, Redis
  • Authentication: JWT, OAuth2
  • Storage: MinIO / AWS S3
  • Search: Elasticsearch
  • Documentation: Swagger/OpenAPI
  • Testing: Testify, Mockery
  • Logging: Zap
  • Monitoring: Prometheus

🌍 Environment Variables

# Server
PORT=8080
ENV=development

# Database
POSTGRES_DSN=postgres://user:pass@localhost:5432/forgemaze?sslmode=disable
MONGODB_URI=mongodb://localhost:27017
MONGODB_DATABASE=forgemaze
REDIS_ADDR=localhost:6379
REDIS_PASSWORD=

# JWT
JWT_SECRET=your-secret-key
JWT_EXPIRATION=24h
REFRESH_TOKEN_EXPIRATION=720h

# OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret

# Storage
S3_ENDPOINT=http://localhost:9000
S3_BUCKET=forgemaze
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin

# Email (optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-password

# Email via Resend (optional; if set, replaces SMTP for sending)
# In app/config/conf*.json set email_account.resend.api_key to your key (replace re_xxxxxxxxx).
# Get your API key at https://resend.com
RESEND_API_KEY=re_xxxxxxxxx

📚 Available Commands

make run              # Run the application
make build            # Build binary
make test             # Run tests
make test-coverage    # Run tests with coverage
make lint             # Run linter
make migrate-up       # Run database migrations
make migrate-down     # Rollback migrations
make seed             # Seed database with demo data
make swagger          # Generate Swagger docs
make docker-build     # Build Docker image
make docker-run       # Run Docker container

🔌 API Endpoints

Authentication

POST   /api/v1/auth/register
POST   /api/v1/auth/login
POST   /api/v1/auth/forgot-password   # Request password reset email (Keycloak sends it)
POST   /api/v1/auth/refresh
POST   /api/v1/auth/logout

Forgot password: The API asks Keycloak to send the reset email. For the email to be sent, configure SMTP in Keycloak: Admin Console → your Realm → Realm settingsEmail (host, port, from, auth). Otherwise Keycloak returns an error and the link is not sent (the API still responds with success to avoid email enumeration).

Labyrinths

GET    /api/v1/labyrinths              # List labyrinths
GET    /api/v1/labyrinths/:id          # Get labyrinth details
POST   /api/v1/labyrinths              # Create new labyrinth
PUT    /api/v1/labyrinths/:id          # Update labyrinth
DELETE /api/v1/labyrinths/:id          # Delete labyrinth
POST   /api/v1/labyrinths/:id/publish  # Publish labyrinth
POST   /api/v1/labyrinths/:id/fork     # Fork/copy labyrinth
GET    /api/v1/labyrinths/:id/json     # Export to JSON
POST   /api/v1/labyrinths/import       # Import from JSON

# Rooms
GET    /api/v1/labyrinths/:id/rooms    # List rooms
POST   /api/v1/labyrinths/:id/rooms    # Create room
PUT    /api/v1/rooms/:roomId           # Update room
DELETE /api/v1/rooms/:roomId           # Delete room

# Quests
GET    /api/v1/rooms/:roomId/quest     # Get room quest
POST   /api/v1/rooms/:roomId/quest     # Create quest
PUT    /api/v1/quests/:questId         # Update quest
DELETE /api/v1/quests/:questId         # Delete quest

# Sharing
POST   /api/v1/labyrinths/:id/share    # Create share link
GET    /api/v1/share/:token            # Access shared labyrinth
DELETE /api/v1/shares/:shareId         # Revoke share

# Gameplay
POST   /api/v1/labyrinths/:id/play     # Start game session
GET    /api/v1/sessions/:sessionId     # Get session state
PUT    /api/v1/sessions/:sessionId     # Update progress
POST   /api/v1/sessions/:sessionId/complete  # Complete session

Generator

POST   /api/v1/generator/generate
GET    /api/v1/generator/algorithms
POST   /api/v1/generator/validate

Export

GET    /api/v1/export/:id/json
GET    /api/v1/export/:id/xml
GET    /api/v1/export/:id/unity
GET    /api/v1/export/:id/image

See full API documentation at /api/v1/docs (Swagger UI)

🎲 Labyrinth Generation Example

# Create a new labyrinth with generator
curl -X POST http://localhost:8080/api/v1/labyrinths \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "name": "My Learning Labyrinth",
    "description": "A labyrinth for learning English and Russian",
    "grid_rows": 8,
    "grid_cols": 8,
    "languages": ["en", "ru"],
    "support_items": ["compass", "map", "dictionary"],
    "generation_settings": {
      "algorithm": "growing_tree",
      "min_rooms": 20,
      "max_rooms": 30,
      "junction_rate": 0.15,
      "story_room_rate": 0.20,
      "dummy_room_rate": 0.30,
      "seed": "12345"
    }
  }'

# Import labyrinth from JSON (Python generator format)
curl -X POST http://localhost:8080/api/v1/labyrinths/import \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d @learning_labyrinth.json

🔐 Authentication Flow

1. Register/Login → Receive Access Token + Refresh Token
2. Use Access Token in Authorization header for API requests
3. When Access Token expires, use Refresh Token to get new tokens
4. Repeat step 2-3

🧪 Testing

# Run all tests
go test ./...

# Run with coverage
go test -cover ./...

# Run specific package
go test ./internal/generator/...

# Integration tests (requires Docker)
make test-integration

📊 Database Schema

PostgreSQL Tables

👤 Users & Profiles

  • users - User accounts and authentication
  • user_profiles - Extended user profiles (level, XP, stats)
  • user_statistics - User gameplay statistics

🏗️ Labyrinths (Core)

  • labyrinths - Main labyrinth/maze table
  • labyrinth_generation_settings - Generation parameters
  • labyrinth_languages - Languages for learning
  • labyrinth_support_items - Support items (compass, map, etc.)
  • rooms - Rooms in labyrinths
  • corridors - Corridors connecting rooms
  • room_connections - Navigation between rooms

📚 Quests & Content

  • quests - Educational quests in rooms
  • quest_questions - Detailed quest questions
  • labyrinth_keys - Keys to unlock areas

🔗 Sharing & Export

  • labyrinth_shares - Public share links
  • labyrinth_share_logs - Share usage logs
  • labyrinth_exports - Export history (JSON, PDF, PNG)
  • labyrinth_versions - Version history and snapshots

🎮 Gameplay

  • play_sessions - User gameplay sessions
  • room_progress - Progress through rooms
  • quest_progress - Quest completion tracking

⭐ Community

  • labyrinth_reviews - Ratings and reviews
  • user_favorite_labyrinths - User favorites
  • labyrinth_collections - User collections

📖 Dictionaries (Reference Data)

  • difficulty_levels - Basic, Intermediate, Advanced
  • room_types - Briefing, Quest, Junction, Story, Dummy
  • quest_types - Word Mosaic, Language Pairs, etc.
  • languages - Available languages for learning
  • corridor_types - Straight, Winding, Bridge, Teleport
  • support_items - Compass, Map, Dictionary, etc.
  • story_themes - Themes for story rooms
  • reward_types - Quest reward types

📝 Full database documentation: See init-db/README_DATABASE.md

🔧 Database initialization scripts:

  1. 01-init-forgemaze.sql - Base schema
  2. 04-init-labyrinth-tables.sql - Labyrinth tables
  3. 05-seed-labyrinth-data.sql - Reference data

📈 Monitoring

Prometheus metrics available at /metrics:

  • HTTP request duration
  • Request count by endpoint
  • Active connections
  • Database query latency
  • Cache hit/miss rates

🤝 Contributing

See CONTRIBUTING.md for contribution guidelines.

🔗 Links

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages