Open Source
web
Ecoshop
Портфолио-e-commerce, собранный так, чтобы реальный эко-магазин мог на нём жить — Laravel 12 API + React 19 SPA с Feature-Sliced Design и Docker-стеком на 7 сервисов
В цифрах
0
Ролей в админке
0
Docker-сервисов
0
Актуальные версии стека
Проблема
Что я решала
Маленькие эко-магазины уходят на Shopify или Tilda, потому что свой настоящий магазин — это два месяца разработки плюс контракт на поддержку. Запуститься получается, но кастомизировать правила цен, многоролевой доступ к админке и тонкую настройку поиска нельзя — они арендуют софт, а не владеют им.
Мой подход
Как я делала
Laravel 12 на бэкенде с чистым сервисным слоем, React 19 SPA на фронте с Feature-Sliced Design, проверенным Steiger-линтером. Три админских роли (админ, менеджер заказов, контент-менеджер), права привязаны на уровне Laravel Policy — контент-менеджер физически не может изменить цены. Meilisearch для полнотекстового поиска справляется с опечатками и кириллицей. Всё живёт в Docker с Nginx, PostgreSQL 17, Redis 7 и Mailpit для теста писем — docker compose up и всё работает.
Выбор технологий
- Laravel 12— Система Policy/Gate даёт пермишены на уровне поля без ручных middleware. Eloquent-скоупы держат multi-role-запросы читаемыми.
- React 19 + FSD— Feature-Sliced Design, проверенный Steiger-линтером, ловит архитектурный дрейф на этапе линта — никто случайно не импортирует логику админки в витрину.
- Meilisearch— Выбрала вместо PostgreSQL full-text за прощение опечаток и фасетный поиск из коробки. Настройка — один docker-compose-сервис, а не выходные тюнинга.
- Docker + Mailpit— docker compose up поднимает весь стек, включая фейковый SMTP. Новые разрабы подключаются за 5 минут, без туннелей и общего стейджинга.
Результат
Что получилось
Нетехнический владелец магазина ведёт его через админку — drag-and-drop категорий, мульти-загрузка изображений, управление заказами. Полнотекстовый поиск с прощением опечаток — клиенты находят товар даже с ошибкой в названии. Три отдельные роли админки держат границы доверия — редактор контента не получает доступ ко всей БД.