Passa al contenuto principale

Modelli e Relazioni

I modelli Eloquent rappresentano il cuore dell'applicazione Tidiko AI, gestendo le relazioni tra le entitΓ  principali e fornendo un'interfaccia elegante per l'accesso ai dati.

🏒 Company (Azienda)​

Il modello Company rappresenta le aziende che utilizzano la piattaforma e gestisce le loro informazioni, abbonamenti e limiti.

app/Models/Company.php
class Company extends Model
{
use HasFactory, Billable, Notifiable;

protected $table = 'companies';
protected $guarded = [];

public function stripeEmail(): string|null
{
return $this->email;
}

public function stripeName(): string|null
{
return $this->name;
}

public function subscriptionPlan()
{
$sparkPlan = $this->sparkPlan();
$freePlan = SubscriptionPlan::where('name', 'FREE')->first();

if (!$sparkPlan || !$sparkPlan->id) {
return $freePlan;
}

$subscriptionPlan = SubscriptionPlan::where('sandbox_monthly_price_id', $sparkPlan->id)
->orWhere('sandbox_yearly_price_id', $sparkPlan->id)
->orWhere('production_monthly_price_id', $sparkPlan->id)
->orWhere('production_yearly_price_id', $sparkPlan->id)
->first();

return $subscriptionPlan ?? $freePlan;
}
}

Relazioni Company​

app/Models/Company.php
// Relazioni principali
public function assistants()
{
return $this->hasMany(Assistant::class, 'company_id');
}

public function agents()
{
return $this->hasMany(Agent::class, 'company_id');
}

public function users()
{
return $this->hasMany(User::class, 'company_id');
}

public function files()
{
return $this->hasMany(File::class, 'company_id');
}

public function subscriptions()
{
return $this->hasMany(Subscription::class)->orderBy('created_at', 'desc');
}

Campi Principali​

CampoTipoDescrizione
namestringNome dell'azienda
emailstringEmail principale
addressstringIndirizzo
citystringCittΓ 
provincestringProvincia
zipcodestringCAP
websitestringSito web
vatcodestringCodice IVA
phonestringTelefono
credit_balanceintSaldo crediti disponibili
subscription_plan_idintID del piano di abbonamento attivo
stripe_idstringID Stripe
subscription_stripe_idstringID abbonamento Stripe
pm_typestringTipo metodo di pagamento
pm_last_fourstringUltime 4 cifre carta
billing_addressstringIndirizzo di fatturazione
billing_citystringCittΓ  di fatturazione
billing_countrystringPaese di fatturazione

πŸ€– Assistant (Assistente)​

Il modello Assistant rappresenta gli assistenti AI configurati dalle aziende.

app/Models/Assistant.php
class Assistant extends Model
{
use HasFactory;

protected $table = 'assistants';
protected $guarded = [];

public function files()
{
return $this->hasMany(File::class, 'vector_store_uuid', 'vector_store_uuid');
}

public function conversations()
{
return $this->hasMany(Conversation::class, 'assistant_id');
}

public function company()
{
return $this->belongsTo(Company::class);
}
}

Campi Principali Assistant​

CampoTipoDescrizione
assistant_uuidstringUUID univoco dell'assistente
vector_store_uuidstringUUID del vector store associato
namestringNome dell'assistente
descriptiontextDescrizione dell'assistente
instructionstextIstruzioni per l'AI
modelstringModello AI utilizzato (es. gpt-4o)
file_searchintAbilita ricerca nei file
code_interpreterintAbilita interprete di codice
response_formatstringFormato di risposta
temperaturestringTemperatura per la generazione
topPstringTop-p per la generazione
domainsstringDomini autorizzati (comma-separated)
notificationstringConfigurazione notifiche
embedding_optionsstringOpzioni di embedding
iconstringIcona dell'assistente
feed_keystringChiave per feed
feed_enabledintAbilita feed
feed_last_updatestringUltimo aggiornamento feed

🎯 Agent (Agente)​

Il modello Agent rappresenta agenti specializzati per e-commerce e integrazioni specifiche.

app/Models/Agent.php
class Agent extends Model
{
use HasFactory;

protected $table = 'agents';
protected $guarded = [];

public function files()
{
return $this->hasMany(File::class, 'vector_store_uuid', 'vector_store_uuid');
}

public function company()
{
return $this->belongsTo(Company::class);
}

public function getVectorStoreUuid()
{
$company = $this->company;
return $company->vector_store_uuid;
}

public function conversations()
{
return $this->hasMany(Conversation::class, 'agent_id');
}
}

Campi Principali Agent​

CampoTipoDescrizione
agent_uuidstringUUID univoco dell'agente
namestringNome dell'agente
company_namestringNome dell'azienda per l'agente
company_descriptiontextDescrizione dell'azienda
file_searchintAbilita ricerca nei file
shop_seachintAbilita ricerca nel negozio
languagestringLingua dell'agente
woo_consumer_keystringChiave consumer WooCommerce
woo_consumer_secretstringSegreto consumer WooCommerce
website_urlstringURL del sito web
iconstringIcona dell'agente
embedding_optionsstringOpzioni di embedding
domainsstringDomini autorizzati
feed_keystringChiave per feed
notificationstringConfigurazione notifiche
enable_extra_instructionsintAbilita istruzioni extra
extra_instructionsstringIstruzioni extra
vector_store_uuidstringUUID del vector store

πŸ’¬ Conversation (Conversazione)​

Il modello Conversation gestisce le conversazioni tra utenti e assistenti/agenti.

app/Models/Conversation.php
class Conversation extends Model
{
use HasFactory;

protected $table = 'conversations';
protected $guarded = [];

public function messages()
{
return $this->hasMany(Message::class);
}

public function agent()
{
return $this->belongsTo(Agent::class, 'agent_id');
}

public function assistant()
{
return $this->belongsTo(Assistant::class, 'assistant_id');
}
}

Campi Principali Conversation​

CampoTipoDescrizione
conversation_uuidstringUUID univoco della conversazione
assistant_idintID dell'assistente (nullable)
agent_idintID dell'agente (nullable)
started_atdatetimeData/ora di inizio
ended_atdatetimeData/ora di fine
tokens_usedintToken totali utilizzati
input_tokens_usedintToken di input utilizzati
output_tokens_usedintToken di output utilizzati
input_costdecimalCosto dei token di input
output_costdecimalCosto dei token di output
domainstringDominio di origine
locationjsonInformazioni di geolocalizzazione

πŸ“ Message (Messaggio)​

Il modello Message rappresenta i singoli messaggi all'interno delle conversazioni.

app/Models/Message.php
class Message extends Model
{
use HasFactory;

protected $table = 'messages';
protected $guarded = [];

public function conversation()
{
return $this->belongsTo(Conversation::class);
}
}

Campi Principali Message​

CampoTipoDescrizione
message_uuidstringUUID univoco del messaggio
conversation_idintID della conversazione
senderstringMittente (user/assistant)
messagetextContenuto del messaggio
tokens_usedintToken utilizzati per questo messaggio
modelstringModello AI utilizzato
costdecimalCosto del messaggio

πŸ“„ File (File)​

Il modello File gestisce i file caricati per il training degli assistenti.

app/Models/File.php
class File extends Model
{
use HasFactory;

protected $table = 'files';
protected $guarded = [];

public function company()
{
return $this->belongsTo(Company::class);
}

public function user()
{
return $this->belongsTo(User::class);
}
}

Campi Principali File​

CampoTipoDescrizione
file_uuidstringUUID univoco del file
vector_store_uuidstringUUID del vector store
namestringNome del file
processed_namestringNome processato del file
typestringTipo (file/link/api)
content_typestringTipo di contenuto
sizeintDimensione in bytes
processedintSe il file Γ¨ stato processato
refresh_enabledintSe il refresh Γ¨ abilitato
refresh_interval_daysintIntervallo di refresh in giorni
next_refresh_atstringProssimo refresh
api_request_typestringTipo richiesta API
jwt_tokenstringToken JWT per API
api_request_bodystringBody richiesta API
uploaded_atstringData di upload

πŸ’³ SubscriptionPlan (Piano di Abbonamento)​

Il modello SubscriptionPlan gestisce i piani di abbonamento disponibili.

app/Models/SubscriptionPlan.php
class SubscriptionPlan extends Model
{
use HasFactory;

protected $table = 'subscription_plans';
protected $guarded = [];

protected $casts = [
'is_default' => 'boolean',
'is_custom' => 'boolean',
'features' => 'array',
'monthly_price' => 'decimal:2',
'yearly_price' => 'decimal:2',
];

public function toSparkPlan(): array
{
$sparkPlan = [
'name' => $this->name,
'short_description' => $this->short_description ?? "Abbonamento {$this->name} Tidiko",
'features' => $this->generateFeatures(),
'archived' => false,
];

$isTestMode = config('app.stripe_test', false);
$monthlyPriceId = $isTestMode ? $this->sandbox_monthly_price_id : $this->production_monthly_price_id;
$yearlyPriceId = $isTestMode ? $this->sandbox_yearly_price_id : $this->production_yearly_price_id;

if ($monthlyPriceId) {
$sparkPlan['monthly_id'] = $monthlyPriceId;
}

if ($yearlyPriceId) {
$sparkPlan['yearly_id'] = $yearlyPriceId;
}

return $sparkPlan;
}
}

Campi Principali SubscriptionPlan​

CampoTipoDescrizione
namestringNome del piano
short_descriptionstringDescrizione breve
max_assistantsintNumero massimo di assistenti
max_productsintNumero massimo di prodotti
max_messagesintNumero massimo di messaggi mensili
max_file_uploadsintNumero massimo di upload file
storage_limit_mbintLimite di storage in MB
monthly_pricedecimalPrezzo mensile
yearly_pricedecimalPrezzo annuale
is_defaultbooleanPiano predefinito
is_custombooleanPiano personalizzato
featuresjsonArray delle funzionalitΓ  incluse
sort_orderintOrdine di visualizzazione
sandbox_product_idstringID prodotto Stripe sandbox
sandbox_monthly_price_idstringID prezzo mensile sandbox
sandbox_yearly_price_idstringID prezzo annuale sandbox
production_product_idstringID prodotto Stripe production
production_monthly_price_idstringID prezzo mensile production
production_yearly_price_idstringID prezzo annuale production

πŸ”‘ ApiKey (Chiave API)​

Il modello ApiKey gestisce le chiavi API per l'integrazione.

app/Models/ApiKey.php
class ApiKey extends Model
{
use HasFactory;

protected $table = 'api_keys';
protected $guarded = [];

public function company()
{
return $this->belongsTo(Company::class, 'company_id');
}
}

Campi Principali ApiKey​

CampoTipoDescrizione
namestringNome della chiave API
keystringChiave API crittografata
activeintSe la chiave Γ¨ attiva
notestringNote sulla chiave
allowed_hoststringHost autorizzato
company_idintID dell'azienda proprietaria

πŸ‘€ User (Utente)​

Il modello User gestisce gli utenti del sistema.

app/Models/User.php
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable;

protected $fillable = [
'name',
'email',
'password',
'role',
'company_id',
];

protected $hidden = [
'password',
'remember_token',
];

protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];

public function company()
{
return $this->belongsTo(Company::class);
}
}

Campi Principali User​

CampoTipoDescrizione
namestringNome dell'utente
emailstringEmail dell'utente
passwordstringPassword hashata
rolestringRuolo (admin/editor)
company_idintID dell'azienda
email_verified_atdatetimeData verifica email
remember_tokenstringToken per remember me
terms_acceptance_idintID accettazione termini

πŸ”” Notification (Notifica)​

Il modello Notification gestisce le notifiche del sistema.

app/Models/Notification.php
class Notification extends Model
{
use HasFactory;

protected $table = 'notifications';
protected $guarded = [];

public function company()
{
return $this->belongsTo(Company::class);
}
}

Campi Principali Notification​

CampoTipoDescrizione
titlestringTitolo della notifica
messagestringMessaggio della notifica
typestringTipo di notifica
statusstringStato (read/unread)
urlstringURL di destinazione
company_idintID dell'azienda

πŸ€– ModelAI (Modello AI)​

Il modello ModelAI gestisce i modelli AI disponibili e i loro costi.

app/Models/ModelAI.php
class ModelAI extends Model
{
use HasFactory;

protected $table = 'models';
}

Campi Principali ModelAI​

CampoTipoDescrizione
namestringNome del modello AI
tokensintNumero di token per calcolo
input_cost_per_tokensstringCosto per token di input
output_cost_per_tokensstringCosto per token di output
commission_ratestringTasso di commissione
cache_read_cost_per_tokenstringCosto per token di cache read

πŸ“ PromptTemplate (Template Prompt)​

Il modello PromptTemplate gestisce i template di prompt per assistenti e agenti.

app/Models/PromptTemplate.php
class PromptTemplate extends Model
{
use HasFactory;

protected $table = 'prompt_templates';
protected $guarded = [];
}

Campi Principali PromptTemplate​

CampoTipoDescrizione
namestringNome del template
descriptionstringDescrizione del template
promptstringContenuto del prompt
typestringTipo (instruction/type/personality)
company_idintID azienda (nullable)
user_idintID utente (nullable)

πŸ“Š Relazioni tra Modelli​

Diagramma delle Relazioni​

Relazioni Principali​

  1. Company β†’ Assistants/Agents: Una azienda puΓ² avere assistenti e agenti multipli
  2. Company β†’ Users: Una azienda puΓ² avere utenti multipli
  3. Company β†’ Files: Una azienda puΓ² avere file multipli
  4. Company β†’ ApiKeys: Una azienda puΓ² avere chiavi API multiple
  5. Company β†’ Notifications: Una azienda puΓ² avere notifiche multiple
  6. Assistant/Agent β†’ Conversations: Ogni assistente/agente puΓ² avere conversazioni multiple
  7. Conversation β†’ Messages: Ogni conversazione contiene messaggi multipli
  8. Assistant/Agent β†’ Files: Gli assistenti/agenti possono condividere file tramite vector_store_uuid
  9. User β†’ Files: Gli utenti possono caricare file
  10. User β†’ PromptTemplates: Gli utenti possono creare template di prompt
  11. ModelAI β†’ Messages: I modelli AI sono utilizzati nei messaggi
  12. PromptTemplate β†’ Assistant: I template di prompt sono utilizzati dagli assistenti

πŸ”„ Eventi e Observer​

Model Events​

app/Observers/AssistantObserver.php
class AssistantObserver
{
public function created(Assistant $assistant)
{
// Creazione automatica del vector store
$vectorStoreUuid = NodeApiService::createCollection($assistant);
$assistant->update(['vector_store_uuid' => $vectorStoreUuid]);
}

public function deleting(Assistant $assistant)
{
// Pulizia del vector store
NodeApiService::deleteAssistant($assistant);
}
}

Scopes e Query Builders​

app/Models/Assistant.php
class Assistant extends Model
{
public function scopeForCompany($query, $companyId)
{
return $query->where('company_id', $companyId);
}

public function scopeActive($query)
{
return $query->whereNull('deleted_at');
}

public function scopeWithFiles($query)
{
return $query->with(['files' => function($q) {
$q->where('processed', true);
}]);
}
}

πŸ“ˆ Performance e Ottimizzazioni​

Eager Loading​

app/Http/Controllers/AssistantController.php
public function index()
{
$assistants = Assistant::with(['company', 'files', 'conversations'])
->where('company_id', auth()->user()->company_id)
->get();

return view('assistants.index', compact('assistants'));
}

Caching delle Relazioni​

app/Models/Company.php
public function subscriptionPlan()
{
return Cache::remember("company_{$this->id}_subscription_plan", 3600, function() {
$sparkPlan = $this->sparkPlan();
$freePlan = SubscriptionPlan::where('name', 'FREE')->first();

if (!$sparkPlan || !$sparkPlan->id) {
return $freePlan;
}

return SubscriptionPlan::where('sandbox_monthly_price_id', $sparkPlan->id)
->orWhere('production_monthly_price_id', $sparkPlan->id)
->first() ?? $freePlan;
});
}

I modelli Eloquent forniscono una base solida e flessibile per la gestione dei dati nell'applicazione Tidiko AI, con relazioni ben definite e ottimizzazioni per le performance.