init commit

This commit is contained in:
David Melendez
2026-01-14 22:38:44 +01:00
parent 4e0c415f0b
commit e25d53d054
124 changed files with 21653 additions and 1 deletions

View File

@@ -0,0 +1,63 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('phone')->nullable();
$table->date('date_of_birth')->nullable();
$table->enum('gender', ['male', 'female', 'other', 'prefer_not_to_say'])->nullable();
$table->string('avatar')->nullable();
$table->text('bio')->nullable();
$table->string('website')->nullable();
$table->string('linkedin')->nullable();
$table->string('github')->nullable();
$table->string('twitter')->nullable();
$table->json('preferences')->nullable(); // User preferences as JSON
$table->boolean('newsletter_subscribed')->default(false);
$table->timestamp('last_login_at')->nullable();
$table->string('last_login_ip')->nullable();
$table->enum('status', ['active', 'inactive', 'suspended'])->default('active');
$table->timestamp('suspended_at')->nullable();
$table->string('suspension_reason')->nullable();
$table->integer('login_attempts')->default(0);
$table->timestamp('locked_until')->nullable();
$table->string('locale', 10)->default('en');
$table->string('timezone', 50)->default('UTC');
$table->boolean('two_factor_enabled')->default(false);
$table->string('two_factor_secret')->nullable();
$table->json('two_factor_recovery_codes')->nullable();
$table->timestamp('profile_completed_at')->nullable();
$table->rememberToken();
$table->timestamps();
// Indexes for performance
$table->index(['email', 'status']);
$table->index(['last_login_at']);
$table->index(['created_at']);
$table->index(['status']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('password_reset_tokens', function (Blueprint $table) {
$table->string('email')->primary();
$table->string('token');
$table->timestamp('created_at')->nullable();
$table->index(['email', 'token']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('password_reset_tokens');
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
$table->text('connection');
$table->string('queue', 191); // Changed from text to string with length
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
$table->index(['failed_at']);
$table->index(['queue']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('failed_jobs');
}
};

View File

@@ -0,0 +1,64 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('resumes', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('title');
$table->text('description')->nullable();
$table->enum('template', ['professional', 'modern', 'executive', 'minimal', 'technical'])->default('professional');
$table->json('content')->nullable(); // Resume content as JSON
$table->json('settings')->nullable(); // Template settings as JSON
$table->enum('status', ['draft', 'published', 'archived'])->default('draft');
$table->boolean('is_public')->default(false);
$table->string('public_url')->nullable()->unique();
$table->timestamp('published_at')->nullable();
$table->integer('view_count')->default(0);
$table->integer('download_count')->default(0);
$table->timestamp('last_viewed_at')->nullable();
$table->timestamp('last_downloaded_at')->nullable();
$table->integer('completion_percentage')->default(0);
$table->json('completion_sections')->nullable(); // Which sections are complete
$table->string('pdf_path')->nullable(); // Path to generated PDF
$table->timestamp('pdf_generated_at')->nullable();
$table->integer('pdf_version')->default(1);
$table->json('analytics')->nullable(); // Analytics data
$table->json('feedback')->nullable(); // User feedback/notes
$table->boolean('allow_comments')->default(false);
$table->string('password')->nullable(); // Password protection
$table->timestamp('expires_at')->nullable(); // Public link expiration
$table->json('share_settings')->nullable(); // Sharing permissions
$table->string('slug')->nullable(); // SEO-friendly URL
$table->json('seo_meta')->nullable(); // SEO metadata
$table->timestamps();
$table->softDeletes(); // Soft delete for data recovery
// Indexes for performance
$table->index(['user_id', 'status']);
$table->index(['is_public', 'published_at']);
$table->index(['template']);
$table->index(['created_at']);
$table->index(['view_count']);
$table->index(['slug']);
$table->index(['public_url']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('resumes');
}
};

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('resume_views', function (Blueprint $table) {
$table->id();
$table->foreignId('resume_id')->constrained()->onDelete('cascade');
$table->string('ip_address');
$table->string('user_agent')->nullable();
$table->string('referrer')->nullable();
$table->string('country')->nullable();
$table->string('city')->nullable();
$table->json('browser_info')->nullable(); // Browser details
$table->integer('duration')->nullable(); // Time spent viewing (seconds)
$table->boolean('is_download')->default(false);
$table->enum('format', ['web', 'pdf', 'docx'])->default('web');
$table->timestamp('viewed_at');
$table->timestamps();
// Indexes for analytics
$table->index(['resume_id', 'viewed_at']);
$table->index(['ip_address']);
$table->index(['country']);
$table->index(['is_download']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('resume_views');
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('activity_logs', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained()->onDelete('set null');
$table->string('event'); // login, logout, resume_created, etc.
$table->string('description');
$table->json('properties')->nullable(); // Additional event data
$table->string('ip_address')->nullable();
$table->string('user_agent')->nullable();
$table->morphs('subject'); // Polymorphic relation to any model
$table->timestamps();
// Indexes for querying
$table->index(['user_id', 'created_at']);
$table->index(['event']);
// Note: morphs() already creates an index for subject_type and subject_id
$table->index(['created_at']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('activity_logs');
}
};