Build Laravel 13 ticket assistant with Docker, Livewire admin, and helpdesk scraper command

This commit is contained in:
SitiWeb
2026-04-29 13:11:39 +02:00
parent 141a1a3c9b
commit 3c4572bb12
58 changed files with 9377 additions and 455 deletions

View File

@@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up(): void
{
DB::statement('CREATE EXTENSION IF NOT EXISTS vector');
}
public function down(): void
{
DB::statement('DROP EXTENSION IF EXISTS vector');
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
$dimension = (int) config('services.embedding.dimension', 768);
DB::statement("ALTER TABLE articles ADD COLUMN embedding vector({$dimension})");
DB::statement('CREATE INDEX articles_embedding_cosine_idx ON articles USING ivfflat (embedding vector_cosine_ops)');
}
public function down(): void
{
Schema::dropIfExists('articles');
}
};

View File

@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('tickets', function (Blueprint $table) {
$table->id();
$table->text('message');
$table->timestamps();
});
$dimension = (int) config('services.embedding.dimension', 768);
DB::statement("ALTER TABLE tickets ADD COLUMN embedding vector({$dimension})");
DB::statement('CREATE INDEX tickets_embedding_cosine_idx ON tickets USING ivfflat (embedding vector_cosine_ops)');
}
public function down(): void
{
Schema::dropIfExists('tickets');
}
};

View File

@@ -0,0 +1,23 @@
<?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
{
Schema::create('embedding_cache', function (Blueprint $table) {
$table->id();
$table->string('text_hash', 64)->unique();
$table->longText('text');
$table->json('embedding');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('embedding_cache');
}
};

View File

@@ -0,0 +1,25 @@
<?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
{
Schema::create('ai_decisions', function (Blueprint $table) {
$table->id();
$table->foreignId('ticket_id')->constrained()->cascadeOnDelete();
$table->foreignId('article_id')->nullable()->constrained()->nullOnDelete();
$table->float('confidence')->default(0);
$table->text('explanation')->nullable();
$table->json('raw_response')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('ai_decisions');
}
};

View File

@@ -0,0 +1,24 @@
<?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
{
Schema::create('feedback', function (Blueprint $table) {
$table->id();
$table->foreignId('ticket_id')->constrained()->cascadeOnDelete();
$table->foreignId('article_id')->nullable()->constrained()->nullOnDelete();
$table->boolean('is_correct');
$table->text('notes')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('feedback');
}
};