Недоработки, известные проблемы и план развития
Этот документ фиксирует текущее состояние системы: известные недоработки, некритичные баги и планируемые улучшения. Цель — прозрачность для команды и приоритизация работы. Документ следует обновлять при изменениях.
1. Окружение и запуск
1.1. config/redis.php отсутствует, но требуется в config/console.php
- Где:
config/console.phpстрока 8 —require __DIR__ . '/redis.php', а также компонентыredisиyii\redis\Cache. - Проблема: файла
config/redis.phpнет в репозитории. Консольное приложение (php yii) падает с ошибкой «include file not found» при старте, если файл не создать вручную. - Затрагивает: консольные команды (миграции, cron, email-send).
- Рекомендация: добавить
config/redis.php(обёртка над$_ENV['REDIS_HOST'|'REDIS_PORT'|'REDIS_PASSWORD']) или убрать его подключение изconsole.php. Такжеyii\redis\Cacheтребует расширениеyii2-redis, которого нет вcomposer.json(в зависимостях толькоext-redis).
1.2. .env.example не полностью соответствует фактическим переменным
- В
.env.exampleестьPASSPORT_SCOPES, но в коде scopes берутся изmodules/passport/auth/config/params.php(жёстко заданный массив), а не из.env.
2. Реальный код vs документация шаблона
- Папка
docs/script-yii-template/описывает шаблон, а не текущий проект. Часть описанного (например,config/ignore_routes.php, JWT-компоненты,core/infrastructure/http/,core/infrastructure/listener/в ядре) в проекте отсутствует. Поддерживать шаблонную документацию как «актуальную для проекта» нельзя.
3. Архитектурные недоработки
3.1. Класс modules\projects\domain\event\IEventDispatcher дублирует core\application\port\IEventDispatcher
- В
modules/projects/domain/event/иmodules/tasks/domain/event/объявлены локальные интерфейсыIEventDispatcher. Это «свои» порты на уровне модулей, но они дублируют имя из ядра. Риск путаницы при импортах (в коде используются алиасыuse ... as GlobalEventDispatcher). Стоит унифицировать (использовать один порт ядра) или явно задокументировать назначение.
3.2. NotificationHub::send() не бросает ошибки
- Ошибки отправки уведомлений логируются (
Yii::error) и «глотаются» — вызывающий код не узнает о сбое. Для критичных уведомлений (приглашения) желательно вернуть статус/бросить исключение или добавить очередь (см. п. 5).
3.3. Каналы уведомлений: только Email реально используется
PushChannel(Redis) иTelegramChannelобъявлены в DI, но в коде реально используется только email (SendInvitationEmailListener,SendNonMaxRatingEmailListener). SMS-канал (SmsChannel) существует вcore/application/notification/channel/, но не зарегистрирован вNotificationHub(там только email/telegram/push). Это каркас для будущего.
3.4. UserFirstLoginEvent диспатчится, но глобальных слушателей по умолчанию нет
- Событие генерируется в
SyncUserHandler(при первом входе). Подписка — только из модуля projects (CreatePersonalProjectOnUserFirstLoginвconfig/di.phpпроектов). Если модуль projects отключён — событие «повиснет». Нормально для текущей архитектуры, но стоит держать в уме.
4. Известные некритичные баги и «запахи» кода
4.1. modules\projects\presentation\controller\InvitationController::actionCancel
- Параметр
emailзадан в#[OA\Parameter(in: 'path')], а фактически читается из query:Yii::$app->request->get('email')(маршрутDELETE project/<id>/invitation— без<email>в пути). Swagger-документация вводит в заблуждение.
4.2. Смешение стилей ответов ошибочных статусов
- Часть контроллеров возвращает
ErrorDtoсо статусом 200 (например,actionInviteвозвращает$this->error(...)как обычный ответ), часть — бросаетHttpException(получаем реальный HTTP-код). Фронтенду стоит проверять структуруerrorдаже при HTTP 200. Рекомендация: унифицировать — возвращать реальные HTTP-коды через исключения.
4.3. console.php требует Mailer в dsn-комментарии
- Закомментирован
dsnв mailer; используется схема из отдельных переменных. Не баг, но мусорный код стоит почистить.
4.4. BaseController::loadMultipartModel
- Логика предназначена для multipart, но используется и для JSON. Работает, но это «серая зона»: для JSON-тела модели грузятся через
load(Yii::$app->request->post(), '')в контроллерах, а не черезloadMultipartModel. Стоит унифицировать загрузку данных.
4.5. Тесты — заготовки из шаблона
- В
tests/лежат тесты из шаблона Yii2 (ContactFormCest,LoginFormCest,AboutCest, моделиContactFormTest,LoginFormTest), не относящиеся к TASKFLOW. Реальных тестов доменов/модулей нет. Приоритет: написать тесты на CQRS-хендлеры и DTO.
4.6. Отсутствие mail/ директории
- В
config/web.phpиconsole.phpуказан'viewPath' => '@app/mail', но папкиmail/в репозитории нет. Если уведомления используют шаблоны писем — их пока нет (письма формируются в коде, см.SendInvitationEmailListener,SendNonMaxRatingEmailListener). При добавлении шаблонных писем нужно создать папку.
5. План развития (Roadmap)
5.1. Вынести статистику в отдельный модуль / сервисы
- Сейчас
TaskStatisticsServiceживёт внутриmodules/tasks/application/service/и реализует порт ядраITaskStatisticsService. Задачи модуля tasks — «управление задачами», статистика — кросс-модульная аналитика. - План: выделить
modules/analytics(илиmodules/stats), перенести тудаTaskStatisticsService, busy-chart, суммы времени; продумать порты ядра для агрегации.
5.2. Локальный RBAC в проектах
- Сейчас права внутри проектов (
IProjectAccess/ProjectAccess, роли участников) — отдельная механика, не связанная с глобальным RBAC. - План: ввести локальные роли/разрешения участников проекта, проверяемые через
AuthorizationService(или отдельныйProjectAuthorization), с поддержкойmode=self-or-anyна уровне ресурсов проекта; единая модель прав для задач/досок.
5.3. Модуль статистики по времени и занятости
- Сейчас busy-chart (
GetUserBusyChartQuery) и daily-summary реализованы для одного пользователя. План: агрегаты по команде/проекту, отчёты за период, экспорт.
5.4. Файловое хранилище
- В README заявлено «файловое хранилище», но реализация отсутствует (нет модуля/инфраструктуры загрузки файлов). План: модуль
files(загрузка через multipart, хранение, раздача, права на файлы привязанные к задачам).
5.5. Донастройка Push/Telegram-каналов
PushChannelготов (Redis), но нет потребителя шины push-событий;TelegramChannel— заглушка. План: настроить реальные доставки, добавить вNotificationHubSMS, управление подписками пользователя на каналы.
5.6. Очереди и асинхронность
- Отправка писем синхронная (в обработке запроса). План: очередь на Redis (заготовка
commands/EmailSendCommand.phpуже есть), вынос уведомлений и событий в фоновые обработчики.
5.7. Обратная связь: доп. метрики и модерация идей
- Идеи (
FeedbackIdea) сейчас только создаются/читаются. План: статусы идей (new/planned/done), голосование, привязка к задачам.
5.8. XSS/CSRF и безопасность cookie
- Cookies имеют
httpOnly,secure,SameSite=LAX— хорошо. План: ревизия CORS-заголовков (сейчас только каркас OPTIONS), защита от CSRF для не-безопасных методов, rate-limiting на/auth/*и/feedback/*.
5.9. Улучшение тестов и CI
- Добавить PHPStan level 6 в CI, тесты на модули, прогон миграций в CI (сейчас только
composer validate+composer install+ окружение).
5.10. Документация: генерация схем БД
- Привести
docs/в соответствие с кодом после каждого крупного изменения (чек-лист вdeveloper-guide.md).
6. Как обновлять этот документ
- Новую недоработку/баг — добавлять с указанием «Где» (файл/класс) и «Затрагивает».
- При фиксе — переносить пункт в раздел «Решено» (создать при необходимости) или удалять.
- Roadmap-пункты — дополнять связью с существующими модулями и портами ядра.