init
This commit is contained in:
86
app/Models/AiModel.php
Normal file
86
app/Models/AiModel.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EntityStatus;
|
||||
use App\Enums\SourceLevel;
|
||||
use App\Models\Concerns\HasPublicationScope;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class AiModel extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasPublicationScope;
|
||||
|
||||
protected $table = 'ai_models';
|
||||
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'source_id',
|
||||
'name',
|
||||
'slug',
|
||||
'provider',
|
||||
'summary',
|
||||
'description',
|
||||
'modality',
|
||||
'context_window',
|
||||
'price_input',
|
||||
'price_output',
|
||||
'deployment_mode',
|
||||
'effectiveness_score',
|
||||
'price_score',
|
||||
'speed_score',
|
||||
'total_score',
|
||||
'source_level',
|
||||
'last_verified_at',
|
||||
'status',
|
||||
'is_stale',
|
||||
'stale_note',
|
||||
'alternative_model_id',
|
||||
'seo_title',
|
||||
'seo_description',
|
||||
'h1',
|
||||
'canonical_url',
|
||||
'published_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'price_input' => 'decimal:6',
|
||||
'price_output' => 'decimal:6',
|
||||
'last_verified_at' => 'datetime',
|
||||
'published_at' => 'datetime',
|
||||
'is_stale' => 'boolean',
|
||||
'source_level' => SourceLevel::class,
|
||||
'status' => EntityStatus::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function source(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Source::class);
|
||||
}
|
||||
|
||||
public function alternative(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(self::class, 'alternative_model_id');
|
||||
}
|
||||
|
||||
public function tags(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'entity_tag_maps', 'entity_id', 'tag_id')
|
||||
->wherePivot('entity_type', self::class)
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
68
app/Models/Article.php
Normal file
68
app/Models/Article.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EntityStatus;
|
||||
use App\Enums\SourceLevel;
|
||||
use App\Models\Concerns\HasPublicationScope;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasPublicationScope;
|
||||
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'source_id',
|
||||
'title',
|
||||
'slug',
|
||||
'excerpt',
|
||||
'body',
|
||||
'source_name',
|
||||
'source_url',
|
||||
'source_level',
|
||||
'last_verified_at',
|
||||
'status',
|
||||
'is_stale',
|
||||
'stale_note',
|
||||
'seo_title',
|
||||
'seo_description',
|
||||
'h1',
|
||||
'canonical_url',
|
||||
'published_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'published_at' => 'datetime',
|
||||
'last_verified_at' => 'datetime',
|
||||
'is_stale' => 'boolean',
|
||||
'source_level' => SourceLevel::class,
|
||||
'status' => EntityStatus::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function source(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Source::class);
|
||||
}
|
||||
|
||||
public function tags(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'entity_tag_maps', 'entity_id', 'tag_id')
|
||||
->wherePivot('entity_type', self::class)
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
49
app/Models/Category.php
Normal file
49
app/Models/Category.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'type',
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function tools(): HasMany
|
||||
{
|
||||
return $this->hasMany(Tool::class);
|
||||
}
|
||||
|
||||
public function models(): HasMany
|
||||
{
|
||||
return $this->hasMany(AiModel::class);
|
||||
}
|
||||
|
||||
public function articles(): HasMany
|
||||
{
|
||||
return $this->hasMany(Article::class);
|
||||
}
|
||||
|
||||
public function guides(): HasMany
|
||||
{
|
||||
return $this->hasMany(Guide::class);
|
||||
}
|
||||
}
|
||||
38
app/Models/ChangeLog.php
Normal file
38
app/Models/ChangeLog.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ChangeLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'entity_type',
|
||||
'entity_id',
|
||||
'action',
|
||||
'before_data',
|
||||
'after_data',
|
||||
'changed_by',
|
||||
'changed_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'before_data' => 'array',
|
||||
'after_data' => 'array',
|
||||
'changed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function changedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'changed_by');
|
||||
}
|
||||
}
|
||||
19
app/Models/Concerns/HasPublicationScope.php
Normal file
19
app/Models/Concerns/HasPublicationScope.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
use App\Enums\EntityStatus;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait HasPublicationScope
|
||||
{
|
||||
public function scopePublished(Builder $query): Builder
|
||||
{
|
||||
return $query
|
||||
->where('status', EntityStatus::Published->value)
|
||||
->whereNotNull('published_at')
|
||||
->where('published_at', '<=', now());
|
||||
}
|
||||
}
|
||||
25
app/Models/EntityTagMap.php
Normal file
25
app/Models/EntityTagMap.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class EntityTagMap extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'tag_id',
|
||||
'entity_type',
|
||||
'entity_id',
|
||||
];
|
||||
|
||||
public function tag(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Tag::class);
|
||||
}
|
||||
}
|
||||
53
app/Models/Guide.php
Normal file
53
app/Models/Guide.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EntityStatus;
|
||||
use App\Models\Concerns\HasPublicationScope;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Guide extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasPublicationScope;
|
||||
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'title',
|
||||
'slug',
|
||||
'excerpt',
|
||||
'body',
|
||||
'difficulty',
|
||||
'status',
|
||||
'seo_title',
|
||||
'seo_description',
|
||||
'h1',
|
||||
'canonical_url',
|
||||
'published_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'published_at' => 'datetime',
|
||||
'status' => EntityStatus::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function tags(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'entity_tag_maps', 'entity_id', 'tag_id')
|
||||
->wherePivot('entity_type', self::class)
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
49
app/Models/Source.php
Normal file
49
app/Models/Source.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\SourceLevel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Source extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'domain',
|
||||
'type',
|
||||
'trust_level',
|
||||
'is_whitelisted',
|
||||
'crawl_allowed',
|
||||
'note',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_whitelisted' => 'boolean',
|
||||
'crawl_allowed' => 'boolean',
|
||||
'trust_level' => SourceLevel::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function tools(): HasMany
|
||||
{
|
||||
return $this->hasMany(Tool::class);
|
||||
}
|
||||
|
||||
public function aiModels(): HasMany
|
||||
{
|
||||
return $this->hasMany(AiModel::class);
|
||||
}
|
||||
|
||||
public function articles(): HasMany
|
||||
{
|
||||
return $this->hasMany(Article::class);
|
||||
}
|
||||
}
|
||||
33
app/Models/Tag.php
Normal file
33
app/Models/Tag.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function mappings(): HasMany
|
||||
{
|
||||
return $this->hasMany(EntityTagMap::class);
|
||||
}
|
||||
}
|
||||
79
app/Models/Tool.php
Normal file
79
app/Models/Tool.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EntityStatus;
|
||||
use App\Enums\SourceLevel;
|
||||
use App\Models\Concerns\HasPublicationScope;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Tool extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasPublicationScope;
|
||||
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'source_id',
|
||||
'name',
|
||||
'slug',
|
||||
'summary',
|
||||
'description',
|
||||
'official_url',
|
||||
'logo_url',
|
||||
'pricing_type',
|
||||
'platform',
|
||||
'language',
|
||||
'has_api',
|
||||
'source_level',
|
||||
'last_verified_at',
|
||||
'status',
|
||||
'is_stale',
|
||||
'stale_note',
|
||||
'alternative_tool_id',
|
||||
'seo_title',
|
||||
'seo_description',
|
||||
'h1',
|
||||
'canonical_url',
|
||||
'published_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'has_api' => 'boolean',
|
||||
'is_stale' => 'boolean',
|
||||
'last_verified_at' => 'datetime',
|
||||
'published_at' => 'datetime',
|
||||
'source_level' => SourceLevel::class,
|
||||
'status' => EntityStatus::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function source(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Source::class);
|
||||
}
|
||||
|
||||
public function alternative(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(self::class, 'alternative_tool_id');
|
||||
}
|
||||
|
||||
public function tags(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'entity_tag_maps', 'entity_id', 'tag_id')
|
||||
->wherePivot('entity_type', self::class)
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
48
app/Models/User.php
Normal file
48
app/Models/User.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user