Тема
Готовые связки под задачи
Не отдельные пакеты, а проверенные комбинации «библиотеки + подход + грабли» под типовые бизнес-задачи. Каталог одиночных пакетов — в 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.
Как пользоваться этим разделом
- Нашёл задачу → взял связку как список зависимостей и архитектурных решений.
- Прочитал «грабли» — они собраны из реальных инцидентов, не пропускать.
- Отдельные пакеты и альтернативы — в каталоге библиотек, российские сервисы — в ru-specific.