123 lines
5.7 KiB
PHP
123 lines
5.7 KiB
PHP
<?php
|
|
|
|
use Illuminate\Database\Migrations\Migration;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
return new class extends Migration
|
|
{
|
|
public function up(): void
|
|
{
|
|
// ---------------------------------------------------------------
|
|
// PERSONAL ACCESS TOKENS (Sanctum)
|
|
// ---------------------------------------------------------------
|
|
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->morphs('tokenable');
|
|
$table->text('name');
|
|
$table->string('token', 64)->unique();
|
|
$table->text('abilities')->nullable();
|
|
$table->timestamp('last_used_at')->nullable();
|
|
$table->timestamp('expires_at')->nullable()->index();
|
|
$table->timestamps();
|
|
});
|
|
|
|
// ---------------------------------------------------------------
|
|
// WALLETS (per-currency balance per user)
|
|
// ---------------------------------------------------------------
|
|
Schema::create('wallets', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
|
$table->string('currency', 10); // BTC | ETH | SOL | BTX | EUR
|
|
$table->decimal('balance', 20, 8)->default(0);
|
|
$table->string('deposit_address')->nullable();
|
|
$table->timestamps();
|
|
|
|
$table->unique(['user_id', 'currency']);
|
|
$table->index(['user_id', 'currency']);
|
|
});
|
|
|
|
// ---------------------------------------------------------------
|
|
// WALLET TRANSFERS (main balance <-> vault, audit log)
|
|
// ---------------------------------------------------------------
|
|
Schema::create('wallet_transfers', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
|
$table->enum('type', ['deposit', 'withdraw']); // deposit = main->vault, withdraw = vault->main
|
|
$table->decimal('amount', 20, 4);
|
|
$table->decimal('balance_before', 20, 4);
|
|
$table->decimal('balance_after', 20, 4);
|
|
$table->decimal('vault_before', 20, 4);
|
|
$table->decimal('vault_after', 20, 4);
|
|
$table->string('currency', 10)->default('BTX');
|
|
$table->string('idempotency_key', 64)->nullable();
|
|
$table->json('meta')->nullable();
|
|
$table->timestamps();
|
|
|
|
$table->index(['user_id', 'created_at']);
|
|
$table->index(['user_id', 'type']);
|
|
$table->unique(['user_id', 'idempotency_key']);
|
|
});
|
|
|
|
// ---------------------------------------------------------------
|
|
// VAULT TRANSFERS (encrypted audit trail)
|
|
// ---------------------------------------------------------------
|
|
Schema::create('vault_transfers', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
|
$table->string('direction', 16); // to_vault | from_vault
|
|
$table->text('amount'); // Encrypted
|
|
$table->text('main_balance_before'); // Encrypted
|
|
$table->text('main_balance_after'); // Encrypted
|
|
$table->text('vault_balance_before'); // Encrypted
|
|
$table->text('vault_balance_after'); // Encrypted
|
|
$table->string('idempotency_key', 64)->nullable();
|
|
$table->string('source', 16)->default('web'); // web | api
|
|
$table->unsignedBigInteger('created_by')->nullable();
|
|
$table->text('metadata')->nullable(); // Encrypted
|
|
$table->timestamps();
|
|
|
|
$table->index(['user_id', 'created_at']);
|
|
$table->index(['user_id', 'direction']);
|
|
$table->unique(['user_id', 'idempotency_key']);
|
|
});
|
|
|
|
// ---------------------------------------------------------------
|
|
// CRYPTO PAYMENTS (NOWPayments / on-chain deposits)
|
|
// ---------------------------------------------------------------
|
|
Schema::create('crypto_payments', function (Blueprint $table) {
|
|
$table->id();
|
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
|
$table->uuid('order_id')->unique();
|
|
$table->string('invoice_id')->unique();
|
|
$table->string('payment_id')->unique();
|
|
$table->string('pay_currency', 20);
|
|
$table->decimal('pay_amount', 36, 18)->nullable();
|
|
$table->decimal('actually_paid', 36, 18)->nullable();
|
|
$table->string('pay_address')->nullable();
|
|
$table->decimal('price_amount', 20, 8)->nullable();
|
|
$table->string('price_currency', 10)->default('USD');
|
|
$table->decimal('exchange_rate_at_payment', 28, 12)->nullable();
|
|
$table->string('status', 40)->index(); // waiting | confirming | finished | failed | expired | partially_paid
|
|
$table->unsignedInteger('confirmations')->nullable();
|
|
$table->json('tx_hash')->nullable();
|
|
$table->decimal('fee', 36, 18)->nullable();
|
|
$table->json('raw_payload')->nullable();
|
|
$table->decimal('credited_btx', 20, 8)->nullable();
|
|
$table->timestamp('credited_at')->nullable();
|
|
$table->timestamps();
|
|
|
|
$table->index(['user_id', 'status']);
|
|
});
|
|
}
|
|
|
|
public function down(): void
|
|
{
|
|
Schema::dropIfExists('crypto_payments');
|
|
Schema::dropIfExists('vault_transfers');
|
|
Schema::dropIfExists('wallet_transfers');
|
|
Schema::dropIfExists('wallets');
|
|
Schema::dropIfExists('personal_access_tokens');
|
|
}
|
|
};
|