Files
portal/app/app/Models/LeadStatus.php
T
Дмитрий e31ea5354a phase2(lead-statuses): GET /api/lead-statuses + Pinia-store с snapshot fallback
Заменяет static-снапшот LEAD_STATUSES в коде на live-данные из БД.
Custom slug'и (добавленные после deployment'а) теперь видны UI без rebuild'а.

Backend:
- LeadStatus model (PK=slug string, incrementing=false, timestamps=null).
- LeadStatusController::index — GET /api/lead-statuses, ORDER BY sort_order,
  slug. Таблица глобальная (не tenant-aware), auth не требуется на MVP.

Pest +5 (LeadStatusesIndexTest):
- 200 + не пустой / все 14 системных slug'ов из seed / все нужные поля /
  sort_order ASC / кастомный slug после INSERT появляется в endpoint'е.

Frontend:
- api/leadStatuses.ts::listLeadStatuses — GET helper.
- stores/leadStatuses.ts::useLeadStatusesStore — Pinia setup-store:
  statuses default = LEAD_STATUSES snapshot (UI работает без fetch'а),
  load(force=false) идемпотентен, bySlug computed Map, findBySlug helper.
  На fail — snapshot остаётся, fetchError=true.
- DealsView/KanbanView/DealDetailDrawer переехали со static-импорта
  LEAD_STATUSES на store. KanbanView использует safe-access
  dealsByStatus[slug] || [] (защита от custom slug'а из API без seeded
  column). load() в onMounted у обоих view'ов.

Vitest +7 (leadStatusesStore.spec.ts):
- initial snapshot / findBySlug existing & null / load success replace +
  loaded / load reject — fetchError + snapshot fallback / load идемпотентен /
  load(force=true) refetch.
- 2 spec'а DealDetailDrawer получили setActivePinia(createPinia()) в
  beforeEach (без этого Pinia store-injection в jsdom падает).

PHPStan baseline регенерирован.

Регресс:
- Lint+type-check+format passed.
- Vitest 280/280 за 19.44 сек (+7 от 273).
- Vite build 1.17 сек.
- Pint + PHPStan passed.
- Pest 210/210 за 24.59 сек (+5 от 205, 840 assertions).

Реестр v1.63→v1.64 / CLAUDE.md v1.54→v1.55.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 08:59:17 +03:00

47 lines
1.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Системный/пользовательский статус воронки.
*
* Глобальная таблица (НЕ tenant-aware) — все тенанты разделяют один список.
* Будущее расширение под tenant-кастомные статусы потребует tenant_id колонку
* + RLS — пока вне scope.
*
* Источник: db/schema.sql v8.7 §3, table `lead_statuses`.
*
* @mixin IdeHelperLeadStatus
*/
class LeadStatus extends Model
{
public $timestamps = false;
protected $primaryKey = 'slug';
public $incrementing = false;
protected $keyType = 'string';
protected $fillable = [
'slug',
'name_ru',
'is_system',
'sort_order',
'color_hex',
'description',
];
protected function casts(): array
{
return [
'is_system' => 'boolean',
'sort_order' => 'integer',
];
}
}