Автор курсового проекта: Rinat Sarmuldin Email: ura07srr@gmail.com
This project was developed as part of my participation in the Commercial Software Development – PHP training program by iTransition (remote, 2026).
- Учебный проект на Symfony 6.4 и PostgreSQL.
- Фокус на архитектуре, безопасности и тестируемости.
- Публичные/приватные инвентари, ACL-доступ, кастомные поля и генерация идентификаторов.
- Иерархия: инвентарь → группы → товары/позиции.
- Ключевые сценарии доступа покрыты тестами.
- Публичные инвентари в фикстурах получают реальные фото-иллюстрации.
- Источник placeholder-изображений: loremflickr.com (замените на свои в продакшене).
- Файлы лежат в
public/images/public-inventories/. - Привязка идет по названию инвентаря в
templates/home/index.html.twig.
- Регистрация и аутентификация пользователей
- Ролевая модель (
ROLE_ADMIN,ROLE_USER) - Защита доступа через Symfony Security + Voter
- CSRF-защита для деструктивных операций
- Проверки на IDOR и подмену параметров
- Публичная главная страница с входом/регистрацией
- Профиль пользователя с ограничением доступа owner/admin
- Управление инвентарями (создание, редактирование, просмотр, удаление)
- Публичные и приватные инвентари
- ACL-доступ (READ / WRITE)
- Поиск и фильтрация инвентарей
- Пагинация и сортировка
- Группы товаров внутри инвентаря (CRUD)
- Разные типы данных (текст, число, дата, выбор, чекбокс)
- Динамическая генерация форм
- Изменение порядка полей
- Обязательные и необязательные поля
- Создание, редактирование, удаление товаров
- Перемещение товаров между группами
- Генерация кастомных идентификаторов
- Заполнение значений кастомных полей
- Уникальность ID в рамках инвентаря
- CRUD для инвентарей и предметов
- API Platform (JSON-LD, Swagger UI)
- Фильтрация и сортировка
- Пагинация
- Защита через ACL
Swagger UI: http://localhost:8090/api/docs OpenAPI JSON: http://localhost:8090/api/docs.json OpenAPI JSON (альтернатива): http://localhost:8090/api/docs.jsonopenapi
Эндпоинты для проверки:
GET /api/health— проверка доступности APIGET /api— документация API Platform (HTML)
Архитектура ориентирована на разделение ответственности и тестируемость:
- Controller / API Resource — HTTP-слой (Web и REST).
- State Processor — обработка состояний сущностей в API.
- Service — бизнес-логика.
- Domain — доменные правила, value object'ы, enum'ы, политики.
- Repository — работа с БД через Doctrine ORM.
- Entity — ORM-сущности с метаданными API Platform.
- DTO — объекты передачи данных между слоями.
- Security / Voter — контроль доступа (ACL).
- Docker + Docker Compose.
- PHP 8.2+ и расширения:
php-ctype,php-iconv,php-xml,php-pgsql,php-mbstring,php-intl. - Composer.
- PostgreSQL 16.
- Клонирование репозитория:
git clone git@gitlab.com:07Rinat07/inventory-platform.git
cd inventory-platform- Запуск контейнеров (dev, включая базу данных):
docker compose -f compose.yaml -f compose.dev.yaml up -d --buildDev-окружение поднимает фикстуры автоматически (LOAD_FIXTURES=1 в compose.dev.yaml).
Пересборка (если менялись Dockerfile/зависимости/ENV):
# обычная пересборка
docker compose -f compose.yaml -f compose.dev.yaml up -d --build
# чистая пересборка (удалит контейнеры и тома)
docker compose -f compose.yaml -f compose.dev.yaml down -v
docker compose -f compose.yaml -f compose.dev.yaml up -d --build
# пересборка только app/worker
docker compose -f compose.yaml -f compose.dev.yaml build app worker
docker compose -f compose.yaml -f compose.dev.yaml up -dДля продакшена/хостинга задайте переменные окружения (через панель хостинга или .env.local):
APP_ENV=prodAPP_DEBUG=0APP_SECRET=...DATABASE_URL=...MAILER_DSN=...
Продакшен-стек через Docker Compose:
docker compose -f compose.yaml -f compose.prod.yaml up -d --buildПосле первого запуска выполните миграции вручную:
docker compose -f compose.yaml -f compose.prod.yaml exec -T app php bin/console doctrine:migrations:migrate --no-interactionЕсли используете внешнюю базу, запустите только app/worker и укажите DATABASE_URL:
docker compose -f compose.yaml up -d --build- Доступ к приложению:
- Web: http://localhost:8090/
- API (Swagger): http://localhost:8090/api
- Mailer (Mailpit): http://localhost:8025/
- Выполнение команд Symfony (dev):
docker compose -f compose.yaml -f compose.dev.yaml exec -T app php bin/console ...- Запуск тестов:
docker compose -f compose.yaml -f compose.dev.yaml exec -T app php bin/phpunit --configuration phpunit.dist.xmlЛокально (без Docker):
php bin/phpunit --configuration phpunit.dist.xml- Загрузка тестовых данных (фикстуры) при необходимости:
docker compose -f compose.yaml -f compose.dev.yaml exec -T app php bin/console doctrine:fixtures:load --no-interaction
docker compose -f compose.yaml -f compose.dev.yaml exec -T app php bin/console doctrine:fixtures:load --no-interaction --env=test- Проверка статуса контейнеров и healthcheck:
docker compose -f compose.yaml -f compose.prod.yaml psЕсли контейнер app unhealthy, обычно причина — права на var/ и public/bundles.
Исправить можно так:
docker compose -f compose.yaml -f compose.prod.yaml exec -T app sh -lc "mkdir -p var/cache/prod var/cache/dev var/log public/bundles && chown -R www-data:www-data var public/bundles && chmod -R 777 var public/bundles"После этого перезапустите контейнер:
docker compose -f compose.yaml -f compose.prod.yaml restart app- Отчет о покрытии (dev, через PCOV):
docker compose -f compose.yaml -f compose.dev.yaml exec -T app sh -lc "scripts/coverage.sh"Отчет будет в var/coverage/clover.xml.
- Пересборка картинок/фронта (если менялись ассеты):
docker compose -f compose.yaml -f compose.dev.yaml exec -T app php bin/console assets:install public --no-interaction- Установка зависимостей:
sudo apt update
sudo apt install -y php8.2 php8.2-cli php8.2-common php8.2-pgsql php8.2-xml php8.2-mbstring php8.2-curl php8.2-intl php8.2-zip
sudo apt install -y postgresql-16
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer- Установка зависимостей проекта:
composer install- Создание пользователя в PostgreSQL:
sudo -u postgres psql -c "CREATE USER inventory_user WITH PASSWORD 'inventory_pass';"
sudo -u postgres psql -c "ALTER USER inventory_user CREATEDB;"- Настройка подключения:
Создайте .env.local и .env.test.local:
DATABASE_URL="pgsql://inventory_user:inventory_pass@127.0.0.1:5432/inventory_app?serverVersion=16"- Инициализация базы данных:
php bin/console doctrine:database:create --if-not-exists
php bin/console doctrine:migrations:migrate --no-interaction
php bin/console doctrine:fixtures:load --no-interaction
php bin/console doctrine:database:create --env=test --if-not-exists
php bin/console doctrine:migrations:migrate --env=test --no-interaction
php bin/console doctrine:fixtures:load --env=test --no-interaction- Запуск сервера:
php -S localhost:8000 -t public- Проверка:
- Swagger UI: http://localhost:8000/api при запуске через Docker.
- Форматы:
application/ld+json,application/json.
Примеры эндпоинтов:
GET /api/inventories— список инвентарей.POST /api/inventories— создание инвентаря.GET /api/inventories/{id}/items— предметы инвентаря.POST /api/inventories/{id}/custom-fields/reorder— изменение порядка полей.
Проект содержит Unit, Integration и Functional тесты (включая API).
- ✅ Авторизация и аутентификация
- ✅ Права доступа и безопасность
- ✅ CRUD операции
- ✅ API endpoints
- ✅ Пагинация
- ✅ Поиск и фильтрация
- ✅ Валидация данных
- ✅ ACL-доступ
docker compose -f compose.yaml -f compose.dev.yaml exec -T app sh -lc "scripts/coverage.sh"Проект включает интеграцию с Salesforce для управления взаимоотношениями с клиентами (CRM).
-
Создайте Salesforce Developer Account:
- Перейдите на https://developer.salesforce.com/signup
- Зарегистрируйте бесплатный Developer org
-
Создайте Connected App в Salesforce:
- Setup → Apps → App Manager → New Connected App
- Заполните основную информацию
- Enable OAuth Settings: Yes
- Callback URL:
https://login.salesforce.com/services/oauth2/callback - Selected OAuth Scopes:
Full access (full),Perform requests on your behalf at any time (refresh_token, offline_access) - Сохраните и получите Consumer Key и Consumer Secret
-
Получите Security Token:
- Settings → Reset My Security Token
- Токен придет на email
-
Настройте переменные окружения:
Добавьте в .env.local или настройте через переменные окружения Docker:
# Salesforce Configuration
SALESFORCE_CONSUMER_KEY=your_consumer_key_here
SALESFORCE_CONSUMER_SECRET=your_consumer_secret_here
SALESFORCE_USERNAME=your_salesforce_username@example.com
SALESFORCE_PASSWORD=your_salesforce_password
SALESFORCE_SECURITY_TOKEN=your_security_tokenПример с вашими данными:
SALESFORCE_CONSUMER_KEY=your_consumer_key_here
SALESFORCE_CONSUMER_SECRET=your_consumer_secret_here
SALESFORCE_USERNAME=your_email@example.com
SALESFORCE_PASSWORD=your_password
SALESFORCE_SECURITY_TOKEN=your_token_from_email- Настройте сервис в
config/services.yaml:
services:
App\Service\Salesforce\SalesforceService:
arguments:
$consumerKey: '%env(SALESFORCE_CONSUMER_KEY)%'
$consumerSecret: '%env(SALESFORCE_CONSUMER_SECRET)%'
$username: '%env(SALESFORCE_USERNAME)%'
$password: '%env(SALESFORCE_PASSWORD)%'
$securityToken: '%env(SALESFORCE_SECURITY_TOKEN)%'- Войдите в систему как пользователь
- Перейдите в свой профиль
- Нажмите кнопку "Send to Salesforce"
- Заполните форму с информацией о компании и контакте
- После отправки в Salesforce будут созданы:
- Account — запись о компании
- Contact — контакт, привязанный к Account
После успешной отправки:
- Войдите в Salesforce Developer org
- Перейдите в раздел Accounts или Contacts
- Найдите созданные записи по имени компании или email
- SalesforceService — сервис для работы с Salesforce REST API
- SalesforceAccountDto — DTO для данных Account
- SalesforceContactDto — DTO для данных Contact
- SalesforceIntegrationFormType — форма для сбора данных
- SalesforceException — исключение для ошибок интеграции
Интеграция использует Username-Password Flow для аутентификации:
- Автоматическое получение access token
- Безопасное хранение credentials в переменных окружения
- Логирование всех операций
- Symfony Security + Voter.
- Проверки на IDOR и подмену параметров.
- CSRF-защита для деструктивных операций.
- admin@test.com / admin12345 — ROLE_ADMIN (полный доступ)
- user@test.com / user12345 — ROLE_USER (доступ к своим и публичным инвентарям)
- Данные нормализованы, без JSON-хранения.
- Динамическое создание таблиц не используется.
- Используются явные связи и индексы.
✅ Проект готов к работе и тестированию
- ✅ Полная система аутентификации и авторизации
- ✅ Управление инвентарями (CRUD)
- ✅ Публичные и приватные инвентари
- ✅ ACL-доступ (READ / WRITE)
- ✅ Группы товаров внутри инвентарей
- ✅ Кастомные поля с разными типами данных
- ✅ Генерация кастомных идентификаторов
- ✅ REST API на базе API Platform
- ✅ Пагинация и сортировка
- ✅ Покрытие ключевых сценариев тестами
- ✅ Защита от CSRF и IDOR
- ✅ Валидация данных
- Backend: Symfony 6.4, PHP 8.2+
- База данных: PostgreSQL 16
- ORM: Doctrine ORM
- API: API Platform (JSON-LD, Swagger UI)
- Тестирование: PHPUnit
- Контейнеризация: Docker + Docker Compose
