Skip to content

Готовые связки под задачи

Не отдельные пакеты, а проверенные комбинации «библиотеки + подход + грабли» под типовые бизнес-задачи. Каталог одиночных пакетов — в OSS-библиотеках.

Мультиязычный сайт

Связка: mcamara/laravel-localization (префиксы роутов /ru, /en) + spatie/laravel-translatable (переводы полей в JSON) + laravel-lang/common (переводы UI/валидации).

  • Роуты — через Route::group локализации, hreflang — из того же пакета.
  • Переводимые поля модели держать списком в $translatable, Filament — официальный translatable-плагин с табами локалей.
  • Грабли: поиск по JSON-переводам не индексируется btree — при активном поиске по переводам брать astrotomic/laravel-translatable (отдельные таблицы) с самого начала; перенос с JSON на таблицы посреди проекта — больно.

Полнотекстовый поиск с фасетами

Связка: laravel/scout + Meilisearch (Docker-контейнер) + фасеты Meilisearch.

  • Индексируемое определяется toSearchableArray() — класть только нужное для поиска и фильтров, не всю модель.
  • Синхронизация через очередь (SCOUT_QUEUE=true) — импорт не блокирует запросы.
  • Грабли: после массовых update() в обход Eloquent индекс молча устаревает — завершать импорт командой scout:import; настройки фильтруемых атрибутов задавать миграцией-командой, не руками в дашборде.
  • Когда не нужен: каталог < 10k записей с простыми фильтрами — хватит PostgreSQL (tsvector + GIN, рецепт в спецификации миграций).

Загрузка изображений «как у больших»

Связка: spatie/laravel-medialibrary + conversions в очереди + WebP + responsive images.

  • Конверсии (thumb, card, hero) объявлять в модели; тяжёлые — nonQueued() только для мелких превью.
  • WebP как формат конверсий + loading="lazy" ниже фолда — базовая производительность без CDN.
  • Валидация до сохранения: mimes + max + Rule::dimensions.
  • Грабли: не хранить оригиналы в public диске без нужды; для приватных документов — отдельный диск + временные URL (temporaryUrl).

PDF-документы (счета, КП, договоры)

Связка: spatie/laravel-pdf (Chromium) + Blade-шаблон + очередь.

  • Шаблон — обычный Blade с инлайн-CSS: дизайнеру и разработчику привычно, в отличие от DOMPDF-ограничений.
  • Генерация в джобе, файл — в medialibrary к сущности (заказу/счёту).
  • Грабли: Chromium в Docker-образ добавить заранее (browsershot требует); кириллица — подключить шрифт в шаблоне, не полагаться на системные.
  • Альтернатива без Chromium: barryvdh/laravel-dompdf — когда деплой-простота важнее точности вёрстки.

Заявки с форм → Telegram + админка

Связка: FormRequest + spatie/laravel-honeypot + throttle + модель Lead + Filament-ресурс + notification-channels/telegram (через очередь).

  • Уведомление — Notification с каналами database (история в админке) + telegram (мгновенно менеджеру), обязательно ShouldQueue.
  • Бейдж непрочитанных в Filament — getNavigationBadge() по count новых.
  • Грабли: honeypot не спасает от целевого спама — добавить rate limit по IP и Turnstile на формах с абузом; телефон нормализовать mutator'ом до сохранения.

Роли и права в админке

Связка: spatie/laravel-permission + bezhansalleh/filament-shield + Policy.

  • Shield генерирует permissions по ресурсам Filament и даёт UI управления ролями.
  • Доменные проверки (не UI) — через Policy, они же работают в API.
  • Грабли: кеш прав (permission:cache-reset после сидинга); не проверять роль строкой в коде — только permission (can()), роли меняются.

Отчёты и экспорт для клиента

Связка: pxlrbt/filament-excel (экспорт из таблиц админки) + maatwebsite/excel (кастомные отчёты) + очередь для больших выгрузок.

  • До ~10k строк — синхронно; больше — queue() экспорт с уведомлением о готовности.
  • Грабли: экспорт «всех столбцов» утекает лишними данными — описывать столбцы явно; для выгрузок 100k+ строк — spatie/simple-excel потоково.

Импорт больших данных (прайсы, фиды, ETL)

Связка: spatie/simple-excel (потоковое чтение) + upsert() чанками + джоб-батчи (Bus::batch) + ANALYZE после.

  • Читать потоком, писать upsert() по 500–1000 строк, считать прогресс батчем.
  • Отключать ненужное на время импорта: scout-синхронизацию, observers (осознанно).
  • Грабли: PostgreSQL после массового импорта — устаревшая статистика планировщика (ANALYZE table); параллельные воркеры × work_mem = OOM (см. правило студии про max_parallel_workers_per_gather=1 на время ETL).

«Рядом со мной» — геопоиск

Связка: PostGIS + clickbar/laravel-magellan + гео-индекс GIST.

  • Радиус/полигоны — ST_DWithin по geography-типу, из коробки у magellan.
  • Координаты фронту — из structured-поля, не пересчитывать на лету.
  • Грабли: не мешать SRID; расстояния — geography (метры), не geometry (градусы). MySQL-проекты — matanyadaev/laravel-eloquent-spatial, но сложная геометрия там дороже.

Реалтайм: уведомления, счётчики, чат

Связка: laravel/reverb + laravel-echo + private channels + Notification broadcast.

  • Reverb — first-party, свой сервер не нужен, конфиг из коробки.
  • Уведомления — тот же Notification-класс, добавить broadcast канал.
  • Грабли: авторизация каналов (routes/channels.php) — проверять принадлежность, не полагаться на «непубличность» имени; за Caddy — проксировать websocket-upgrade (отдельный handle на /app).

Подписки и тарифы (РФ)

Связка: своя модель Plan/Subscription + bavix/laravel-wallet (баланс) + ЮKassa рекуррентные платежи + scheduler для продления.

  • Cashier не подходит (Stripe/Paddle в РФ недоступны) — модель подписки своя, но тонкая: план, период, статус, ends_at.
  • Продление — ежедневная schedule-команда: списать с сохранённого метода оплаты, при неудаче — grace period и уведомления.
  • Грабли: хранить историю платежей отдельно от подписки (спор/возврат = факт платежа); вебхуки ЮKassa идемпотентно; тесты на все переходы статусов подписки.

Многошаговые статусы (заказ, заявка, модерация)

Связка: PHP Enum + spatie/laravel-model-states (переходы) + activitylog (история).

  • Правила переходов — в классах состояний, не в if-ах контроллеров.
  • История «кто и когда сменил статус» — activitylog с logOnly(['status']).
  • Грабли: enum-столбец в БД + PHP Enum держать в синхроне (новый статус = миграция); не давать админке «телепортировать» статус мимо переходов — те же правила и для Filament-actions.

SEO-конвейер для контентных проектов

Связка: seo-блоки с шаблонами переменных (по спецификации SEO) + spatie/laravel-sitemap (cron) + spatie/schema-org (JSON-LD) + 301-карта редиректов.

  • Мета: приоритет ручное → шаблон → default из модели; H1 ≠ title.
  • Sitemap — генерация из БД по расписанию + после деплоя.
  • Грабли: тест на sitemap (все URL живые) и RedirectTest на 301-карту — иначе SEO теряется молча при рефакторинге роутов.

Публичный API для мобильного приложения

Связка: laravel/sanctum (токены) + spatie/laravel-data (DTO/ресурсы) + spatie/laravel-query-builder (фильтры) + dedoc/scramble (OpenAPI-дока автогеном).

  • Версионирование через префикс /api/v1 с первого дня — дешевле, чем вводить потом.
  • Scramble генерит доку из типов — мобильщики получают актуальную спеку без ручной поддержки.
  • Грабли: rate limit на все мутирующие endpoint'ы; ошибки — единый JSON-формат через Handler; не отдавать модели напрямую (toArray утекает лишним) — только Data/Resource.

Как пользоваться этим разделом

  1. Нашёл задачу → взял связку как список зависимостей и архитектурных решений.
  2. Прочитал «грабли» — они собраны из реальных инцидентов, не пропускать.
  3. Отдельные пакеты и альтернативы — в каталоге библиотек, российские сервисы — в ru-specific.

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