976c0f03e3
Schema: - ai_chats: company_id, user_id, title, provider; index pe activitate - ai_messages: role (system/user/assistant), content, meta JSON (tokens, latency, model) Service AiAssistantService (multi-provider): - ask($chat, $message): persistă mesajul user, build system prompt cu context tenant (statistici clienți/mașini/cereri/datorii), apelează API-ul providerului, persistă răspunsul cu meta (tokens, latency) - callClaude: api.anthropic.com/v1/messages cu claude-sonnet-4-5 - callOpenAI: api.openai.com/v1/chat/completions cu gpt-4o-mini - callGemini: generativelanguage.googleapis.com cu gemini-1.5-flash - Try/catch pe toate; eroare devine mesaj asistent fără să crape System prompt include: - Numele și orașul companiei - Statistici curente (clienți, mașini, cereri noi, fișe active, datorii) - Limita stricta: NU inventează date Custom Filament Page /app/ai-assistant (group Analiză): - Sidebar stâng: listă conversații (last 20), buton 'Nouă' + delete cu confirm - Main: bubble chat (user dreapta albastru, asistent stânga gri) - Meta jos pe răspuns: provider · latency · tokens - Empty state friendly cu instrucțiuni configurare - Loading indicator (3 dots animate) când AI răspunde - Auto-scroll la mesaj nou - Enter trimite, Shift+Enter newline - Auto-titlu chat din primul mesaj user (60 chars) Settings page extins cu secțiune 'Asistent AI': - Provider implicit (claude/gpt/gemini) - 3 chei API (password fields, revealable) - Key-urile salvate în companies.settings.ai (per tenant, izolat)
41 lines
1.4 KiB
PHP
41 lines
1.4 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
|
|
{
|
|
Schema::create('ai_chats', function (Blueprint $t) {
|
|
$t->id();
|
|
$t->foreignId('company_id')->constrained()->cascadeOnDelete();
|
|
$t->foreignId('user_id')->constrained()->cascadeOnDelete();
|
|
$t->string('title')->default('Conversație nouă');
|
|
$t->string('provider')->default('claude'); // claude / gpt / gemini
|
|
$t->timestamps();
|
|
|
|
$t->index(['company_id', 'user_id', 'updated_at']);
|
|
});
|
|
|
|
Schema::create('ai_messages', function (Blueprint $t) {
|
|
$t->id();
|
|
$t->foreignId('company_id')->constrained()->cascadeOnDelete();
|
|
$t->foreignId('ai_chat_id')->constrained()->cascadeOnDelete();
|
|
$t->string('role'); // system / user / assistant
|
|
$t->longText('content');
|
|
$t->json('meta')->nullable(); // tokens, model, latency_ms
|
|
$t->timestamps();
|
|
|
|
$t->index(['company_id', 'ai_chat_id', 'created_at']);
|
|
});
|
|
}
|
|
|
|
public function down(): void
|
|
{
|
|
Schema::dropIfExists('ai_messages');
|
|
Schema::dropIfExists('ai_chats');
|
|
}
|
|
};
|