Backend REST API service for ForgeMaze platform - authentication, maze generation, database operations, and business logic..
- 🔐 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
- Go 1.21+
- PostgreSQL 15+
- MongoDB 6+
- Redis 7+
# 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 runAPI will be available at http://localhost:8080
# Start all services (API + PostgreSQL + MongoDB + Redis)
docker-compose up -d
# View logs
docker-compose logs -f api
# Stop services
docker-compose downforgemaze-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
- 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
# 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_xxxxxxxxxmake 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 containerPOST /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 settings → Email (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).
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
POST /api/v1/generator/generate
GET /api/v1/generator/algorithms
POST /api/v1/generator/validate
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)
# 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.json1. 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
# Run all tests
go test ./...
# Run with coverage
go test -cover ./...
# Run specific package
go test ./internal/generator/...
# Integration tests (requires Docker)
make test-integrationusers- User accounts and authenticationuser_profiles- Extended user profiles (level, XP, stats)user_statistics- User gameplay statistics
labyrinths- Main labyrinth/maze tablelabyrinth_generation_settings- Generation parameterslabyrinth_languages- Languages for learninglabyrinth_support_items- Support items (compass, map, etc.)rooms- Rooms in labyrinthscorridors- Corridors connecting roomsroom_connections- Navigation between rooms
quests- Educational quests in roomsquest_questions- Detailed quest questionslabyrinth_keys- Keys to unlock areas
labyrinth_shares- Public share linkslabyrinth_share_logs- Share usage logslabyrinth_exports- Export history (JSON, PDF, PNG)labyrinth_versions- Version history and snapshots
play_sessions- User gameplay sessionsroom_progress- Progress through roomsquest_progress- Quest completion tracking
labyrinth_reviews- Ratings and reviewsuser_favorite_labyrinths- User favoriteslabyrinth_collections- User collections
difficulty_levels- Basic, Intermediate, Advancedroom_types- Briefing, Quest, Junction, Story, Dummyquest_types- Word Mosaic, Language Pairs, etc.languages- Available languages for learningcorridor_types- Straight, Winding, Bridge, Teleportsupport_items- Compass, Map, Dictionary, etc.story_themes- Themes for story roomsreward_types- Quest reward types
📝 Full database documentation: See init-db/README_DATABASE.md
🔧 Database initialization scripts:
01-init-forgemaze.sql- Base schema04-init-labyrinth-tables.sql- Labyrinth tables05-seed-labyrinth-data.sql- Reference data
Prometheus metrics available at /metrics:
- HTTP request duration
- Request count by endpoint
- Active connections
- Database query latency
- Cache hit/miss rates
See CONTRIBUTING.md for contribution guidelines.