Files
honey-be/APPLICATION_OVERVIEW_old.md
Tihon 15498c8337
All checks were successful
Deploy to VPS / deploy (push) Successful in 52s
Initial setup, cleanup, VPS setup
2026-03-07 23:11:31 +02:00

44 KiB
Raw Permalink Blame History

Lottery Application - Complete Overview

Table of Contents

  1. Application Overview
  2. Architecture
  3. Core Features
  4. Game Mechanics
  5. Referral System
  6. Tasks System
  7. Payment System
  8. User Management
  9. Feature Switches
  10. Lottery Bot System
  11. Database Schema
  12. API Endpoints

Application Overview

The Lottery Application is a Telegram Mini App that provides a real-time lottery game experience. Users can participate in lottery rounds across multiple game rooms, complete tasks to earn rewards, refer friends to earn commissions, and manage their balance through Telegram Stars payments.

Technology Stack:

  • Backend: Java 17, Spring Boot 3.2.0, MySQL, WebSocket (STOMP)
  • Frontend: React, Vite, WebSocket client
  • Authentication: Telegram Mini App initData validation, JWT for admin panel
  • Payment: Crypto deposits (external API), optional Telegram Stars (legacy); feature switch for deposits
  • Payout: Crypto withdrawals (external API), STARS/GIFT (Telegram); feature switch for withdrawals
  • Infrastructure: Docker, Nginx, VPS deployment

Domain: win-spin.live


Architecture

Backend Architecture

  • Spring Boot REST API with WebSocket support for real-time game updates
  • Dual Authentication System:
    • Telegram initData validation for app users (via AuthInterceptor)
    • JWT-based authentication for admin panel (via Spring Security)
  • Session Management: Bearer token-based sessions stored in sessions table
  • Real-time Communication: WebSocket (STOMP) for game state broadcasts

Frontend Architecture

  • Main App (lottery-fe): React SPA (Vite) deployed at win-spin.live. Path / shows a home/landing screen; /auth (or other paths) loads the authenticated app. Screens: Main (game), Game History, FAQ, Support, Support Chat, Referral, Transaction History, Store, Payment Options/Confirmation/Error, Tasks, Payout, Stars Payout Confirmation, Daily Bonus. Balance and user state from GET /api/users/current; game join and room state via WebSocket. i18n and Telegram WebApp integration.
  • Admin Panel (lottery-admin): React SPA (Vite, React Router, TanStack Query) at win-spin.live/{secret-path}/. Routes: Login, Dashboard (stats), Rooms (list + RoomDetail), Feature Switchers, Configurations, Bots, Users (list + UserDetail), Payments, Payouts, Support Tickets (list + TicketDetail, Quick Answers), Masters, Analytics (User, Game, Financial, Referral). Role-based visibility: ROLE_ADMIN (all), ROLE_PAYOUT_SUPPORT (payouts), ROLE_TICKETS_SUPPORT (tickets + quick answers).
  • WebSocket Client (lottery-fe): Real-time game state via STOMP; subscribe to /topic/room/{roomNumber}/state, send join via /app/game/join.

Database

  • MySQL with Flyway migrations
  • Normalized Schema: User data split across multiple tables (A, B, D)
  • Performance: Indexed for high concurrency (1000+ concurrent users)

Core Features

1. Real-Time Lottery Game

  • 3 Game Rooms with different bet limits:
    • Room 1: 1-50 tickets
    • Room 2: 10-500 tickets
    • Room 3: 100-5000 tickets
  • Game Phases:
    • WAITING: Waiting for at least 2 players
    • COUNTDOWN: 5-second countdown after 2nd player joins
    • SPINNING: 5-second spinning animation
    • RESOLUTION: Winner announcement
  • Winner Selection: Random selection based on ticket distribution (weighted lottery)
  • House Commission: 20% of total pool (80% distributed to winner)

2. User Balance System

  • Balance A: Main balance (used for betting, can be withdrawn)
  • Balance B: Secondary balance (bonuses, rewards)
  • Currency: Internal "tickets" system (1 ticket = 1,000,000 in bigint format)
  • Deposit Conversion: 1 USD = 1,000 tickets (crypto deposits); legacy Telegram Stars conversion no longer used for new deposits
  • Withdrawal Limit: Only winnings since last deposit can be withdrawn; tracked in total_win_after_deposit (reset on deposit, reduced when payout created)

3. Telegram Integration

  • Telegram Mini App: Full integration with Telegram WebView
  • Telegram Stars Payments: Deposit via Telegram Stars
  • Telegram Bot: Handles webhooks, channel membership verification
  • Avatar Management: Downloads and stores user avatars from Telegram

4. Multi-Language Support

  • i18n: Full internationalization support
  • Languages: Multiple language codes stored per user
  • Localization Service: Dynamic message translation

5. Support System

  • Support Tickets: Users can create tickets
  • Support Messages: Threaded conversations per ticket
  • Status Tracking: OPENED/CLOSED status

6. Admin Panel

  • Secret Path Access: Accessible via win-spin.live/{secret-path}/
  • Role-Based Access: ROLE_ADMIN (full access), ROLE_PAYOUT_SUPPORT (payouts only), ROLE_TICKETS_SUPPORT (support tickets and quick answers). Admins table stores role per account.
  • Dashboard: Stats overview (total/new users, active players 24h/7d/30d, revenue and payouts in Stars and crypto USD, net revenue, rounds count, open support tickets). Served by GET /api/admin/dashboard/stats.
  • Rooms: List all game rooms; room detail by room number (participants, phase, totals); repair round for stuck rooms (POST /api/admin/rooms/{roomNumber}/repair).
  • Configurations: App configuration view for admins (GET /api/admin/configurations).
  • Bots: Lottery bot configs management—create/update/delete bot configs (linked to real users), shuffle bot order. Scheduler (when lottery_bot_scheduler_enabled is on) auto-joins bots into joinable rounds per time window and persona.
  • User Management: Paginated users list; user detail (profile, balance, transactions, game rounds, tasks); ban user; manual balance adjustment.
  • Feature Switchers: Runtime toggles for remote_bet_enabled, payment_enabled, payout_enabled, lottery_bot_scheduler_enabled.
  • Payments: List payments with filters (userId, status); crypto and legacy records.
  • Payouts: List payouts with filters (userId, status, type); manual complete/cancel for PROCESSING or WAITING (CRYPTO status synced by cron).
  • Support Tickets: List tickets, ticket detail with messages; close ticket. Quick Answers: Per-admin templates for fast replies (CRUD); access for ROLE_ADMIN and ROLE_TICKETS_SUPPORT.
  • Masters: Referral masters view.
  • Analytics: Revenue time series (crypto USD) and activity metrics (new users, rounds, revenue by period) for charts; range 7d/30d/90d/1y/all.
  • JWT Authentication: Separate admin authentication system.
  • Admin Table: Separate admins table; optional user_id linking to db_users_a for support messages.

Game Mechanics

Game Flow

  1. User Joins Room:

    • User selects a room (1, 2, or 3)
    • User places a bet (within room limits)
    • Balance A is deducted immediately
    • User becomes a participant
  2. Round Start:

    • When 2nd player joins, countdown starts (5 seconds)
    • During countdown, more players can join
    • After countdown, spinning phase begins (5 seconds)
  3. Winner Selection:

    • Winner selected randomly based on ticket distribution
    • Probability = (user_tickets / total_tickets)
    • House takes 20% commission
    • Winner receives 80% of total pool
  4. Round Resolution:

    • Winner's balance credited
    • Referral commissions processed
    • Round marked as completed
    • New round starts automatically

Bet Limits Per Room

Room Min Bet Max Bet Max Bet Per User
1 1 50 50
2 10 500 500
3 100 5000 5000

Note: All amounts stored in bigint format (1 ticket = 1,000,000)

Game Phases

  • WAITING: Room waiting for players (minimum 2 required)
  • COUNTDOWN: 5-second countdown after 2nd player joins
  • SPINNING: 5-second spinning animation (no new bets allowed)
  • RESOLUTION: Winner announced, payouts processed

Real-Time Updates

  • WebSocket Broadcasts: All room state changes broadcast to connected clients
  • State Synchronization: Clients receive full room state on connection
  • Participant Updates: Real-time participant list and bet totals

Referral System

3-Tier Referral Structure

The referral system tracks up to 5 levels of referrers, but commissions are paid to the first 3 levels:

Referral Chain:

  • referer_id_1: Direct referrer (Level 1)
  • referer_id_2: Referrer's referrer (Level 2)
  • referer_id_3: Referrer's referrer's referrer (Level 3)
  • referer_id_4: Level 4 (tracked but no commission)
  • referer_id_5: Level 5 (tracked but no commission)

Commission Rates

When Referral Wins:

  • All Levels: 1% of referral's net profit
  • Net Profit Calculation: (total_pool - house_commission) - referral_bet

When Referral Loses:

  • Level 1: 4% of referral's bet
  • Level 2: 2% of referral's bet
  • Level 3: 1% of referral's bet

Referral Statistics

Each user tracks:

  • referals_1 to referals_5: Count of direct referrals at each level
  • from_referals_1 to from_referals_5: Total commissions earned from each level
  • to_referer_1 to to_referer_5: Total commissions paid to referrers

Third Bet Bonus

  • Special bonus given to referrers when their referral makes their 3rd bet
  • Uses rounds_played column (not transaction count)
  • Prevents issues with transaction cleanup cron jobs

Tasks System

Task Types

  1. Referral Tasks (referral):

    • Invite 1, 3, 7, 15, 30, 50, 100 friends
    • Rewards: 2, 5, 15, 25, 40, 60, 150 Stars respectively
    • One-time rewards (can only claim each tier once)
  2. Follow Task (follow):

    • Follow the news channel
    • Reward: 5 Stars
    • Verified via Telegram Bot API
  3. Deposit Task (other):

    • Top up balance: $5
    • Reward: 100 Stars
    • Based on deposit_total field
  4. Daily Bonus (daily):

    • Claim 1 free ticket every 24 hours
    • Reward: 1 ticket
    • Tracked in user_daily_bonus_claims table

Task Completion Logic

  • Referral Tasks: Counts referals_1 from db_users_d
  • Follow Task: Verified via Telegram Bot API channel membership check
  • Deposit Task: Checks deposit_total >= requirement
  • Daily Bonus: Checks if last claim was > 24 hours ago

Task Rewards

  • Rewards credited to Balance A (main balance)
  • Transaction recorded in transactions table with type TASK_BONUS
  • Task marked as claimed in user_task_claims table

Payment System

Crypto Deposits (Primary)

Deposits are handled via an external crypto API (e.g. spin-passim.tech). The backend syncs deposit methods periodically and provides deposit addresses on demand; balance is credited when the 3rd party sends a completion webhook.

Deposit Flow:

  1. User enters USD amount on Store screen (min 2, max 10,000 USD; max 2 decimal places).
  2. User selects a crypto method on Payment Options (methods from crypto_deposit_methods, synced every 10 min from external API).
  3. Backend calls external API POST api/v1/deposit-address (pid, amountUsd, userData); no payment record is created yet.
  4. User is shown wallet address and exact amount in coins to send (Payment Confirmation screen).
  5. When the 3rd party detects the deposit, it calls POST /api/deposit_webhook/{token} with user_id and usd_amount.
  6. Backend creates a COMPLETED payment record, credits balance (1 USD = 1,000 tickets in DB units: 1 ticket = 1,000,000), updates deposit_total/deposit_count, resets total_win_after_deposit, and creates a DEPOSIT transaction.

Payment Record (crypto):

  • usd_amount: decimal (e.g. 1.25 USD)
  • tickets_amount: bigint (1 USD = 1,000 tickets → 1,000,000,000 in DB)
  • stars_amount: 0 for crypto
  • status: PENDING (if invoice created but not used), COMPLETED, FAILED, CANCELLED

Feature Switch: When payment_enabled is off, deposit-related endpoints return 503 and the Store shows "deposits temporarily unavailable".

Telegram Stars (Legacy)

  • Creating new payments via Stars (invoice link) is no longer supported; the app uses crypto-only for new deposits.
  • Telegram payment webhook is still processed for backward compatibility if a legacy payment is completed.
  • Legacy conversion: Stars × 0.9 × 1,000,000 for tickets (no longer used for new flows).

Payout System

Payout Types:

  • CRYPTO: Primary. User selects withdrawal method (e.g. TON, LTC, TRX), enters wallet and amount in tickets. Backend calls external API POST api/v1/withdrawal; on success creates payout with payment_id, deducts balance, and a cron job syncs status from GET api/v1/withdrawals-info/{payment_id}.
  • STARS: Convert tickets to Telegram Stars (fixed amounts; admin may process manually).
  • GIFT: Convert to Telegram gifts (HEART, BEAR, etc.); admin may process manually.

Crypto Payout Flow:

  1. User opens Payout screen; backend returns withdrawal methods from crypto_withdrawal_methods (synced every 30 min from external API).
  2. User selects method, enters wallet and amount (tickets). Frontend may call GET withdrawal-method-details?pid= for rate_usd and fee to show "You will receive".
  3. User submits; backend acquires per-user lock, calls external API POST withdrawal, then creates payout (type CRYPTO) with payment_id, crypto_name, amount_coins, commission_coins, amount_to_send, wallet, status PROCESSING, and deducts balance.
  4. Cron job (every minute) fetches PROCESSING/WAITING CRYPTO payouts with payment_id, calls withdrawals-info API, and updates status: -1→PROCESSING, 0→WAITING, 1→COMPLETED (marks completed, updates withdraw_total/count), 2→CANCELLED (refunds balance, creates cancellation transaction).

Payout Statuses:

  • PROCESSING: Created or being processed by external provider
  • WAITING: Awaiting confirmation (from API status 0)
  • COMPLETED: Resolved; user withdraw_total/count updated
  • CANCELLED: Refunded to balance_a

Withdrawal Rules:

  • At least one deposit required before any withdrawal.
  • Withdrawal amount cannot exceed total_win_after_deposit (winnings since last deposit).
  • Crypto withdrawal amount must have at most 2 decimal places (in ticket units).
  • One withdrawal at a time per user (in-memory lock).

Feature Switch: When payout_enabled is off, withdrawal-related endpoints return 503 and the Payout screen shows "withdrawals temporarily unavailable".


User Management

User Data Structure

User data is split across 3 tables for normalization:

db_users_a (User Authentication & Profile):

  • Basic user info (Telegram ID, name, language, country)
  • Registration and login timestamps
  • Ban status
  • Avatar URL

db_users_b (User Balance & Financial):

  • Balance A (main balance)
  • Balance B (bonus balance)
  • Deposit/withdraw totals and counts
  • Rounds played counter
  • total_win_after_deposit: Total winnings since last deposit (bigint). Reset to 0 on each deposit; incremented when user wins a round; reduced when user creates a payout. Used to enforce withdrawal limit (only this amount can be withdrawn).

db_users_d (User Referral Data):

  • Referral chain (5 levels)
  • Referral statistics
  • Commission tracking

User Sessions

  • Session Management: Bearer token-based
  • Multi-Device Support: Up to 5 active sessions per user
  • Session Expiration: Configurable TTL
  • Automatic Cleanup: Cron job removes expired sessions

User Authentication

  • Telegram initData Validation: Validates Telegram Mini App authentication

  • Session Creation: Creates session token on first login

  • Session Validation: AuthInterceptor validates all API requests

  • Current User API: Returns paymentEnabled and payoutEnabled from feature switches (used by frontend to show/hide or disable Store and Payout).


Feature Switches

Runtime toggles stored in feature_switches table. Changes take effect immediately without restart. Configurable from the admin panel.

Key Description
remote_bet_enabled When on, 3rd party can register users to rounds via GET /api/remotebet/{token}?user_id=&room=&amount=. When off, endpoint returns 503.
payment_enabled When on, deposits (Store, Payment Options, deposit-address, create invoice) are allowed. When off, related API endpoints return 503 and Store shows "deposits temporarily unavailable". Default: 1.
payout_enabled When on, withdrawals (Payout screen, withdrawal-methods, withdrawal-method-details, crypto-withdrawal) are allowed. When off, related endpoints return 503 and Payout shows "withdrawals temporarily unavailable". Default: 1.
lottery_bot_scheduler_enabled When on, the lottery bot scheduler auto-joins configured bots (from lottery_bot_configs) into joinable rounds within their time windows and persona. When off, scheduler skips registration. Default: 1.

Lottery Bot System

Bots are real users (from db_users_a/db_users_b) with a config row in lottery_bot_configs. The scheduler runs periodically and, when lottery_bot_scheduler_enabled is on, registers these users into active rounds via the same join flow as real players (balance deducted, etc.).

Bot Config (per user)

  • Rooms: Flags room_1, room_2, room_3 (which rooms the bot can play).
  • Time window (UTC): time_utc_start, time_utc_end—bot only plays within this window.
  • Bet range: bet_min, bet_max in bigint (1 ticket = 1,000,000).
  • Persona: conservative, aggressive, or balanced—used by the bet decision service to choose bet size and timing.
  • Active: Toggle to enable/disable this bot without deleting the config.

One config per user; user_id is unique. Admin can create/update/delete configs and shuffle bot order via the Bots page.

Scheduler

  • When the feature switch is on, a scheduled job evaluates active configs, checks time windows and room state, and places bets for bots using the bet decision service (persona-based logic).
  • Bots participate in the same game flow as human players (rounds, referral logic, etc.).

Database Schema

Core Tables

sessions

User session management for Bearer token authentication.

Column Type Description
id BIGINT Primary key, auto-increment
session_id_hash VARCHAR(255) Hashed session ID (unique)
user_id INT Foreign key to db_users_a.id
created_at TIMESTAMP Session creation time
expires_at TIMESTAMP Session expiration time

Indexes:

  • idx_session_hash on session_id_hash
  • idx_expires_at on expires_at
  • idx_user_id on user_id
  • idx_user_created on (user_id, created_at)

db_users_a

User authentication and profile information.

Column Type Description
id INT Primary key, auto-increment
screen_name VARCHAR(75) User's screen name
telegram_id BIGINT Telegram user ID (unique)
telegram_name VARCHAR(33) Telegram username
is_premium INT Telegram Premium status (0/1)
language_code VARCHAR(2) User's language code
country_code VARCHAR(2) User's country code
device_code VARCHAR(5) Device type code
ip VARBINARY(16) User's IP address (IPv4/IPv6)
date_reg INT Registration timestamp (Unix)
date_login INT Last login timestamp (Unix)
banned INT Ban status (0/1)
avatar_url VARCHAR(500) Avatar URL with cache busting
last_telegram_file_id VARCHAR(255) Telegram file ID for avatar

Indexes:

  • Primary key on id
  • Unique key on telegram_id
  • Index on telegram_name
  • Index on ip

db_users_b

User balance and financial information.

Column Type Description
id INT Primary key (matches db_users_a.id)
balance_a BIGINT UNSIGNED Main balance (tickets in bigint format)
balance_b BIGINT UNSIGNED Bonus balance (tickets in bigint format)
deposit_total BIGINT Total deposits (in bigint format)
deposit_count INT Number of deposits
withdraw_total BIGINT Total withdrawals (in bigint format)
withdraw_count INT Number of withdrawals
rounds_played INT Number of rounds user participated in
total_win_after_deposit BIGINT Winnings since last deposit (1 ticket = 1,000,000). Reset on deposit; increased on win; decreased when payout created. Withdrawal limit.

Indexes:

  • Primary key on id

Note: balance_a and balance_b store values in bigint format where 1 ticket = 1,000,000

db_users_d

User referral data and statistics.

Column Type Description
id INT Primary key (matches db_users_a.id)
referer_id_1 INT Level 1 referrer ID
referer_id_2 INT Level 2 referrer ID
referer_id_3 INT Level 3 referrer ID
referer_id_4 INT Level 4 referrer ID
referer_id_5 INT Level 5 referrer ID
master_id INT Master referrer ID
referals_1 INT Count of level 1 referrals
referals_2 INT Count of level 2 referrals
referals_3 INT Count of level 3 referrals
referals_4 INT Count of level 4 referrals
referals_5 INT Count of level 5 referrals
from_referals_1 BIGINT Commissions earned from level 1
from_referals_2 BIGINT Commissions earned from level 2
from_referals_3 BIGINT Commissions earned from level 3
from_referals_4 BIGINT Commissions earned from level 4
from_referals_5 BIGINT Commissions earned from level 5
to_referer_1 BIGINT Commissions paid to level 1 referrer
to_referer_2 BIGINT Commissions paid to level 2 referrer
to_referer_3 BIGINT Commissions paid to level 3 referrer
to_referer_4 BIGINT Commissions paid to level 4 referrer
to_referer_5 BIGINT Commissions paid to level 5 referrer

Indexes:

  • Primary key on id
  • Indexes on referer_id_1 through referer_id_5
  • Index on master_id

Game Tables

game_rooms

Active game rooms (Room 1, 2, 3).

Column Type Description
id INT Primary key, auto-increment
room_number INT Room number (1, 2, or 3), unique
current_phase VARCHAR(20) Current game phase (WAITING, COUNTDOWN, SPINNING, RESOLUTION)
countdown_end_at TIMESTAMP Countdown end time (NULL if not counting down)
total_bet BIGINT UNSIGNED Total tickets bet in current round
registered_players INT Number of players in current round
created_at TIMESTAMP Room creation time
updated_at TIMESTAMP Last update time

Indexes:

  • Primary key on id
  • Unique key on room_number
  • Index on current_phase
  • Index on countdown_end_at

game_rounds

Completed game rounds history.

Column Type Description
id BIGINT Primary key, auto-increment
room_id INT Foreign key to game_rooms.id
phase VARCHAR(20) Final phase (usually RESOLUTION)
total_bet BIGINT UNSIGNED Total tickets/bet in the round
winner_user_id INT Winner's user ID (NULL if no winner)
winner_bet BIGINT UNSIGNED Winner's ticket/bet count
commission BIGINT UNSIGNED House commission (20% of total)
payout BIGINT UNSIGNED Winner's payout (80% of total)
started_at TIMESTAMP Round start time
countdown_started_at TIMESTAMP Countdown start time
countdown_ended_at TIMESTAMP Countdown end time
resolved_at TIMESTAMP Resolution time
created_at TIMESTAMP Record creation time

Indexes:

  • Primary key on id
  • Index on room_id
  • Index on winner_user_id
  • Index on resolved_at
  • Foreign key to game_rooms(id)

game_round_participants

Participants in each game round.

Column Type Description
id BIGINT Primary key, auto-increment
round_id BIGINT Foreign key to game_rounds.id
user_id INT Foreign key to db_users_a.id
tickets BIGINT UNSIGNED User's total tickets in this round
joined_at TIMESTAMP When user joined the round

Indexes:

  • Primary key on id
  • Index on round_id
  • Index on user_id
  • Composite index on (round_id, user_id)
  • Foreign keys to game_rounds(id) and db_users_a(id)

Task Tables

tasks

Available tasks for users to complete.

Column Type Description
id INT Primary key, auto-increment
type VARCHAR(20) Task type: referral, follow, other, daily
requirement INT Requirement value (e.g., number of referrals, deposit amount)
reward_amount BIGINT Reward amount in bigint format
reward_type VARCHAR(20) Reward type: Stars, Tickets, Power
display_order INT Display order in UI
title VARCHAR(255) Task title
description TEXT Task description

Indexes:

  • Primary key on id
  • Index on type
  • Index on display_order

Default Tasks:

  • Referral: Invite 1, 3, 7, 15, 30, 50, 100 friends (rewards: 2, 5, 15, 25, 40, 60, 150 Stars)
  • Follow: Follow news channel (reward: 5 Stars)
  • Deposit: Top up $5 (reward: 100 Stars)
  • Daily: Daily bonus (reward: 1 ticket, claimable every 24h)

user_task_claims

Tracks which tasks users have claimed.

Column Type Description
id BIGINT Primary key, auto-increment
user_id INT Foreign key to db_users_a.id
task_id INT Foreign key to tasks.id
claimed_at TIMESTAMP When task was claimed

Indexes:

  • Primary key on id
  • Unique composite index on (user_id, task_id)
  • Index on user_id
  • Index on task_id
  • Foreign keys to db_users_a(id) and tasks(id)

user_daily_bonus_claims

Tracks daily bonus claims (optimized table to avoid JOINs).

Column Type Description
id BIGINT Primary key, auto-increment
user_id INT Foreign key to db_users_a.id
avatar_url VARCHAR(255) User's avatar URL (denormalized)
screen_name VARCHAR(75) User's screen name (denormalized)
claimed_at TIMESTAMP Claim time

Indexes:

  • Primary key on id
  • Index on user_id
  • Index on claimed_at (DESC)
  • Foreign key to db_users_a(id)

Feature Switches Table

feature_switches

Runtime feature toggles (e.g. remote bet, deposits, withdrawals). Admin can change without restart.

Column Type Description
key VARCHAR(64) Primary key (e.g. remote_bet_enabled, payment_enabled, payout_enabled)
enabled TINYINT(1) 0 or 1
updated_at TIMESTAMP Last update

Crypto Deposit Tables

crypto_deposit_config

Single row (id=1): minimum_deposit (decimal), methods_hash for sync skip when unchanged.

Column Type Description
id INT Primary key (1)
methods_hash VARCHAR(255) Hash from external API; skip sync when unchanged
minimum_deposit DECIMAL(10,2) Minimum USD (e.g. 2.50)
updated_at TIMESTAMP Last update

crypto_deposit_methods

One row per active deposit method (synced from external API every 10 min). pid = icon filename without extension (e.g. 235.png).

Column Type Description
id BIGINT Primary key
pid INT External API PID (unique)
name VARCHAR(100) e.g. TON, USDT
network VARCHAR(50) e.g. TON, TRC20
example VARCHAR(255) Example address
min_deposit_sum DECIMAL(10,2) Min USD for this method
updated_at TIMESTAMP Last update

Crypto Withdrawal Tables

crypto_withdrawal_methods

One row per active withdrawal method (synced from external API every 30 min). pid = method id; icon_id = icon filename (e.g. 30.png).

Column Type Description
id BIGINT Primary key
pid INT Method ID (unique)
name VARCHAR(50) Ticker (e.g. LTC, TON)
network VARCHAR(100) Network name
icon_id VARCHAR(20) Icon filename without extension
min_withdrawal DECIMAL(10,2) Min withdrawal USD
updated_at TIMESTAMP Last update

Payment Tables

payments

Payment records (crypto and legacy Telegram Stars).

Column Type Description
id BIGINT Primary key, auto-increment
user_id INT Foreign key to db_users_a.id
order_id VARCHAR(255) Unique order ID
stars_amount INT Telegram Stars (0 for crypto)
usd_amount DECIMAL(20,2) USD amount (crypto; e.g. 1.25)
tickets_amount BIGINT UNSIGNED Tickets in bigint (1 USD = 1,000 tickets → 1,000,000,000 per USD)
status VARCHAR(20) PENDING, COMPLETED, FAILED, CANCELLED
telegram_payment_charge_id VARCHAR(255) Telegram (legacy)
telegram_provider_payment_charge_id VARCHAR(255) Telegram (legacy)
created_at TIMESTAMP Creation time
completed_at TIMESTAMP Completion time

Indexes:

  • Primary key on id
  • Unique key on order_id
  • Index on user_id
  • Index on status
  • Index on created_at
  • Composite index on (user_id, status)
  • Foreign key to db_users_a(id)

payouts

Withdrawal/payout requests (CRYPTO, STARS, GIFT).

Column Type Description
id BIGINT Primary key, auto-increment
user_id INT Foreign key to db_users_a.id
username VARCHAR(255) User's username (for STARS/GIFT)
wallet VARCHAR(120) Wallet address (CRYPTO)
type VARCHAR(20) CRYPTO, STARS, GIFT
gift_name VARCHAR(50) Gift type for GIFT (HEART, BEAR, etc.)
crypto_name VARCHAR(20) Ticker for CRYPTO (e.g. TRX, TON)
total BIGINT UNSIGNED Tickets in bigint format
stars_amount INT Stars amount (0 for CRYPTO)
usd_amount DECIMAL(20,2) USD equivalent (CRYPTO)
amount_coins VARCHAR(50) Withdrawal amount in coins (from API)
commission_coins VARCHAR(50) Commission in coins (from API)
amount_to_send VARCHAR(50) Final amount to send (from API)
payment_id INT Crypto API payment id (for status sync)
quantity INT Quantity (e.g. gifts); default 1
status VARCHAR(20) PROCESSING, WAITING, COMPLETED, CANCELLED
created_at TIMESTAMP Request time
updated_at TIMESTAMP Last update (touched by cron sync)
resolved_at TIMESTAMP Resolution time

Indexes:

  • Primary key on id
  • Index on user_id
  • Index on status
  • Index on type
  • Index on created_at
  • Index on updated_at
  • Composite indexes for CRYPTO status sync
  • Foreign key to db_users_a(id)

transactions

Transaction history (all balance changes).

Column Type Description
id BIGINT Primary key, auto-increment
user_id INT Foreign key to db_users_a.id
amount BIGINT Amount in bigint format (positive=credit, negative=debit)
type VARCHAR(50) Type: DEPOSIT, WITHDRAWAL, WIN, LOSS, TASK_BONUS, CANCELLATION_OF_WITHDRAWAL
task_id INT Task ID for TASK_BONUS type (nullable)
round_id BIGINT Round ID for WIN/LOSS type (nullable)
created_at TIMESTAMP Transaction time

Indexes:

  • Primary key on id
  • Composite index on (user_id, created_at DESC)
  • Composite index on (user_id, type)
  • Foreign key to db_users_a(id)

Note: Transactions older than 30 days are automatically cleaned up by cron job.

Support Tables

support_tickets

User support tickets.

Column Type Description
id BIGINT Primary key, auto-increment
user_id INT Foreign key to db_users_a.id
subject VARCHAR(100) Ticket subject
status ENUM Status: OPENED, CLOSED
created_at TIMESTAMP Ticket creation time
updated_at TIMESTAMP Last update time

Indexes:

  • Primary key on id
  • Index on user_id
  • Index on status
  • Composite index on (user_id, status)
  • Index on created_at
  • Foreign key to db_users_a(id)

support_messages

Messages within support tickets.

Column Type Description
id BIGINT Primary key, auto-increment
ticket_id BIGINT Foreign key to support_tickets.id
user_id INT Foreign key to db_users_a.id
message VARCHAR(2000) Message content
created_at TIMESTAMP Message time

Indexes:

  • Primary key on id
  • Index on ticket_id
  • Index on user_id
  • Composite index on (ticket_id, created_at)
  • Foreign keys to support_tickets(id) and db_users_a(id)

Admin Tables

admins

Admin user accounts (separate from regular users).

Column Type Description
id INT Primary key, auto-increment
user_id INT Optional FK to db_users_a.id (for support messages)
username VARCHAR(50) Admin username (unique)
password_hash VARCHAR(255) BCrypt hashed password
role VARCHAR(20) Role: ROLE_ADMIN, ROLE_PAYOUT_SUPPORT, ROLE_TICKETS_SUPPORT
created_at TIMESTAMP Account creation time
updated_at TIMESTAMP Last update time

Indexes:

  • Primary key on id
  • Unique key on username
  • Index on role
  • Index on user_id

lottery_bot_configs

Bot behaviour config: one row per user; user must exist in db_users_a.

Column Type Description
id INT Primary key, auto-increment
user_id INT FK to db_users_a.id (unique)
room_1 TINYINT(1) Can play room 1 (0/1)
room_2 TINYINT(1) Can play room 2 (0/1)
room_3 TINYINT(1) Can play room 3 (0/1)
time_utc_start TIME Start of active window (UTC)
time_utc_end TIME End of active window (UTC)
bet_min BIGINT Min bet in bigint (1 ticket = 1,000,000)
bet_max BIGINT Max bet in bigint
persona VARCHAR(20) conservative, aggressive, balanced
active TINYINT(1) 1 = enabled, 0 = disabled
created_at TIMESTAMP Creation time
updated_at TIMESTAMP Last update time

Indexes:

  • Unique key on user_id
  • Index on (active, room_1, room_2, room_3)

quick_answers

Admin quick-response templates for support (per admin).

Column Type Description
id INT Primary key, auto-increment
admin_id INT FK to admins.id
text TEXT Template text
created_at TIMESTAMP Creation time
updated_at TIMESTAMP Last update time

Indexes:

  • Primary key on id
  • Index on admin_id
  • Index on (admin_id, created_at)

API Endpoints

Public Endpoints

  • POST /api/auth/tma/session - Create session from Telegram initData
  • GET /api/check_user/{token}/{telegramId} - Check user info (external API). Token is configured via APP_CHECK_USER_TOKEN (set on server only, not in repo).
  • POST /api/deposit_webhook/{token} - 3rd party deposit completion (no auth). Body: user_id, usd_amount. Token via APP_DEPOSIT_WEBHOOK_TOKEN.

Authenticated Endpoints (Bearer Token)

Game (REST)

  • GET /api/game/room/{roomNumber}/completed-rounds - Last 10 completed rounds for a room
  • GET /api/game/history - Get game history for current user
  • Join and room state: Via WebSocket (see WebSocket section below), not REST.

User

  • GET /api/users/current - Get current user info (includes balance, paymentEnabled, payoutEnabled from feature switches)
  • GET /api/users/referrals - Get referral info
  • POST /api/users/deposit - Legacy/optional deposit flow

Tasks

  • GET /api/tasks?type= - Get available tasks (query: type = referral, follow, other, etc.)
  • GET /api/tasks/daily-bonus - Daily bonus status
  • GET /api/tasks/daily-bonus/recent-claims - Recent daily bonus claims (optional query: timezone)
  • POST /api/tasks/claim - Claim task reward (body: taskId)

Payments (deposits)

  • GET /api/payments/minimum-deposit - Min deposit USD from config (503 if payment disabled)
  • GET /api/payments/deposit-methods - Crypto deposit methods from DB (503 if payment disabled)
  • POST /api/payments/deposit-address - Get crypto deposit address/amount from external API (pid, usdAmount)
  • POST /api/payments/create - Create payment invoice (crypto: usdAmount; legacy Stars no longer supported) (503 if payment disabled)
  • POST /api/payments/cancel - Cancel payment by orderId

Payouts (withdrawals)

  • GET /api/payments/withdrawal-methods - Crypto withdrawal methods from DB (503 if payout disabled)
  • GET /api/payments/withdrawal-method-details?pid= - Rate/fee for method from external API (503 if payout disabled)
  • POST /api/payments/crypto-withdrawal - Create crypto withdrawal (pid, wallet, total in tickets); creates payout and deducts balance (503 if payout disabled)
  • POST /api/payouts - Request STARS or GIFT payout
  • GET /api/payouts/history - Last 20 payouts for current user

Support

  • GET /api/support/tickets - Get user's tickets
  • POST /api/support/tickets - Create ticket
  • GET /api/support/tickets/{ticketId} - Get ticket with messages
  • POST /api/support/tickets/{ticketId}/messages - Send message
  • POST /api/support/tickets/{ticketId}/close - Close ticket

Transactions

  • GET /api/transactions - Get current user's transaction history

Admin Endpoints (JWT Token)

All admin paths are under /api/admin/. Role requirements: dashboard, rooms, configurations, bots, users, payments, payouts, feature-switches, analytics require ADMIN; payouts also allow ROLE_PAYOUT_SUPPORT; tickets and quick-answers allow ROLE_TICKETS_SUPPORT.

  • POST /api/admin/login - Admin login
  • GET /api/admin/dashboard/stats - Dashboard stats (users, active players, revenue/payouts in Stars and crypto USD, rounds, support tickets)
  • GET /api/admin/rooms - List all game rooms
  • GET /api/admin/rooms/{roomNumber} - Room detail (participants, phase, etc.)
  • POST /api/admin/rooms/{roomNumber}/repair - Repair stuck round
  • GET /api/admin/configurations - App configurations
  • GET /api/admin/bots - List lottery bot configs
  • GET /api/admin/bots/{id} - Get bot config by id
  • POST /api/admin/bots - Create bot config
  • PUT /api/admin/bots/{id} - Update bot config
  • DELETE /api/admin/bots/{id} - Delete bot config
  • POST /api/admin/bots/shuffle?roomNumber= - Shuffle bot time windows for room (query: roomNumber = 2 or 3)
  • GET /api/admin/users - Paginated users list (50 per page; sort supported)
  • GET /api/admin/users/{id} - User detail
  • GET /api/admin/users/{id}/transactions - User transactions
  • GET /api/admin/users/{id}/game-rounds - User game rounds
  • GET /api/admin/users/{id}/tasks - User task claims
  • PATCH /api/admin/users/{id}/ban - Ban/unban user (body: banned)
  • POST /api/admin/users/{id}/balance/adjust - Manual balance adjustment
  • GET /api/admin/feature-switches - List all feature switches
  • PATCH /api/admin/feature-switches/{key} - Update feature switch (body: enabled)
  • GET /api/admin/payments - Paginated payments (filter by userId, status)
  • GET /api/admin/payouts - Paginated payouts (filter by userId, status, type)
  • POST /api/admin/payouts/{id}/complete - Mark payout COMPLETED
  • POST /api/admin/payouts/{id}/cancel - Mark payout CANCELLED (refund)
  • GET /api/admin/analytics/revenue - Revenue/payout time series (query: range = 7d, 30d, 90d, 1y, all)
  • GET /api/admin/analytics/activity - Activity metrics for charts
  • GET /api/admin/quick-answers - List quick answers for current admin
  • POST /api/admin/quick-answers - Create quick answer (body: text)
  • PUT /api/admin/quick-answers/{id} - Update quick answer (own only)
  • DELETE /api/admin/quick-answers/{id} - Delete quick answer (own only)

WebSocket

  • Endpoint: /ws (STOMP over SockJS or WebSocket)
  • Subscribe: /topic/room/{roomNumber}/state - Room state updates (full state on subscribe; broadcasts on phase/participant changes)
  • Send (join round): /app/game/join - Payload: roomNumber, amount (tickets in bigint). Join is handled via WebSocket, not REST.

Key Business Logic

Balance Format

All monetary values in balance/transaction/payout totals are stored in bigint format with 6 decimal places:

  • 1 Ticket = 1,000,000 (in database)
  • Crypto deposits: 1 USD = 1,000 tickets → 1,000,000,000 in database per USD
  • Legacy: 1 Telegram Star = 900,000 (0.9 conversion; no longer used for new deposits)
  • Example: 50 tickets = 50,000,000 in database

Winner Selection Algorithm

  1. Calculate total tickets in round
  2. Generate random number between 0 and total_tickets
  3. Iterate through participants, accumulating ticket counts
  4. First participant whose accumulated tickets >= random number wins
  5. This creates a weighted lottery (more tickets = higher chance)

House Commission

  • Rate: 20% of total pool
  • Calculation: commission = total_tickets × 0.2
  • Winner Payout: payout = total_tickets - commission

Referral Commission Calculation

When Referral Wins:

net_profit = (total_pool - house_commission) - referral_bet
commission = net_profit × 0.01  // 1% for all levels

When Referral Loses:

Level 1: commission = referral_bet × 0.04  // 4%
Level 2: commission = referral_bet × 0.02  // 2%
Level 3: commission = referral_bet × 0.01  // 1%

Data Cleanup

  • Transactions: Cleaned up after 30 days (cron job)
  • Game Rounds: Old rounds cleaned up periodically
  • Sessions: Expired sessions cleaned up in batches

Crypto API Integration

  • Deposits: External API base URL and API key via app.crypto-api.base-url and app.crypto-api.api-key. Deposit methods synced every 10 min (cron); deposit address on demand (POST deposit-address). Completion via POST /api/deposit_webhook/{token} (token: app.deposit-webhook.token).
  • Withdrawals: Withdrawal methods synced every 30 min (cron). POST withdrawal creates payout; status sync cron every minute calls GET withdrawals-info for PROCESSING/WAITING CRYPTO payouts and updates status (COMPLETED/CANCELLED trigger balance and transaction updates).

Security Features

  1. Telegram Authentication: Validates Telegram Mini App initData
  2. Session Management: Secure Bearer token sessions
  3. Rate Limiting: Per-user and per-endpoint rate limiting
  4. CORS Protection: Configured for specific origins
  5. Admin Authentication: Separate JWT-based admin system
  6. Input Validation: All user inputs validated
  7. SQL Injection Protection: JPA/Hibernate parameterized queries
  8. XSS Protection: Content Security Policy headers

Performance Optimizations

  1. Database Indexes: Comprehensive indexing for fast queries
  2. Connection Pooling: HikariCP with optimized pool size
  3. WebSocket Keep-Alive: Efficient real-time communication
  4. Batch Operations: Bulk cleanup operations
  5. Caching: In-memory caching for active game rounds
  6. Nginx Caching: Static asset caching (1 year TTL)
  7. Composite Indexes: Optimized for common query patterns

Deployment

  • Backend: Docker container on VPS
  • Frontend: Static files served by Nginx
  • Admin Panel: Static files at win-spin.live/{secret-path}/
  • Database: MySQL on VPS
  • SSL: Let's Encrypt certificates
  • Domain: win-spin.live

This document provides a comprehensive overview of the Lottery Application. For specific implementation details, refer to the source code in the respective service classes and repositories.