feat(автоподбор): Eloquent-модели run/competitor/source

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-06-28 13:12:35 +03:00
parent 8c96c71280
commit 8c7ed798ba
4 changed files with 178 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class AutopodborCompetitor extends Model
{
public $timestamps = false;
protected $fillable = [
'tenant_id',
'search_run_id',
'name',
'description',
'is_federal',
'relevance_pct',
'origin',
'site_url',
'directory_urls',
'provenance',
'dedup_key',
'study_run_id',
'studied_at',
];
protected $casts = [
'is_federal' => 'bool',
'directory_urls' => 'array',
'provenance' => 'array',
'studied_at' => 'datetime',
'created_at' => 'datetime',
];
public function sources(): HasMany
{
return $this->hasMany(AutopodborSource::class, 'competitor_id');
}
public function searchRun(): BelongsTo
{
return $this->belongsTo(AutopodborRun::class, 'search_run_id');
}
public function studyRun(): BelongsTo
{
return $this->belongsTo(AutopodborRun::class, 'study_run_id');
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class AutopodborRun extends Model
{
public $timestamps = false;
protected $fillable = [
'tenant_id',
'kind',
'status',
'region_code',
'params',
'competitor_id',
'price_rub_charged',
'balance_transaction_id',
'error_code',
'started_at',
'finished_at',
];
protected $casts = [
'params' => 'array',
'price_rub_charged' => 'decimal:2',
'started_at' => 'datetime',
'finished_at' => 'datetime',
'created_at' => 'datetime',
];
public function competitors(): HasMany
{
return $this->hasMany(AutopodborCompetitor::class, 'search_run_id');
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AutopodborSource extends Model
{
public $timestamps = false;
protected $fillable = [
'tenant_id',
'competitor_id',
'study_run_id',
'signal_type',
'identifier',
'phone_kind',
'provenance_url',
'provenance_label',
'dedup_key',
'created_project_id',
];
protected $casts = [
'created_at' => 'datetime',
];
public function competitor(): BelongsTo
{
return $this->belongsTo(AutopodborCompetitor::class, 'competitor_id');
}
public function project(): BelongsTo
{
return $this->belongsTo(Project::class, 'created_project_id');
}
}
@@ -0,0 +1,45 @@
<?php
use App\Models\AutopodborRun;
use App\Models\AutopodborCompetitor;
use App\Models\AutopodborSource;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
uses(DatabaseTransactions::class, \Tests\Concerns\SharesSupplierPdo::class);
it('связывает run → competitors → sources', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = " . $tenant->id);
$run = AutopodborRun::create([
'tenant_id' => $tenant->id,
'kind' => 'search',
'status' => 'done',
'region_code' => 16,
'params' => [],
]);
$comp = AutopodborCompetitor::create([
'tenant_id' => $tenant->id,
'search_run_id' => $run->id,
'name' => 'Окна Комфорт',
'dedup_key' => 'okna-komfort',
'relevance_pct' => 100,
]);
$src = AutopodborSource::create([
'tenant_id' => $tenant->id,
'competitor_id' => $comp->id,
'study_run_id' => $run->id,
'signal_type' => 'site',
'identifier' => 'okna-komfort.ru',
'dedup_key' => 'site:okna-komfort.ru',
]);
expect($comp->sources()->count())->toBe(1)
->and($comp->searchRun->id)->toBe($run->id)
->and($src->competitor->id)->toBe($comp->id)
->and($run->competitors()->count())->toBe(1);
});