Added database structure and components

This commit is contained in:
2025-11-13 21:27:45 +00:00
parent 3f1c69c15b
commit 98a2ca4611
182 changed files with 3847 additions and 9 deletions
@@ -0,0 +1,258 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
// Administrator, Player
$table->enum('type', ['A', 'P'])->default('P');
// Nickname - must be unique
$table->string('nickname', 20)->nullable()->unique();
// User access is blocked
$table->boolean('blocked')->default(false);
// User Photo/Avatar
$table->string('photo_avatar_filename')->nullable();
// Brain Coin Balance
$table->integer('coins_balance')->default(0);
// Users can be deleted with "soft deletes"
$table->softDeletes();
// custom data
$table->json('custom')->nullable();
});
// NOTE: Only multiplayer matches are registered
Schema::create('matches', function (Blueprint $table) {
$table->id();
// Type of games in the match (Bisca dos 3; Bisca dos 9)
$table->enum('type', ['3', '9'])->default('3');
// Player 1 (usually, creates the match)
$table->unsignedBigInteger('player1_user_id');
$table->foreign('player1_user_id')->references('id')->on('users');
// Player 2 (usually, joins the match)
$table->unsignedBigInteger('player2_user_id');
$table->foreign('player2_user_id')->references('id')->on('users');
// Winner (null when not ended)
$table->unsignedBigInteger('winner_user_id')->nullable();
$table->foreign('winner_user_id')->references('id')->on('users');
// Loser (null when not ended)
$table->unsignedBigInteger('loser_user_id')->nullable();
$table->foreign('loser_user_id')->references('id')->on('users');
// Match status
// Pending - Match is waiting for players
// Playing - Match is in progress
// Ended - Match is over
// Interrupted - Match was interrupted due to technical issues (not finished; no winner)
// Note: depending of the project's implementation, some status may never be used
$table->enum('status', ['Pending', 'Playing', 'Ended', 'Interrupted']);
// The stake for this match
$table->integer('stake')->default(3);
// Moment when the match began
$table->dateTime('began_at')->nullable();
// Moment when the match ended
$table->dateTime('ended_at')->nullable();
// Match total time (in seconds) = ended_at - began_at
$table->decimal('total_time', 8, 2)->nullable();
// After the match ended, the total marks for player 1
$table->integer('player1_marks')->nullable();
// After the game ended, the total marks for player 2
$table->integer('player2_marks')->nullable();
// After the match ended, the sum of points for player 1 (all games)
$table->integer('player1_points')->nullable();
// After the match ended, the sum of points for player 2 (all games)
$table->integer('player2_points')->nullable();
// custom data
$table->json('custom')->nullable();
});
// NOTE: Only multiplayer games are registered
Schema::create('games', function (Blueprint $table) {
$table->id();
// Type of game (Bisca dos 3; Bisca dos 9)
$table->enum('type', ['3', '9'])->default('3');
// Player 1 (usually, creates the game)
$table->unsignedBigInteger('player1_user_id');
$table->foreign('player1_user_id')->references('id')->on('users');
// Player 2 (usually, joins the game)
$table->unsignedBigInteger('player2_user_id');
$table->foreign('player2_user_id')->references('id')->on('users');
// True when the game has ended with a draw
$table->boolean('is_draw')->default(false);
// Winner (null when not ended, or when a draw)
$table->unsignedBigInteger('winner_user_id')->nullable();
$table->foreign('winner_user_id')->references('id')->on('users');
// Loser (null when not ended, or when a draw)
$table->unsignedBigInteger('loser_user_id')->nullable();
$table->foreign('loser_user_id')->references('id')->on('users');
// Match (null for standalone games)
$table->unsignedBigInteger('match_id')->nullable();
$table->foreign('match_id')->references('id')->on('matches');
// Game status: 'Pending', 'Playing', 'Ended', or 'Interrupted'.
// Pending: waiting for players
// Playing: in progress
// Ended: finished
// Interrupted: stopped due to technical issues (unfinished; no winner)
// Note: depending on the projects implementation, some statuses may never be used.
$table->enum('status', ['Pending', 'Playing', 'Ended', 'Interrupted']);
// Moment when the game began
$table->dateTime('began_at')->nullable();
// Moment when the game ended
$table->dateTime('ended_at')->nullable();
// Game total time (in seconds) = ended_at - began_at
$table->decimal('total_time', 8, 2)->nullable();
// After the game ended, the total of points for player 1
$table->integer('player1_points')->nullable();
// After the game ended, the total of points for player 2
$table->integer('player2_points')->nullable();
// custom data
$table->json('custom')->nullable();
});
Schema::create('coin_transaction_types', function (Blueprint $table) {
$table->id();
$table->string('name', 40);
// Credit - increase coins
// Debit - decrease coins
$table->enum('type', ['C', 'D']);
// Transaction Types can be deleted with "soft deletes"
$table->softDeletes();
// custom data
$table->json('custom')->nullable();
});
// Add default coin_transaction_types
DB::table('coin_transaction_types')->insert([
['name' => 'Bonus', 'type' => 'C'], // id = 1
['name' => 'Coin purchase', 'type' => 'C'], // id = 2
['name' => 'Game fee', 'type' => 'D'], // id = 3
['name' => 'Match stake', 'type' => 'D'], // id = 4
['name' => 'Game payout', 'type' => 'C'], // id = 5
['name' => 'Match payout', 'type' => 'C'], // id = 6
]);
Schema::create('coin_transactions', function (Blueprint $table) {
$table->id();
// Datetime of the coin transaction
$table->dateTime('transaction_datetime');
// User associated with the transaction
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
// Match associated with the transaction (optional - it can be null)
$table->unsignedBigInteger('match_id')->nullable();
$table->foreign('match_id')->references('id')->on('matches');
// Game associated with the transaction (optional - it can be null)
$table->unsignedBigInteger('game_id')->nullable();
$table->foreign('game_id')->references('id')->on('games');
// Type of the transaction
$table->unsignedBigInteger('coin_transaction_type_id');
$table->foreign('coin_transaction_type_id')->references('id')->on('coin_transaction_types');
// Amount of the transaction (coins)
// Positive -> increments the total amount of brain coins (Credit)
// Negative -> decrements the total amount of brain coins (Debit)
$table->integer('coins');
// custom data
$table->json('custom')->nullable();
});
Schema::create('coin_purchases', function (Blueprint $table) {
$table->id();
// Datetime of the coin purchase
$table->dateTime('purchase_datetime');
// User associated with the purchase
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
// Coin Transaction associated with this purchase
// One to One relation (purchase must have a coin transaction)
$table->unsignedBigInteger('coin_transaction_id')->unique();
$table->foreign('coin_transaction_id')->references('id')->on('coin_transactions');
// Amount of the purchase (real money in euros)
$table->decimal('euros', 8, 2);
// Purchases will involve a payment with a type and a reference
// MBWAY - Phone number with 9 digits
// PAYPAL - eMail
// IBAN - bank transfer (2 letters + 23 digits)
// MB - Multibanco payment - entity number (5 digits) + Reference (9 digits))
// VISA - Visa card number (16 digits)
$table->enum('payment_type', ['MBWAY', 'PAYPAL', 'IBAN', 'MB', 'VISA']);
$table->string('payment_reference', 30);
// custom data
$table->json('custom')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::drop('coin_purchases');
Schema::drop('coin_transactions');
Schema::drop('coin_transaction_types');
Schema::drop('games');
Schema::drop('matches');
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('deleted_at');
$table->dropColumn('custom');
$table->dropColumn('coins_balance');
$table->dropColumn('photo_avatar_filename');
$table->dropColumn('blocked');
$table->dropColumn('nickname');
$table->dropColumn('type');
});
}
};