Skip to content

API 4 my e-sports hub (modular Monolith)

License

Notifications You must be signed in to change notification settings

Bulletdev/prostaff-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

423 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

>        ██████╗ ██████╗  ██████╗ ███████╗████████╗ █████╗ ███████╗███████╗
>        ██╔══██╗██╔══██╗██╔═══██╗██╔════╝╚══██╔══╝██╔══██╗██╔════╝██╔════╝
>        ██████╔╝██████╔╝██║   ██║███████╗   ██║   ███████║█████╗  █████╗
>        ██╔═══╝ ██╔══██╗██║   ██║╚════██║   ██║   ██╔══██║██╔══╝  ██╔══╝
>        ██║     ██║  ██║╚██████╔╝███████║   ██║   ██║  ██║██║     ██║
>        ╚═╝     ╚═╝  ╚═╝ ╚═════╝ ╚══════╝   ╚═╝   ╚═╝  ╚═╝╚═╝     ╚═╝
                  API — eSports Analytics Hub - ProStaff.gg

Security Scan Codacy Badge

Ruby Version Rails Version PostgreSQL Redis Swagger License


╔══════════════════════════════════════════════════════════════════════════════╗
║  PROSTAFF API — Ruby on Rails 7.2 (API-Only)                                 ║
╠══════════════════════════════════════════════════════════════════════════════╣
║  Backend for the ProStaff.gg esports team management platform.               ║
║  200+ documented endpoints · JWT Auth · Modular Monolith · p95 ~500ms        ║
╚══════════════════════════════════════════════════════════════════════════════╝

▶ Key Features (click to expand)
┌─────────────────────────────────────────────────────────────────────────────┐
│  [■] JWT Authentication       — Refresh tokens + token blacklisting         │
│  [■] HashID URLs              — Base62 encoding for obfuscated URLs         │
│  [■] Swagger Docs             — 200+ endpoints documented interactively     │
│  [■] Riot Games API           — Automatic match and player import           │
│  [■] Advanced Analytics       — KDA trends, champion pools, vision control  │
│  [■] Scouting System          — Talent discovery + watchlist management     │
│  [■] VOD Review System        — Collaborative timestamp annotations         │
│  [■] Schedule Management      — Matches, scrims and team events             │
│  [■] Goal Tracking            — Performance goals (team and players)        │
│  [■] Competitive Module       — PandaScore integration + draft analysis     │
│  [■] Scrims Management        — Opponent tracking + analytics               │
│  [■] Strategy Module          — Draft planning + tactical boards            │
│  [■] Support System           — Ticketing + staff dashboard + FAQ           │
│  [■] Global Search            — Meilisearch full-text search across models  │
│  [■] Real-time Messaging      — Action Cable WebSocket team chat            │
│  [■] Background Jobs          — Sidekiq for async background processing     │
│  [■] Security Hardened        — OWASP Top 10, Brakeman, ZAP tested          │
│  [■] High Performance         — p95: ~500ms · cached: ~50ms                 │
│  [■] Modular Monolith         — Scalable modular architecture               │
│  [■] Observability            — /health/live + /health/ready + Sidekiq mon. │
│  [■] 401 Rate Spike Detection — Sliding-window middleware, alerts at >5%    │
│  [■] Job Heartbeat Tracking   — Stale scheduled job detection via Redis     │
└─────────────────────────────────────────────────────────────────────────────┘

Table of Contents

┌──────────────────────────────────────────────────────┐
│  01 · Quick Start                                    │
│  02 · Technology Stack                               │
│  03 · Architecture                                   │
│  04 · Setup                                          │
│  05 · Development Tools                              │
│  06 · API Documentation                              │
│  07 · Testing                                        │
│  08 · Performance & Load Testing                     │
│  09 · Security                                       │
│  10 · Observability & Monitoring                     │
│  11 · Deployment                                     │
│  12 · CI/CD                                          │
│  13 · Contributing                                   │
│  14 · License                                        │
└──────────────────────────────────────────────────────┘

01 · Quick Start

▶ Option 1: Docker (Recommended)
# 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
▶ Option 2: Local Development (Without Docker)
# 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-docs
  API:          http://localhost:3333
  Swagger Docs: http://localhost:3333/api-docs

02 · Technology Stack

╔══════════════════════╦════════════════════════════════════════════════════╗
║  LAYER               ║  TECNOLOGY                                         ║
╠══════════════════════╬════════════════════════════════════════════════════╣
║  Language            ║  Ruby 3.4.5                                        ║
║  Framework           ║  Rails 7.2.0 (API-only mode)                       ║
║  Database            ║  PostgreSQL 14+                                    ║
║  Authentication      ║  JWT (access + refresh tokens)                     ║
║  URL Obfuscation     ║  HashID with Base62 encoding                       ║
║  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                                       ║
║  Full-text Search    ║  Meilisearch                                       ║
║  Real-time           ║  Action Cable (WebSocket)                          ║
╚══════════════════════╩════════════════════════════════════════════════════╝

03 · Architecture

This API follows a modular monolith architecture:

┌─────────────────────────────────────────────────────────────────────────────┐
│  MODULE             │  RESPONSIBILITY                                       │
├─────────────────────┼───────────────────────────────────────────────────────┤
│  authentication     │  User auth and authorization                          │
│  dashboard          │  Dashboard statistics and metrics                     │
│  players            │  Player management and statistics                     │
│  scouting           │  Player scouting and talent discovery                 │
│  analytics          │  Performance, competitive draft, tournament & opponent│
│  matches            │  Match data and statistics                            │
│  schedules          │  Event and schedule management                        │
│  vod_reviews        │  Video review and timestamp management                │
│  team_goals         │  Goal setting and tracking                            │
│  riot_integration   │  Riot Games API integration                           │
│  competitive        │  PandaScore integration, pro matches, draft analysis  │
│  scrims             │  Scrim management and opponent team tracking          │
│  strategy           │  Draft planning and tactical board system             │
│  support            │  Support ticket system with staff dashboard and FAQ   │
│  messaging          │  Real-time team chat via Action Cable WebSocket       │
│  search             │  Global full-text search powered by Meilisearch       │
│  notifications      │  In-app notification system                           │
└─────────────────────┴───────────────────────────────────────────────────────┘

Architecture Diagram

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[Support Ticket Model] --> PostgreSQL
    SupportTicketMessageModel[SupportTicketMessage Model] --> PostgreSQL
    TacticalBoardModel[TacticalBoard Model] --> PostgreSQL
    TeamGoalModel[Team Goal 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
    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
Loading

Key Architecture Principles:

  1. Modular Monolith: Each module is self-contained with its own controllers, models, and services
  2. API-Only: Rails configured in API mode for JSON responses
  3. JWT Authentication: Stateless authentication using JWT tokens
  4. Background Processing: Long-running tasks handled by Sidekiq
  5. Caching: Redis used for session management and performance optimization
  6. External Integration: Riot Games API integration for real-time data
  7. Rate Limiting: Rack::Attack for API rate limiting
  8. CORS: Configured for cross-origin requests from frontend

Deployment Architecture

graph TB
    subgraph "Clients"
        FrontendApp["ProStaff.gg<br/>Front + TypeScript SPA"]
        PlayerPortal["Player Portal<br/>JWT player token"]
    end

    subgraph "Production — Coolify"
        Traefik["Traefik<br/>TLS + Let's Encrypt<br/>WebSocket proxy"]
    end

    subgraph "Rails — Puma"
        Cable["Action Cable<br/>WebSocket /cable<br/>(team chat)"]
        Router["Rails Router<br/>REST API v1<br/>200+ endpoints"]
        Sidekiq["Sidekiq<br/>Background Workers<br/>(Riot sync · reindex)"]
    end

    subgraph "Data"
        PG[("PostgreSQL")]
        RD[("Redis")]
        Meili[("Meilisearch")]
    end

    subgraph "External APIs"
        RiotAPI["Riot Games API"]
        PandaScore["PandaScore API"]
    end

    FrontendApp -- "HTTPS REST" --> Traefik
    FrontendApp -- "WSS /cable" --> Traefik
    PlayerPortal -- "HTTPS REST" --> Traefik

    Traefik -- "HTTP" --> Router
    Traefik -- "WS upgrade" --> Cable

    Router -- "reads / writes" --> PG
    Router -- "cache · JWT blacklist" --> RD
    Router -- "full-text search" --> Meili
    Cable -- "pub/sub" --> RD
    Sidekiq -- "async jobs" --> PG
    Sidekiq -- "queue · cache" --> RD
    Sidekiq -- "reindex docs" --> Meili

    Router -- "player data" --> RiotAPI
    Sidekiq -- "match sync" --> RiotAPI
    Router -- "pro matches" --> PandaScore

    style FrontendApp fill:#1e88e5
    style PlayerPortal fill:#5c6bc0
    style Traefik fill:#1565c0
    style Cable fill:#b1003e
    style Sidekiq fill:#b1003e
    style PG fill:#336791
    style RD fill:#d82c20
    style Meili fill:#ff5722
    style RiotAPI fill:#eb0029
    style PandaScore fill:#ff6b35
Loading

04 · Setup

Prerequisites

[✓] Ruby 3.2+
[✓] PostgreSQL 14+
[✓] Redis 6+

Installation

1. Clone the repository:

git clone <repository-url>
cd prostaff-api

2. Install dependencies:

bundle install

3. Setup environment variables:

cp .env.example .env

Edit .env with your configuration:

  • Database credentials
  • JWT secret key
  • Riot API key (get from https://developer.riotgames.com)
  • PandaScore API key (optional, for competitive data)
  • Redis URL
  • CORS origins
  • HashID salt (for URL obfuscation — keep secret!)
  • Frontend URL

4. Setup the database:

rails db:create
rails db:migrate
rails db:seed

5. Start the services:

# Terminal 1 — Redis
redis-server

# Terminal 2 — Sidekiq
bundle exec sidekiq

# Terminal 3 — Rails server
rails server

API available at http://localhost:3333


05 · Development Tools

Generate Secrets

Generate secure secrets for your .env file:

./scripts/generate_secrets.sh

Generates: SECRET_KEY_BASE (Rails) and JWT_SECRET_KEY (JWT signing).

Get JWT Token (for API testing)

./scripts/get-token.sh

This will:

  1. Create or find a test user (test@prostaff.gg)
  2. Generate a valid JWT token
  3. 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/players

Custom credentials:

TEST_EMAIL="admin@example.com" TEST_PASSWORD="MyPass123!" ./scripts/get-token.sh

06 · API Documentation

▶ Interactive Documentation — Swagger UI (click to expand)

Access:

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

Generating/Updating Documentation

# Run integration specs and generate Swagger docs
RSWAG_GENERATE=1 bundle exec rake rswag:specs:swaggerize

# Or run specs individually
bundle exec rspec spec/integration/

Note: RSWAG_GENERATE=1 bypasses the local test-DB requirement — the swagger formatter uses --dry-run so no database queries are executed.

Generated file: swagger/v1/swagger.yaml

Base URL

http://localhost:3333/api/v1

Authentication

All endpoints (except auth) require a Bearer token:

Authorization: Bearer <your-jwt-token>
╔═══════════════╦══════════════════════════════════╗
║  Token Type   ║  Bearer (JWT)                    ║
║  Access TTL   ║  24h (via JWT_EXPIRATION_HOURS)  ║
║  Refresh TTL  ║  7 days                          ║
╚═══════════════╩══════════════════════════════════╝

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"}'

Authentication Endpoints

  • POST /auth/register — Register new organization and admin user
  • POST /auth/login — Login user
  • POST /auth/refresh — Refresh JWT token
  • POST /auth/logout — Logout user
  • POST /auth/forgot-password — Request password reset
  • POST /auth/reset-password — Reset password
  • GET /auth/me — Get current user info

Core Endpoints

Dashboard

  • GET /dashboard — Get complete dashboard data
  • GET /dashboard/stats — Get quick stats
  • GET /dashboard/activities — Get recent activities
  • GET /dashboard/schedule — Get upcoming schedule

Players

  • GET /players — List players
  • GET /players/:id — Get player details
  • POST /players — Create player
  • PATCH /players/:id — Update player
  • DELETE /players/:id — Delete player
  • GET /players/stats — Get roster statistics
  • POST /players/import — Import player from Riot API

Matches

  • GET /matches — List matches
  • GET /matches/:id — Get match details
  • POST /matches — Create match
  • POST /matches/import — Import match from Riot API

Scouting

  • GET /scouting/players — List scouting targets
  • GET /scouting/regions — Get available regions
  • POST /scouting/players — Add scouting target

Analytics

  • GET /analytics/performance — Team performance analytics
  • GET /analytics/team-comparison — Compare all players
  • GET /analytics/champions/:player_id — Champion pool statistics
  • GET /analytics/kda-trend/:player_id — KDA trend over time
  • GET /analytics/laning/:player_id — Laning phase performance
  • GET /analytics/teamfights/:player_id — Teamfight performance
  • GET /analytics/vision/:player_id — Vision control statistics
  • GET /analytics/competitive/draft-performance — Pick/ban/side/role performance from competitive matches
  • GET /analytics/competitive/tournament-stats — Win/loss breakdown per tournament and stage
  • GET /analytics/competitive/opponents — Aggregated record against each unique opponent

All competitive analytics endpoints accept optional query filters: tournament, patch, region, start_date, end_date

Schedules

  • GET /schedules — List all scheduled events
  • GET /schedules/:id — Get schedule details
  • POST /schedules — Create new event
  • PATCH /schedules/:id — Update event
  • DELETE /schedules/:id — Delete event

Team Goals

  • GET /team-goals — List all goals
  • GET /team-goals/:id — Get goal details
  • POST /team-goals — Create new goal
  • PATCH /team-goals/:id — Update goal progress
  • DELETE /team-goals/:id — Delete goal

VOD Reviews

  • GET /vod-reviews — List VOD reviews
  • GET /vod-reviews/:id — Get review details
  • POST /vod-reviews — Create new review
  • PATCH /vod-reviews/:id — Update review
  • DELETE /vod-reviews/:id — Delete review
  • GET /vod-reviews/:id/timestamps — List timestamps
  • POST /vod-reviews/:id/timestamps — Create timestamp
  • PATCH /vod-timestamps/:id — Update timestamp
  • DELETE /vod-timestamps/:id — Delete timestamp

Riot Data

  • GET /riot-data/champions — Get champions ID map
  • GET /riot-data/champions/:key — Get champion details
  • GET /riot-data/all-champions — Get all champions data
  • GET /riot-data/items — Get all items
  • GET /riot-data/summoner-spells — Get summoner spells
  • GET /riot-data/version — Get current Data Dragon version
  • POST /riot-data/clear-cache — Clear Data Dragon cache (owner only)
  • POST /riot-data/update-cache — Update Data Dragon cache (owner only)

Riot Integration

  • GET /riot-integration/sync-status — Get sync status for all players

Competitive (PandaScore Integration)

  • GET /competitive-matches — List competitive matches
  • GET /competitive-matches/:id — Get competitive match details
  • GET /competitive/pro-matches — List all pro matches
  • GET /competitive/pro-matches/:id — Get pro match details
  • GET /competitive/pro-matches/upcoming — Get upcoming pro matches
  • GET /competitive/pro-matches/past — Get past pro matches
  • POST /competitive/pro-matches/refresh — Refresh pro matches from PandaScore
  • POST /competitive/pro-matches/import — Import specific pro match
  • POST /competitive/draft-comparison — Compare team compositions
  • GET /competitive/meta/:role — Get meta champions by role
  • GET /competitive/composition-winrate — Get composition winrate statistics
  • GET /competitive/counters — Get champion counter suggestions

Scrims Management

  • GET /scrims/scrims — List all scrims
  • GET /scrims/scrims/:id — Get scrim details
  • POST /scrims/scrims — Create new scrim
  • PATCH /scrims/scrims/:id — Update scrim
  • DELETE /scrims/scrims/:id — Delete scrim
  • POST /scrims/scrims/:id/add_game — Add game to scrim
  • GET /scrims/scrims/calendar — Get scrims calendar
  • GET /scrims/scrims/analytics — Get scrims analytics
  • GET /scrims/opponent-teams — List opponent teams
  • GET /scrims/opponent-teams/:id — Get opponent team details
  • POST /scrims/opponent-teams — Create opponent team
  • PATCH /scrims/opponent-teams/:id — Update opponent team
  • DELETE /scrims/opponent-teams/:id — Delete opponent team
  • GET /scrims/opponent-teams/:id/scrim-history — Get scrim history with opponent

Strategy Module

  • GET /strategy/draft-plans — List draft plans
  • GET /strategy/draft-plans/:id — Get draft plan details
  • POST /strategy/draft-plans — Create new draft plan
  • PATCH /strategy/draft-plans/:id — Update draft plan
  • DELETE /strategy/draft-plans/:id — Delete draft plan
  • POST /strategy/draft-plans/:id/analyze — Analyze draft plan
  • PATCH /strategy/draft-plans/:id/activate — Activate draft plan
  • PATCH /strategy/draft-plans/:id/deactivate — Deactivate draft plan
  • GET /strategy/tactical-boards — List tactical boards
  • GET /strategy/tactical-boards/:id — Get tactical board details
  • POST /strategy/tactical-boards — Create new tactical board
  • PATCH /strategy/tactical-boards/:id — Update tactical board
  • DELETE /strategy/tactical-boards/:id — Delete tactical board
  • GET /strategy/tactical-boards/:id/statistics — Get tactical board statistics
  • GET /strategy/assets/champion/:champion_name — Get champion assets
  • GET /strategy/assets/map — Get map assets

Support System

  • GET /support/tickets — List user's tickets
  • GET /support/tickets/:id — Get ticket details
  • POST /support/tickets — Create new support ticket
  • PATCH /support/tickets/:id — Update ticket
  • DELETE /support/tickets/:id — Delete ticket
  • POST /support/tickets/:id/close — Close ticket
  • POST /support/tickets/:id/reopen — Reopen ticket
  • POST /support/tickets/:id/messages — Add message to ticket
  • GET /support/faq — List all FAQs
  • GET /support/faq/:slug — Get FAQ by slug
  • POST /support/faq/:slug/helpful — Mark FAQ as helpful
  • POST /support/faq/:slug/not-helpful — Mark FAQ as not helpful
  • GET /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)

Global Search

  • GET /search?q=:query — Full-text search across players, organizations, scouting targets, opponent teams and FAQs

Notifications

  • GET /notifications — List user notifications
  • GET /notifications/:id — Get notification
  • PATCH /notifications/:id/mark-as-read — Mark as read
  • PATCH /notifications/mark-all-as-read — Mark all as read
  • GET /notifications/unread-count — Get unread count
  • DELETE /notifications/:id — Delete notification

Health & Observability

GET /health/live              — Liveness probe: is Puma alive? Never checks deps.
                                Always returns 200 while the process responds.
                                Use for container restart policies (Coolify/K8s).

GET /health/ready             — Readiness probe: checks PostgreSQL + Redis + Meilisearch.
                                Returns 200 (ok/disabled) or 503 (any dep unreachable).
                                Use for load balancer traffic routing.

GET /api/v1/monitoring/sidekiq  — Admin only. Full Sidekiq snapshot:
                                  queue depths, worker count, dead queue, retry queue,
                                  scheduled job heartbeats (stale detection), alert flags.
                                  Returns 503 if Redis unavailable.

Monitoring endpoint response includes:

  • scheduled_jobs — last run timestamp + stale: true/false per cron job
  • alerts.stale_jobs — true if any scheduled job exceeded its alert window
  • alerts.no_workers — true if no Sidekiq workers running
  • alerts.dead_queue_exceeded — true if dead queue > 10 jobs
  • alerts.queue_depth_exceeded — true if total queue depth > 100 jobs

Team Members (chat)

  • GET /team-members — List organization members (staff only — rejects player tokens)

Messages (DM)

  • GET /messages — List direct message history with a member
  • DELETE /messages/:id — Soft-delete a message

For complete endpoint documentation with request/response examples, visit /api-docs


07 · Testing

Unit & Request Tests

# Full test suite
bundle exec rspec

# 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/integration

Integration Tests (Swagger Documentation)

Integration tests serve dual purpose:

  1. Test API endpoints with real HTTP requests
  2. Generate Swagger documentation automatically
# Run integration tests and generate Swagger docs
RSWAG_GENERATE=1 bundle exec rake rswag:specs:swaggerize

# Run specific integration spec
bundle exec rspec spec/integration/players_spec.rb

Current coverage:

╔══════════════════════════╦════════════════════╗
║  MODULE                  ║  ENDPOINTS         ║
╠══════════════════════════╬════════════════════╣
║  Authentication          ║  8                 ║
║  Players                 ║  9                 ║
║  Matches                 ║  11                ║
║  Scouting                ║  10                ║
║  Schedules               ║  8                 ║
║  Team Goals              ║  8                 ║
║  VOD Reviews             ║  11                ║
║  Analytics               ║  7                 ║
║  Riot Data               ║  14                ║
║  Riot Integration        ║  1                 ║
║  Dashboard               ║  4                 ║
║  Competitive             ║  14                ║
║  Scrims                  ║  14                ║
║  Strategy                ║  16                ║
║  Support                 ║  16                ║
║  Admin                   ║  9                 ║
║  Notifications           ║  6                 ║
║  Profile                 ║  4                 ║
║  Rosters                 ║  4                 ║
║  Team Members            ║  1                 ║
║  Messages                ║  2                 ║
║  Constants               ║  1                 ║
║  Fantasy                 ║  2                 ║
╠══════════════════════════╬════════════════════╣
║  TOTAL                   ║  200+ endpoints    ║
╚══════════════════════════╩════════════════════╝

Code Coverage

open coverage/index.html

08 · Performance & Load Testing

Load Testing (k6)

# 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 local
╔═══════════════════════════════════════╗
║  PERFORMANCE BENCHMARKS               ║
╠══════════════════╦════════════════════╣
║  p(95) Docker    ║  ~880ms            ║
║  p(95) Prod est. ║  ~500ms            ║
║  With cache      ║  ~50ms             ║
║  Error rate      ║  0%                ║
╚══════════════════╩════════════════════╝

See TESTING_GUIDE.md and QUICK_START.md


09 · Security Testing (OWASP)

# 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 scan
[✓] OWASP Top 10
[✓] Code security (Brakeman)
[✓] Dependency vulnerabilities
[✓] Runtime security (ZAP)
[✓] CI/CD integration

See security_tests/README.md


10 · Observability & Monitoring

Health Probes

Endpoint Purpose Returns
GET /health/live Liveness — is Puma responding? Always 200
GET /health/ready Readiness — all deps reachable? 200 / 503
GET /up Legacy backward-compatible alias 200

Rule: never point the liveness probe at an endpoint that checks Redis or DB. A Redis crash → liveness fail → container restart → reconnect storm → worse incident.

Sidekiq Monitoring

# Requires admin Bearer token
curl -H "Authorization: Bearer $TOKEN" https://api.prostaff.gg/api/v1/monitoring/sidekiq

Response shape:

{
  "status": "ok | degraded | critical",
  "processes": { "count": 1, "workers": [...] },
  "queues": { "default": 0, "high": 0 },
  "stats": { "enqueued": 0, "dead": 0, "retry": 0 },
  "scheduled_jobs": {
    "RefreshMetadataViewsJob": { "last_run_at": "...", "stale": false },
    "CleanupExpiredTokensJob":  { "last_run_at": "...", "stale": false }
  },
  "alerts": {
    "no_workers": false,
    "queue_depth_exceeded": false,
    "dead_queue_exceeded": false,
    "stale_jobs": false
  }
}

Status rules:

status condition
ok all thresholds within bounds
degraded queue > 100, dead > 10, or any scheduled job stale
critical no Sidekiq workers running

401 Rate Spike Detection

Middleware::AuthFailureTracker counts 401s vs total requests using Redis sliding-window counters (5-minute window). Emits a structured log alert when the ratio exceeds 5%:

{
  "event": "auth_spike_detected",
  "level": "CRITICAL",
  "rate_pct": 8.3,
  "threshold_pct": 5.0,
  "total_requests": 240,
  "total_401s": 20
}

Threshold and window are configurable via env:

AUTH_TRACKER_THRESHOLD=0.05   # default: 5%
AUTH_TRACKER_WINDOW=5         # default: 5 minutes

Configurable Alert Thresholds

SIDEKIQ_QUEUE_ALERT_THRESHOLD=100   # queue depth that triggers degraded
SIDEKIQ_DEAD_ALERT_THRESHOLD=10     # dead queue size that triggers degraded

11 · Deployment

Environment Variables

# Core
DATABASE_URL=postgresql://user:password@host:5432/database
REDIS_URL=redis://host:6379/0
SECRET_KEY_BASE=your-rails-secret

# Authentication
JWT_SECRET_KEY=your-production-secret

# External APIs
RIOT_API_KEY=your-riot-api-key
PANDASCORE_API_KEY=your-pandascore-api-key

# Frontend
CORS_ORIGINS=https://your-frontend-domain.com
FRONTEND_URL=https://your-frontend-domain.com

# HashID Configuration (for URL obfuscation)
HASHID_SALT=your-secret-salt
HASHID_MIN_LENGTH=6

# Observability thresholds (optional, defaults shown)
SIDEKIQ_QUEUE_ALERT_THRESHOLD=100   # queue depth → degraded
SIDEKIQ_DEAD_ALERT_THRESHOLD=10     # dead queue   → degraded
AUTH_TRACKER_THRESHOLD=0.05         # 401 rate spike threshold (5%)
AUTH_TRACKER_WINDOW=5               # sliding window in minutes

Docker

docker build -t prostaff-api .
docker run -p 3333:3000 prostaff-api

12 · CI/CD

Architecture Diagram Auto-Update

┌────────────────────────────────────────────────────────────────┐
│  TRIGGER — changes in:                                         │
│    · app/modules/**    · app/models/**                         │
│    · app/controllers/**  · config/routes.rb  · Gemfile         │
├────────────────────────────────────────────────────────────────┤
│  PROCESS                                                       │
│    1. GitHub Actions detects relevant code changes             │
│    2. Runs scripts/update_architecture_diagram.rb              │
│    3. Script analyzes project structure                        │
│    4. Generates updated Mermaid diagram                        │
│    5. Updates README.md with new diagram                       │
│    6. Commits changes back to the repository                   │
└────────────────────────────────────────────────────────────────┘

Manual update:

ruby scripts/update_architecture_diagram.rb

CI/CD Workflows

Automated testing on every push:

  • Security Scan: Brakeman + dependency check
  • Load Test: Nightly smoke tests
  • Nightly Audit: Complete security scan
  • CORS Smoke Test: Runs after every production deploy — sends a preflight request from each allowed origin and fails the pipeline if CORS is misconfigured

See .github/workflows/ for details.


13 · Contributing

  1. Create a feature branch
  2. Make your changes
  3. Add tests
  4. Run security scan: ./security_tests/scripts/brakeman-scan.sh
  5. Ensure all tests pass
  6. Submit a pull request

The architecture diagram will be automatically updated when you add new modules, models, or controllers.


14 · License

╔══════════════════════════════════════════════════════════════════════════════╗
║  © 2026 ProStaff.gg. All rights reserved.                                    ║
║                                                                              ║
║  This repository contains the official ProStaff.gg API source code.          ║
║  Released under:                                                             ║
║                                                                              ║
║  Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International     ║
╚══════════════════════════════════════════════════════════════════════════════╝

CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

CC BY-NC-SA 4.0


Disclaimer

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.


▓▒░ · © 2026 PROSTAFF.GG · ░▒▓

Sponsor this project

 

Packages

 
 
 

Contributors 5