Ruby on Rails API for the ProStaff.gg esports team management platform.
Key Features (Click to show details)
- JWT Authentication with refresh tokens and token blacklisting
- Interactive Swagger Documentation (170+ endpoints documented)
- Riot Games API Integration for automatic match import and player sync
- Advanced Analytics (KDA trends, champion pools, vision control, etc.)
- Scouting System with talent discovery and watchlist management
- VOD Review System with timestamp annotations
- ️ Schedule Management for matches, scrims, and team events
- Goal Tracking for team and player performance objectives
- Competitive Module with PandaScore integration and draft analysis
- Scrims Management with opponent tracking and analytics
- Strategy Module with draft planning and tactical boards
- Support System with ticketing and FAQ management
- Background Jobs with Sidekiq for async processing
- ️ Security Hardened (OWASP Top 10, Brakeman, ZAP tested)
- High Performance (p95: ~500ms, with cache: ~50ms)
- ️ Modular Monolith architecture for scalability
- Quick Start
- Technology Stack
- Architecture
- Setup
- Development Tools
- API Documentation
- Testing
- Performance & Load Testing
- Security
- Deployment
- Contributing
- License
Quick Start (Click to show details)
# Start all services (API, PostgreSQL, Redis, Sidekiq)
docker compose up -d
# Create test user
docker exec prostaff-api-api-1 rails runner scripts/create_test_user.rb
# Get JWT token for testing
./scripts/get-token.sh
# Access API docs
open http://localhost:3333/api-docs
# Run smoke tests
./load_tests/run-tests.sh smoke local
# Run security scan
./security_tests/scripts/brakeman-scan.sh# Install dependencies
bundle install
# Generate secrets
./scripts/generate_secrets.sh # Copy output to .env
# Setup database
rails db:create db:migrate db:seed
# Start Redis (in separate terminal)
redis-server
# Start Sidekiq (in separate terminal)
bundle exec sidekiq
# Start Rails server
rails server -p 3333
# Get JWT token for testing
./scripts/get-token.sh
# Access API docs
open http://localhost:3333/api-docsAPI will be available at: http://localhost:3333
Swagger Docs: http://localhost:3333/api-docs
- Ruby: 3.4.5
- Rails: 7.2.0 (API-only mode)
- Database: PostgreSQL 14+
- Authentication: JWT (with refresh tokens)
- Background Jobs: Sidekiq
- Caching: Redis (port 6380)
- API Documentation: Swagger/OpenAPI 3.0 (rswag)
- Testing: RSpec, Integration Specs, k6, OWASP ZAP
- Authorization: Pundit
- Serialization: Blueprinter
This API follows a modular monolith architecture with the following modules:
authentication- User authentication and authorizationdashboard- Dashboard statistics and metricsplayers- Player management and statisticsscouting- Player scouting and talent discoveryanalytics- Performance analytics and reportingmatches- Match data and statisticsschedules- Event and schedule managementvod_reviews- Video review and timestamp managementteam_goals- Goal setting and trackingriot_integration- Riot Games API integrationcompetitive- PandaScore integration, pro matches, draft analysisscrims- Scrim management and opponent team trackingstrategy- Draft planning and tactical board systemsupport- Support ticket system with staff and FAQ management
graph TB
subgraph "Client Layer"
Client[Frontend Application]
end
subgraph "API Gateway"
Router[Rails Router]
CORS[CORS Middleware]
RateLimit[Rate Limiting]
Auth[Authentication Middleware]
end
subgraph "Application Layer - Modular Monolith"
subgraph "Authentication Module"
AuthController[Auth Controller]
JWTService[JWT Service]
UserModel[User Model]
end
subgraph "Dashboard Module"
DashboardController[Dashboard Controller]
DashStats[Statistics Service]
end
subgraph "Players Module"
PlayersController[Players Controller]
PlayerModel[Player Model]
ChampionPoolModel[Champion Pool Model]
end
subgraph "Scouting Module"
ScoutingController[Scouting Controller]
ScoutingTargetModel[Scouting Target Model]
Watchlist[Watchlist Service]
end
subgraph "Analytics Module"
AnalyticsController[Analytics Controller]
PerformanceService[Performance Service]
KDAService[KDA Trend Service]
end
subgraph "Matches Module"
MatchesController[Matches Controller]
MatchModel[Match Model]
PlayerMatchStatModel[Player Match Stat Model]
end
subgraph "Schedules Module"
SchedulesController[Schedules Controller]
ScheduleModel[Schedule Model]
end
subgraph "VOD Reviews Module"
VODController[VOD Reviews Controller]
VodReviewModel[VOD Review Model]
VodTimestampModel[VOD Timestamp Model]
end
subgraph "Team Goals Module"
GoalsController[Team Goals Controller]
TeamGoalModel[Team Goal Model]
end
subgraph "Riot Integration Module"
RiotService[Riot API Service]
RiotSync[Sync Service]
end
subgraph "Competitive Module"
CompetitiveController[Competitive Controller]
ProMatchesController[Pro Matches Controller]
PandaScoreService[PandaScore Service]
DraftAnalyzer[Draft Analyzer]
end
subgraph "Scrims Module"
ScrimsController[Scrims Controller]
OpponentTeamsController[Opponent Teams Controller]
ScrimAnalytics[Scrim Analytics Service]
end
subgraph "Strategy Module"
DraftPlansController[Draft Plans Controller]
TacticalBoardsController[Tactical Boards Controller]
DraftAnalysisService[Draft Analysis Service]
end
subgraph "Support Module"
SupportTicketsController[Support Tickets Controller]
SupportFaqsController[Support FAQs Controller]
SupportStaffController[Support Staff Controller]
SupportTicketModel[Support Ticket Model]
SupportFaqModel[Support FAQ Model]
end
end
subgraph "Data Layer"
PostgreSQL[(PostgreSQL Database)]
Redis[(Redis Cache)]
end
subgraph "Background Jobs"
Sidekiq[Sidekiq Workers]
JobQueue[Job Queue]
end
subgraph "External Services"
RiotAPI[Riot Games API]
PandaScoreAPI[PandaScore API]
end
Client -->|HTTP/JSON| CORS
CORS --> RateLimit
RateLimit --> Auth
Auth --> Router
Router --> AuthController
Router --> DashboardController
Router --> PlayersController
Router --> ScoutingController
Router --> AnalyticsController
Router --> MatchesController
Router --> SchedulesController
Router --> VODController
Router --> GoalsController
Router --> CompetitiveController
Router --> ProMatchesController
Router --> ScrimsController
Router --> OpponentTeamsController
Router --> DraftPlansController
Router --> TacticalBoardsController
Router --> SupportTicketsController
Router --> SupportFaqsController
Router --> SupportStaffController
AuthController --> JWTService
AuthController --> UserModel
PlayersController --> PlayerModel
PlayerModel --> ChampionPoolModel
ScoutingController --> ScoutingTargetModel
ScoutingController --> Watchlist
Watchlist --> PostgreSQL
MatchesController --> MatchModel
MatchModel --> PlayerMatchStatModel
SchedulesController --> ScheduleModel
VODController --> VodReviewModel
VodReviewModel --> VodTimestampModel
GoalsController --> TeamGoalModel
AnalyticsController --> PerformanceService
AnalyticsController --> KDAService
CompetitiveController --> PandaScoreService
CompetitiveController --> DraftAnalyzer
ScrimsController --> ScrimAnalytics
ScrimAnalytics --> PostgreSQL
DraftPlansController --> DraftAnalysisService
SupportTicketsController --> SupportTicketModel
SupportFaqsController --> SupportFaqModel
SupportStaffController --> UserModel
AuditLogModel[AuditLog Model] --> PostgreSQL
ChampionPoolModel[ChampionPool Model] --> PostgreSQL
CompetitiveMatchModel[CompetitiveMatch Model] --> PostgreSQL
DraftPlanModel[DraftPlan Model] --> PostgreSQL
MatchModel[Match Model] --> PostgreSQL
NotificationModel[Notification Model] --> PostgreSQL
OpponentTeamModel[OpponentTeam Model] --> PostgreSQL
OrganizationModel[Organization Model] --> PostgreSQL
PasswordResetTokenModel[PasswordResetToken Model] --> PostgreSQL
PlayerModel[Player Model] --> PostgreSQL
PlayerMatchStatModel[PlayerMatchStat Model] --> PostgreSQL
ScheduleModel[Schedule Model] --> PostgreSQL
ScoutingTargetModel[ScoutingTarget Model] --> PostgreSQL
ScrimModel[Scrim Model] --> PostgreSQL
SupportFaqModel[SupportFaq Model] --> PostgreSQL
SupportTicketModel[SupportTicket Model] --> PostgreSQL
SupportTicketMessageModel[SupportTicketMessage Model] --> PostgreSQL
TacticalBoardModel[TacticalBoard Model] --> PostgreSQL
TeamGoalModel[TeamGoal Model] --> PostgreSQL
TokenBlacklistModel[TokenBlacklist Model] --> PostgreSQL
UserModel[User Model] --> PostgreSQL
VodReviewModel[VodReview Model] --> PostgreSQL
VodTimestampModel[VodTimestamp Model] --> PostgreSQL
JWTService --> Redis
DashStats --> Redis
PerformanceService --> Redis
PlayersController --> RiotService
MatchesController --> RiotService
ScoutingController --> RiotService
RiotService --> RiotSync
RiotService --> RiotAPI
RiotService --> Sidekiq
PandaScoreService --> PandaScoreAPI[PandaScore API]
Sidekiq -- Uses --> Redis
style Client fill:#e1f5ff
style PostgreSQL fill:#336791
style Redis fill:#d82c20
style RiotAPI fill:#eb0029
style PandaScoreAPI fill:#ff6b35
style Sidekiq fill:#b1003e
Key Architecture Principles:
- Modular Monolith: Each module is self-contained with its own controllers, models, and services
- API-Only: Rails configured in API mode for JSON responses
- JWT Authentication: Stateless authentication using JWT tokens
- Background Processing: Long-running tasks handled by Sidekiq
- Caching: Redis used for session management and performance optimization
- External Integration: Riot Games API integration for real-time data
- Rate Limiting: Rack::Attack for API rate limiting
- CORS: Configured for cross-origin requests from frontend
- Ruby 3.2+
- PostgreSQL 14+
- Redis 6+
- Clone the repository:
git clone <repository-url>
cd prostaff-api- Install dependencies:
bundle install- Setup environment variables:
cp .env.example .envEdit .env with your configuration:
- Database credentials
- JWT secret key
- Riot API key
- Redis URL
- CORS origins
- Setup the database:
rails db:create
rails db:migrate
rails db:seed- Start the services:
Start Redis:
redis-serverStart Sidekiq (in another terminal):
bundle exec sidekiqStart the Rails server:
rails serverThe API will be available at http://localhost:3333
Generate secure secrets for your .env file:
./scripts/generate_secrets.shThis will generate:
SECRET_KEY_BASE- Rails secret keyJWT_SECRET_KEY- JWT signing key
Generate a JWT token for testing the API:
./scripts/get-token.shThis will:
- Create or find a test user (
test@prostaff.gg) - Generate a valid JWT token
- Show instructions on how to use it
Quick usage:
# Export to environment variable
export BEARER_TOKEN=$(./scripts/get-token.sh | grep -oP 'eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*')
# Use in curl
curl -H "Authorization: Bearer $BEARER_TOKEN" http://localhost:3333/api/v1/playersCustom credentials:
TEST_EMAIL="admin@example.com" TEST_PASSWORD="MyPass123!" ./scripts/get-token.sh📚 API Documentation (Click to show details)
The API provides interactive documentation powered by Swagger/OpenAPI 3.0:
Access the docs:
http://localhost:3333/api-docs
Features:
- ✅ Try out endpoints directly from the browser
- ✅ See request/response schemas
- ✅ Authentication support (Bearer token)
- ✅ Complete parameter documentation
- ✅ Example requests and responses
The Swagger documentation is automatically generated from RSpec integration tests:
# Run integration specs and generate Swagger docs
bundle exec rake rswag:specs:swaggerize
# Or run specs individually
bundle exec rspec spec/integration/The generated documentation file is located at swagger/v1/swagger.yaml.
http://localhost:3333/api/v1
All endpoints (except auth endpoints) require a Bearer token in the Authorization header:
Authorization: Bearer <your-jwt-token>
Token Details:
- Access Token: Expires in 24 hours (configurable via
JWT_EXPIRATION_HOURS) - Refresh Token: Expires in 7 days
- Token Type: Bearer (JWT)
Getting a token:
# Option 1: Use the script
./scripts/get-token.sh
# Option 2: Login via API
curl -X POST http://localhost:3333/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@prostaff.gg","password":"Test123!@#"}'Refreshing a token:
curl -X POST http://localhost:3333/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token":"your-refresh-token"}'POST /auth/register- Register new organization and admin userPOST /auth/login- Login userPOST /auth/refresh- Refresh JWT tokenPOST /auth/logout- Logout userPOST /auth/forgot-password- Request password resetPOST /auth/reset-password- Reset passwordGET /auth/me- Get current user info
GET /dashboard- Get complete dashboard dataGET /dashboard/stats- Get quick statsGET /dashboard/activities- Get recent activitiesGET /dashboard/schedule- Get upcoming schedule
GET /players- List playersGET /players/:id- Get player detailsPOST /players- Create playerPATCH /players/:id- Update playerDELETE /players/:id- Delete playerGET /players/stats- Get roster statisticsPOST /players/import- Import player from Riot API
GET /matches- List matchesGET /matches/:id- Get match detailsPOST /matches- Create matchPOST /matches/import- Import match from Riot API
GET /scouting/players- List scouting targetsGET /scouting/regions- Get available regionsPOST /scouting/players- Add scouting target
GET /analytics/performance- Team performance analyticsGET /analytics/team-comparison- Compare all playersGET /analytics/champions/:player_id- Champion pool statisticsGET /analytics/kda-trend/:player_id- KDA trend over timeGET /analytics/laning/:player_id- Laning phase performanceGET /analytics/teamfights/:player_id- Teamfight performanceGET /analytics/vision/:player_id- Vision control statistics
GET /schedules- List all scheduled eventsGET /schedules/:id- Get schedule detailsPOST /schedules- Create new eventPATCH /schedules/:id- Update eventDELETE /schedules/:id- Delete event
GET /team-goals- List all goalsGET /team-goals/:id- Get goal detailsPOST /team-goals- Create new goalPATCH /team-goals/:id- Update goal progressDELETE /team-goals/:id- Delete goal
GET /vod-reviews- List VOD reviewsGET /vod-reviews/:id- Get review detailsPOST /vod-reviews- Create new reviewPATCH /vod-reviews/:id- Update reviewDELETE /vod-reviews/:id- Delete reviewGET /vod-reviews/:id/timestamps- List timestampsPOST /vod-reviews/:id/timestamps- Create timestampPATCH /vod-timestamps/:id- Update timestampDELETE /vod-timestamps/:id- Delete timestamp
GET /riot-data/champions- Get champions ID mapGET /riot-data/champions/:key- Get champion detailsGET /riot-data/all-champions- Get all champions dataGET /riot-data/items- Get all itemsGET /riot-data/summoner-spells- Get summoner spellsGET /riot-data/version- Get current Data Dragon versionPOST /riot-data/clear-cache- Clear Data Dragon cache (owner only)POST /riot-data/update-cache- Update Data Dragon cache (owner only)
GET /riot-integration/sync-status- Get sync status for all players
GET /competitive-matches- List competitive matchesGET /competitive-matches/:id- Get competitive match detailsGET /competitive/pro-matches- List all pro matchesGET /competitive/pro-matches/:id- Get pro match detailsGET /competitive/pro-matches/upcoming- Get upcoming pro matchesGET /competitive/pro-matches/past- Get past pro matchesPOST /competitive/pro-matches/refresh- Refresh pro matches from PandaScorePOST /competitive/pro-matches/import- Import specific pro matchPOST /competitive/draft-comparison- Compare team compositionsGET /competitive/meta/:role- Get meta champions by roleGET /competitive/composition-winrate- Get composition winrate statisticsGET /competitive/counters- Get champion counter suggestions
GET /scrims/scrims- List all scrimsGET /scrims/scrims/:id- Get scrim detailsPOST /scrims/scrims- Create new scrimPATCH /scrims/scrims/:id- Update scrimDELETE /scrims/scrims/:id- Delete scrimPOST /scrims/scrims/:id/add_game- Add game to scrimGET /scrims/scrims/calendar- Get scrims calendarGET /scrims/scrims/analytics- Get scrims analyticsGET /scrims/opponent-teams- List opponent teamsGET /scrims/opponent-teams/:id- Get opponent team detailsPOST /scrims/opponent-teams- Create opponent teamPATCH /scrims/opponent-teams/:id- Update opponent teamDELETE /scrims/opponent-teams/:id- Delete opponent teamGET /scrims/opponent-teams/:id/scrim-history- Get scrim history with opponent
GET /strategy/draft-plans- List draft plansGET /strategy/draft-plans/:id- Get draft plan detailsPOST /strategy/draft-plans- Create new draft planPATCH /strategy/draft-plans/:id- Update draft planDELETE /strategy/draft-plans/:id- Delete draft planPOST /strategy/draft-plans/:id/analyze- Analyze draft planPATCH /strategy/draft-plans/:id/activate- Activate draft planPATCH /strategy/draft-plans/:id/deactivate- Deactivate draft planGET /strategy/tactical-boards- List tactical boardsGET /strategy/tactical-boards/:id- Get tactical board detailsPOST /strategy/tactical-boards- Create new tactical boardPATCH /strategy/tactical-boards/:id- Update tactical boardDELETE /strategy/tactical-boards/:id- Delete tactical boardGET /strategy/tactical-boards/:id/statistics- Get tactical board statisticsGET /strategy/assets/champion/:champion_name- Get champion assetsGET /strategy/assets/map- Get map assets
GET /support/tickets- List user's ticketsGET /support/tickets/:id- Get ticket detailsPOST /support/tickets- Create new support ticketPATCH /support/tickets/:id- Update ticketDELETE /support/tickets/:id- Delete ticketPOST /support/tickets/:id/close- Close ticketPOST /support/tickets/:id/reopen- Reopen ticketPOST /support/tickets/:id/messages- Add message to ticketGET /support/faq- List all FAQsGET /support/faq/:slug- Get FAQ by slugPOST /support/faq/:slug/helpful- Mark FAQ as helpfulPOST /support/faq/:slug/not-helpful- Mark FAQ as not helpfulGET /support/staff/dashboard- Support staff dashboard (staff only)GET /support/staff/analytics- Support analytics (staff only)POST /support/staff/tickets/:id/assign- Assign ticket to staff (staff only)POST /support/staff/tickets/:id/resolve- Resolve ticket (staff only)
For complete endpoint documentation with request/response examples, visit /api-docs
Run the complete test suite:
bundle exec rspecRun specific test types:
# Unit tests (models, services)
bundle exec rspec spec/models
bundle exec rspec spec/services
# Request tests (controllers)
bundle exec rspec spec/requests
# Integration tests (Swagger documentation)
bundle exec rspec spec/integrationIntegration tests serve dual purpose:
- Test API endpoints with real HTTP requests
- Generate Swagger documentation automatically
# Run integration tests and generate Swagger docs
bundle exec rake rswag:specs:swaggerize
# Run specific integration spec
bundle exec rspec spec/integration/players_spec.rbCurrent coverage:
- ✅ Authentication (8 endpoints)
- ✅ Players (9 endpoints)
- ✅ Matches (11 endpoints)
- ✅ Scouting (10 endpoints)
- ✅ Schedules (8 endpoints)
- ✅ Team Goals (8 endpoints)
- ✅ VOD Reviews (11 endpoints)
- ✅ Analytics (7 endpoints)
- ✅ Riot Data (14 endpoints)
- ✅ Riot Integration (1 endpoint)
- ✅ Dashboard (4 endpoints)
- ✅ Competitive (14 endpoints)
- ✅ Scrims (14 endpoints)
- ✅ Strategy (16 endpoints)
- ✅ Support (15 endpoints)
Total: 170+ endpoints documented
View coverage report after running tests:
open coverage/index.htmlRequired environment variables for production:
DATABASE_URL=postgresql://user:password@host:5432/database
REDIS_URL=redis://host:6379/0
JWT_SECRET_KEY=your-production-secret
RIOT_API_KEY=your-riot-api-key
CORS_ORIGINS=https://your-frontend-domain.com
SECRET_KEY_BASE=your-rails-secretA Dockerfile is provided for containerized deployment:
docker build -t prostaff-api .
docker run -p 3333:3000 prostaff-apiThis project includes an automated workflow that keeps the architecture diagram in sync with the codebase:
-
Trigger: Automatically runs when changes are made to:
app/modules/**- Module definitionsapp/models/**- Data modelsapp/controllers/**- Controllersconfig/routes.rb- Route definitionsGemfile- Dependencies
-
Process:
- GitHub Actions workflow detects relevant code changes
- Runs
scripts/update_architecture_diagram.rb - Script analyzes project structure (modules, models, controllers, services)
- Generates updated Mermaid diagram
- Updates README.md with new diagram
- Commits changes back to the repository
-
Manual Update: You can also manually update the diagram:
ruby scripts/update_architecture_diagram.rb
The diagram automatically reflects:
- New modules added to
app/modules/ - New models created
- New controllers and routes
- Service integrations (Riot API, Redis, PostgreSQL, Sidekiq)
# Quick smoke test (1 min)
./load_tests/run-tests.sh smoke local
# Full load test (16 min)
./load_tests/run-tests.sh load local
# Stress test (28 min)
./load_tests/run-tests.sh stress localCurrent Performance:
- p(95): ~880ms (Docker dev)
- Production estimate: ~500ms
- With cache: ~50ms
- Error rate: 0%
Documentation: See TESTING_GUIDE.md and QUICK_START.md
# Complete security audit
./security_tests/scripts/full-security-audit.sh
# Individual scans
./security_tests/scripts/brakeman-scan.sh # Code analysis
./security_tests/scripts/dependency-scan.sh # Vulnerable gems
./security_tests/scripts/zap-baseline-scan.sh # Web app scanCoverage:
- ✅ OWASP Top 10
- ✅ Code security (Brakeman)
- ✅ Dependency vulnerabilities
- ✅ Runtime security (ZAP)
- ✅ CI/CD integration
Documentation: See security_tests/README.md
Automated testing on every push:
- Security Scan: Brakeman + dependency check
- Load Test: Nightly smoke tests
- Nightly Audit: Complete security scan
See .github/workflows/ for details.
- Create a feature branch
- Make your changes
- Add tests
- Run security scan:
./security_tests/scripts/brakeman-scan.sh - Ensure all tests pass
- Submit a pull request
Note: The architecture diagram will be automatically updated when you add new modules, models, or controllers.
Copyright e Licenciamento
© 2025 ProStaff.gg. Todos os direitos reservados.
Este repositório contém o código-fonte oficial da API para a plataforma de e-sports ProStaff.gg.
O código-fonte contido aqui é disponibilizado sob a licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Você pode encontrar o texto completo da licença no arquivo LICENSE neste repositório.
Shield:
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Prostaff.gg isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties.
Riot Games, and all associated properties are trademarks or registered trademarks of Riot Games, Inc.