Архитектура модуля feedback

Документ описывает слои, сущности и ключевые классы модуля обратной связи.

1. Структура

modules/feedback/
├── Module.php
├── application/
│   ├── command/         # SubmitRatingCommand, SubmitIdeaCommand
│   ├── dto/             # FeedbackRatingDto, FeedbackIdeaDto, FeedbackStatsDto
│   ├── handler/         # SubmitRatingHandler, SubmitIdeaHandler, GetFeedbackStatsHandler
│   ├── port/            # IFeedbackRatingRepository, IFeedbackIdeaRepository
│   └── query/           # GetFeedbackStatsQuery
├── config/
│   ├── di.php           # репозитории + глобальная подписка RatingSubmittedEvent
│   └── routing.php      # /feedback/rating, /feedback/idea, /feedback/stats
├── domain/
│   ├── entity/          # FeedbackRating, FeedbackIdea
│   ├── event/           # RatingSubmittedEvent, IdeaSubmittedEvent
│   └── valueObject/     # Rating, IdeaType
├── infrastructure/
│   ├── listener/        # SendNonMaxRatingEmailListener, BaseNotificationListener
│   ├── migrations/      # feedback_rating, feedback_idea
│   ├── persistence/     # FeedbackRatingAR, FeedbackIdeaAR
│   └── repository/      # DbFeedbackRatingRepository, DbFeedbackIdeaRepository
└── presentation/
    └── controller/      # FeedbackController

2. Сущности

2.1. FeedbackRating

2.2. FeedbackIdea

3. Value objects

Rating

new Rating(int $value);  // 0..5 иначе InvalidArgumentException
value(): int
isMax(): bool            // value >= 4

⚠️ Обратите внимание: isMax() возвращает true при value >= 4, т.е. оценка 4 тоже считается «максимальной» для целей отправки письма (письмо уходит только при оценке 0–3 хотя бы по одному критерию). Поведение задано в коде.

IdeaType

Разрешённые значения: idea, bug, feature, improvement, question.

4. События

СобытиеКогдаДанные
RatingSubmittedEventОтправлена/обновлена оценкаFeedbackRating
IdeaSubmittedEventОтправлена идеяFeedbackIdea

5. Листенеры

SendNonMaxRatingEmailListener (extends BaseNotificationListener)

BaseNotificationListener (абстрактный)

Шаблон рассылки:

6. Порт и репозитории

ПортРеализация
IFeedbackRatingRepositoryDbFeedbackRatingRepository (upsert по userId)
IFeedbackIdeaRepositoryDbFeedbackIdeaRepository

7. Статистика (GetFeedbackStatsHandler)

FeedbackStatsDto содержит: totalIdeas, maxRatings, implementedIdeas, minRatings, totalUsers, totalTasks (последний — через ITaskStatisticsService ядра).