feat: multi-tenant SaaS implementation - admin interface, tenant isolation, and UI updates
This commit is contained in:
@@ -9,10 +9,12 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
#[Fillable(['user_id', 'job_position_id', 'phone', 'linkedin_url', 'status', 'notes', 'cv_score', 'motivation_score', 'interview_score', 'ai_analysis'])]
|
||||
use App\Traits\BelongsToTenant;
|
||||
|
||||
#[Fillable(['user_id', 'job_position_id', 'phone', 'linkedin_url', 'status', 'notes', 'cv_score', 'motivation_score', 'interview_score', 'ai_analysis', 'tenant_id'])]
|
||||
class Candidate extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasFactory, BelongsToTenant;
|
||||
|
||||
protected $casts = [
|
||||
'ai_analysis' => 'array',
|
||||
|
||||
@@ -7,10 +7,12 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
#[Fillable(['title', 'description', 'requirements', 'ai_prompt'])]
|
||||
use App\Traits\BelongsToTenant;
|
||||
|
||||
#[Fillable(['title', 'description', 'requirements', 'ai_prompt', 'tenant_id'])]
|
||||
class JobPosition extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasFactory, BelongsToTenant;
|
||||
|
||||
protected $casts = [
|
||||
'requirements' => 'array',
|
||||
|
||||
@@ -8,10 +8,12 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
#[Fillable(['title', 'description', 'duration_minutes'])]
|
||||
use App\Traits\BelongsToTenant;
|
||||
|
||||
#[Fillable(['title', 'description', 'duration_minutes', 'tenant_id'])]
|
||||
class Quiz extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasFactory, BelongsToTenant;
|
||||
|
||||
public function questions(): HasMany
|
||||
{
|
||||
|
||||
31
app/Models/Tenant.php
Normal file
31
app/Models/Tenant.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
|
||||
#[Fillable(['name'])]
|
||||
class Tenant extends Model
|
||||
{
|
||||
public function users()
|
||||
{
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
|
||||
public function candidates()
|
||||
{
|
||||
return $this->hasMany(Candidate::class);
|
||||
}
|
||||
|
||||
public function quizzes()
|
||||
{
|
||||
return $this->hasMany(Quiz::class);
|
||||
}
|
||||
|
||||
public function jobPositions()
|
||||
{
|
||||
return $this->hasMany(JobPosition::class);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
#[Fillable(['name', 'email', 'password', 'role'])]
|
||||
#[Fillable(['name', 'email', 'password', 'role', 'tenant_id'])]
|
||||
#[Hidden(['password', 'remember_token'])]
|
||||
class User extends Authenticatable
|
||||
{
|
||||
@@ -19,7 +19,12 @@ class User extends Authenticatable
|
||||
|
||||
public function isAdmin(): bool
|
||||
{
|
||||
return $this->role === 'admin';
|
||||
return in_array($this->role, ['admin', 'super_admin']);
|
||||
}
|
||||
|
||||
public function isSuperAdmin(): bool
|
||||
{
|
||||
return $this->role === 'super_admin';
|
||||
}
|
||||
|
||||
public function isCandidate(): bool
|
||||
@@ -32,6 +37,11 @@ class User extends Authenticatable
|
||||
return $this->hasOne(Candidate::class);
|
||||
}
|
||||
|
||||
public function tenant()
|
||||
{
|
||||
return $this->belongsTo(Tenant::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user