Skip to content

Качество кода — принципы

SOLID в Laravel

  • SRP: Service/Controller/Model — одна ответственность. 300+ строк → разбивай
  • OCP: вместо if ($type === 'x') — стратегии/полиморфизм (Enum с методами, interface + implementations)
  • DI: constructor injection, никогда app() / resolve() внутри методов
  • Один публичный метод = одно действие: OrderService::place(), не OrderService::handle($action)

Типизация

  • declare(strict_types=1) в ВСЕХ PHP-файлах бэкенда
  • Типизация параметров и return — всегда
  • Readonly DTOs (app/DTOs/) для передачи данных между слоями — не ассоциативные массивы
  • PHP 8 constructor property promotion

Явность > магия

  • Нет Model::$with->with() в запросе
  • Нет global scopes, меняющих поведение незаметно (кроме SoftDeletes / MultiTenancy)
  • Нет observer'ов с бизнес-логикой — событие + listener с явным вызовом сервиса
  • Макросы только когда pain-point документирован в ADR

Производительность

  • N+1 — это баг. ->with() / ->withCount() обязательны
  • Filament Listing — EagerLoading в Resource
  • Массовые операции — chunk() или lazy(), не ->get() на таблицах >1000 записей
  • Индексы добавлять ДО релиза, не «когда замедлится»
  • Query log в dev: mcp__laravel-boost__database-query с EXPLAIN

Error handling

  • Никогда try { ... } catch (\Exception $e) { return null; } — логируй или пробрасывай
  • Domain exceptions: OrganizationNotFoundException extends DomainException
  • Handler в bootstrap/app.php — единая точка рендеринга API/HTML ошибок
  • throw_if() / throw_unless() вместо вложенных if

Именование (английский, осмысленный)

ЧтоПравилоПример
МетодыГлаголыpublish(), calculateDistance()
Booleanis*/has*/can*isPublished(), hasAwards()
КоллекцииМножественное$organizations, не $orgs
КонстантыSCREAMING_SNAKE_CASEMAX_RETRY_COUNT

Сокращения — только для локальных переменных внутри замыкания.

Комментарии

  • Объясняй «почему», не «что»
  • TODO/FIXME — только с task-id: // TODO(#112): revert slug после expired paid_until
  • PHPDoc обязателен для: служебных методов (Service, Action), интерфейсов, @return Collection<int, Model>

Восстановление данных (catalog)

При потере данных:

  1. php artisan migrate --forcephp artisan db:seed --force
  2. Восстановить координаты: UPDATE organizations SET address_structured = jsonb_set(jsonb_set(COALESCE(address_structured, '{}')::jsonb, '{lat}', to_jsonb(ST_Y(coordinates))), '{lon}', to_jsonb(ST_X(coordinates))) WHERE coordinates IS NOT NULL
  3. scout:flush + scout:import

Внутренняя база знаний студии