Skip to content

07Rinat07/inventory-app

Repository files navigation

👤 Автор

Rinat Sarmuldin. email--> ura07srr@gmail.com



Inventory App — Курсовой проект (Symfony 6.4 LTS).

✔ Контроль доступа через Voter ✔ Реляционная БД ✔ Отсутствие логики в UI ✔ Чёткая архитектура ✔ Поддержка расширяемости ✔ Минималистичный интерфейс

В проекте настроено полноценное тестовое окружение Symfony (test environment) с отдельной PostgreSQL базой данных, миграциями и фикстурами. Реализованы functional-тесты безопасности, проверяющие корректную работу firewall и редиректов для неаутентифицированных пользователей. Конфигурация PHPUnit выполняется через phpunit.xml с явным определением DATABASE_URL, что обеспечивает стабильный и воспроизводимый запуск тестов.


1. Общая информация о проекте

Inventory App — учебный курсовой проект, реализующий систему управления инвентарями (реестрами объектов).
Основной акцент сделан на архитектуру backend-приложения, модель данных и контроль доступа, а не на визуальную часть.

Проект реализован с использованием Symfony 6.4 LTS и соответствует требованиям курсовой работы.


2. Цели и задачи проекта

Цель

Реализовать backend-приложение с корректной архитектурой, серверным контролем доступа и расширяемой моделью данных.

Задачи

  • Реализовать управление инвентарями и их элементами
  • Разграничить права доступа пользователей
  • Обеспечить контроль доступа на уровне сервера
  • Поддержать расширяемость (кастомные поля, кастомные ID)
  • Соблюсти требования курсовой работы

3. Используемые технологии

  • PHP 8.2
  • Symfony 6.4 LTS
  • Doctrine ORM
  • PostgreSQL
  • Twig
  • Symfony Security (Voters)

4. Архитектура приложения

Проект построен с чётким разделением ответственности.

Основные слои

Слой

Назначение

Controller

Обработка HTTP-запросов

Entity

Доменная модель

Repository

Работа с БД

DTO

Передача данных

Service

Бизнес-логика

Security / Voter

Контроль доступа

Twig

Отображение данных

Бизнес-логика не размещается в шаблонах и контроллерах.


5. Модель данных

Основные сущности

  • User — пользователь системы
  • Inventory — инвентарь (реестр)
  • InventoryItem — элемент инвентаря
  • InventoryAccess — ACL-права пользователей
  • CustomField — кастомные поля
  • Discussion / Like — обсуждения и лайки

Принципы хранения данных

  • Реляционная модель
  • Нет JSON-хранилищ
  • Нет динамического создания таблиц
  • Используются индексы и UNIQUE-ограничения
  • Связи описаны через Doctrine ORM

6. Пользователи и роли

Типы пользователей

Тип

Описание

Guest

Неавторизованный пользователь

User

Обычный пользователь

Owner

Владелец инвентаря

Admin

Администратор

Демонстрационные аккаунты

Создаются через Doctrine Fixtures.

Администратор

  • Email: admin@test.com
  • Пароль: admin123

Пользователь

  • Email: user@test.com
  • Пароль: user123

7. Контроль доступа (ACL)

Контроль доступа реализован на серверной стороне с использованием Symfony Security Voters.

Проверяемые действия

  • INVENTORY_VIEW
  • INVENTORY_CREATE_ITEM
  • INVENTORY_EDIT_ITEM
  • INVENTORY_DELETE_ITEM
  • INVENTORY_MANAGE_ACCESS
  • DISCUSSION_WRITE

Логика доступа

Условие

Права

Guest + public inventory

Только VIEW

User + чужой inventory

Только VIEW

Owner

Полный доступ

Admin

Полный доступ

InventoryAccess READ

VIEW

InventoryAccess WRITE

CREATE / EDIT / DELETE

Публичность инвентаря не даёт права на изменение данных.


8. Инвентари (Inventory)

Реализовано:

  • Создание инвентарей
  • Просмотр публичных и собственных инвентарей
  • Управление доступом пользователей
  • Привязка к владельцу

Каждый инвентарь содержит:

  • владельца
  • статус публичности
  • элементы
  • кастомные поля

9. Элементы инвентаря (Inventory Items)

Поддерживаются операции:

  • Просмотр
  • Создание
  • Редактирование
  • Удаление

Все действия защищены ACL-проверками через InventoryVoter.


10. Кастомные поля

Реализована архитектурная поддержка кастомных полей:

  • фиксированное количество
  • типизация
  • расширяемость без изменения схемы БД

11. Discussion и Likes

Реализована backend-поддержка:

  • обсуждений
  • лайков
  • серверных ACL-проверок

UI используется только для демонстрации архитектуры.


12. UI-подход

  • Минималистичный интерфейс
  • Нейтральная (серая) цветовая схема
  • Кнопки действий отображаются только при наличии прав
  • В шаблонах отсутствует бизнес-логика

UI не влияет на безопасность — все проверки выполняются на сервере.


📘 Inventory App — установка и тестирование

Данный документ описывает развёртывание проекта, настройку базы данных, а также запуск и назначение всех unit и functional тестов.
Документация подготовлена с учётом требований и не противоречит архитектуре проекта.


1. Требования к окружению

Обязательное ПО

  • PHP 8.2
  • Composer
  • PostgreSQL 15+
  • Git
  • (опционально) Symfony CLI

Проверка версий

php -v
composer -V
psql --version

2. Установка проекта
2.1 Клонирование репозитория
git clone <REPOSITORY_URL>
cd inventory-app
2.2 Установка зависимостей
composer install

3. Настройка базы данных
Проект использует PostgreSQL + Doctrine ORM.
Для тестов используется отдельная test-база, что соответствует best practice и требованиям.
3.1 Создание пользователя и баз данных (один раз)
В PostgreSQL:

CREATE USER inventory_user WITH PASSWORD 'strongpassword';
CREATE DATABASE inventory_app OWNER inventory_user;
CREATE DATABASE inventory_app_test OWNER inventory_user;

3.2 Настройка окружения
.env
DATABASE_URL="postgresql://inventory_user:strongpassword@127.0.0.1:5432/inventory_app?serverVersion=15&charset=utf8"

.env.test
DATABASE_URL="postgresql://inventory_user:strongpassword@127.0.0.1:5432/inventory_app_test?serverVersion=15&charset=utf8"
APP_ENV=test
APP_DEBUG=0

4. Подготовка базы данных
4.1 Применение миграций (dev / prod)
php bin/console doctrine:migrations:migrate
4.2 Применение миграций для тестовой БД
php bin/console doctrine:migrations:migrate --env=test
4.3 Загрузка фикстур (только test)

rm -rf var/cache/test
php bin/console doctrine:fixtures:load --env=test --no-interaction

Фикстуры создают:
admin@test.com / admin123
user@test.com / user123
public inventory (ADMIN)
private inventory (ADMIN)
discussion + likes

⚠️ Фикстуры используются исключительно для тестов и не влияют на production-логику.

5. Запуск тестов
5.1 🔹 Запуск всех тестов одной командой
APP_DEBUG=0 ./vendor/bin/phpunit

5.2 🔹 Только Unit-тесты
APP_DEBUG=0 ./vendor/bin/phpunit tests/Unit --testdox

5.3 🔹 Только Functional-тесты
APP_DEBUG=0 ./vendor/bin/phpunit tests/Functional --testdox

5.4 🔹 Запуск конкретного теста
APP_DEBUG=0 ./vendor/bin/phpunit tests/Unit/Security/InventoryEditOwnerVoterTest.php --testdox

6. Описание тестов =>
6.1 Unit-тесты (Business Logic)
Unit-тесты проверяют чистую бизнес-логику, без HTTP и без базы данных.

🔹 InventoryVoter (ACL)
Проверяемые правила:
Admin — полный доступ
Owner — полный доступ
Guest — только просмотр public inventory
READ — только VIEW
WRITE — items + discussion
MANAGE_ACCESS — только owner / admin

Это ключевая бизнес-логика проекта.
🔹 InventoryEditOwnerVoterTest
Проверяет, что владелец inventory может редактировать его.
🔹 InventoryEditForeignUserVoterTest
Проверяет, что обычный пользователь не может редактировать чужой inventory.
🔹 InventoryEditAdminVoterTest
Проверяет, что admin может редактировать любой inventory.
🔹 InventoryEditWriteAccessVoterTest
Проверяет, что пользователь с WRITE-доступом может редактировать inventory.
🔹 InventoryManageAccessOwnerVoterTest
Проверяет, что только owner может управлять ACL.
🔹 InventoryManageAccessAdminVoterTest
Проверяет, что admin может управлять ACL любого inventory.
🔹 InventoryDiscussion*VoterTest

Проверяется доступ к discussion:
Owner — может писать
Admin — может писать
WRITE — может писать
READ — не может писать
Guest — не может писать

6.2 Functional-тесты (User Scenarios)
Functional-тесты проверяют реальное поведение приложения через HTTP.
🔹 Login / Logout
Пользователь может войти
Пользователь выходит
После logout доступ запрещён
🔹 AccessControlTest
Guest не может зайти в защищённые страницы.
🔹 InventoryOwnerVoterTest
User не может открыть private inventory другого пользователя (403).
🔹 DiscussionGuestTest
Guest не может писать сообщения в discussion через HTTP.

Functional-тесты подтверждают корректную работу unit-логики в реальном приложении, без дублирования бизнес-правил.

Start and CHECK ALL Tests

  • APP_ENV=test php bin/console cache:clear
    && APP_ENV=test php bin/console doctrine:schema:validate
    && APP_ENV=test ./vendor/bin/phpunit

Unit tests

Located in tests/Unit. They validate isolated business logic and security rules without HTTP layer. Run:

  • php bin/phpunit tests/Unit

Functional tests

(Functional-тест проверяет поведение приложения через HTTP: маршруты, контроллеры и систему безопасности, как при реальном использовании).

Located in tests/Functional. They test application behavior via real HTTP requests, including routing, controllers and security.

Run:

  • php bin/phpunit tests/Functional

Run all tests

  • php bin/phpunit

for WINDOWS 10-11

📦 1. Install and Start PostgreSQL 16

OSPanel module setup

  • Enable PostgreSQL-16 module in OSPanel.
  • Start the module and check logs (logs/postgresql.log) if it fails.

Manual start (fallback)

cd C:OSPanelmodulesdatabasesPostgreSQL-16bin
pg_ctl -D "C:OSPanelmodulesdatabasesPostgreSQL-16data" start

Verify listening port

* netstat -ano | findstr 5432

Expected: LISTENING on 127.0.0.1:5432 or 127.0.1.x:5432.

⚙️ 2. Configure PostgreSQL Network Access

postgresql.conf

listen_addresses = '*'
port = 5432

pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

Restart PostgreSQL after changes.

🐘 3. Enable PHP PostgreSQL Extensions (PHP 8.2)

Edit php.ini for CLI (used by bin/console):

Path example:

C:OSPanelmodulesphpPHP-8.2php.ini

Enable:

extension=pdo_pgsql
extension=pgsql

Restart OSPanel and verify:

php -m | findstr pgsql

Expected: pdo_pgsql, pgsql.

🗄️ 4. Create Database and User, Grant Permissions

Connect as superuser:

cd C:OSPanelmodulesdatabasesPostgreSQL-16bin
psql -U postgres -h 127.0.0.1 -p 5432

SQL commands:

CREATE USER inventory_test WITH PASSWORD 'strongpassword';
CREATE DATABASE inventory_app_test OWNER inventory_test;

GRANT USAGE ON SCHEMA public TO inventory_test;
GRANT CREATE ON SCHEMA public TO inventory_test;

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO inventory_test;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO inventory_test;

ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO inventory_test;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO inventory_test;

🔗 5. Symfony and Doctrine Configuration

.env.test

APP_ENV=test
APP_DEBUG=0
DATABASE_URL="pgsql://inventory_test:strongpassword@127.0.0.1:5432/inventory_app_test?serverVersion=16&charset=utf8"

config/packages/doctrine.yaml

doctrine:
  dbal:
    driver: pdo_pgsql
    url: '%env(resolve:DATABASE_URL)%'
    profiling_collect_backtrace: '%kernel.debug%'
    use_savepoints: true

  orm:
    auto_generate_proxy_classes: true
    enable_lazy_ghost_objects: true
    report_fields_where_declared: true
    validate_xml_mapping: true
    naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
    auto_mapping: true
    mappings:
      App:
        type: attribute
        is_bundle: false
        dir: '%kernel.project_dir%/src/Entity'
        prefix: 'AppEntity'
        alias: App

when@test:
  doctrine:
    dbal:
      dbname_suffix: ''

🧪 6. PHPUnit Configuration

phpunit.xml.dist

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true">
    <php>
        <env name="KERNEL_CLASS" value="AppKernel"/>
        <env name="APP_ENV" value="test"/>
        <env name="APP_DEBUG" value="0"/>
    </php>
</phpunit>

▶️ 7. Run Migrations and Tests (Windows)

Set environment variables

CMD:

set APP_ENV=test
php bin/console cache:clear

PowerShell:

$env:APP_ENV="test"
php bin/console cache:clear

Database setup

php bin/console doctrine:database:create --env=test
php bin/console doctrine:migrations:migrate --env=test

Run tests

php bin/phpunit
php bin/phpunit tests/Unit

🛠️ 8. Troubleshooting

could not find driver → Enable pdo_pgsql and pgsql in php.ini.

connection refused → PostgreSQL not running or listening on different IP. Fix listen_addresses and pg_hba.conf.

permission denied for schema public → Grant schema rights to inventory_test.

You must set the KERNEL_CLASS → Add <env name="KERNEL_CLASS" value="AppKernel"/> in phpunit.xml.dist.

✅ 9. Final Checklist

PostgreSQL running and listening on port 5432.

PHP extensions pdo_pgsql and pgsql enabled.

Database inventory_app_test created, user inventory_test has full rights.

Doctrine configured with pdo_pgsql driver.

PHPUnit configured with KERNEL_CLASS and test env.

Commands run successfully with APP_ENV=test.

About

The project is an educational coursework, but there will be integrations in the future. https://drive.google.com/file/d/1hdRwiOMtmiU_UVepNB15ZMWNpKjKjvHw/view?usp=sharing

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors