Ревизия исходного плана после повторной сверки с кодом. Этот документ оставляет в основном roadmap только подтвержденные и исполнимые задачи. Спорные микро-cleanup, product backlog и крупные redesign-задачи вынесены ниже отдельно.
Дата ревизии: 2026-04-03
- Этот план предназначен для последующей пошаговой реализации без расширения scope.
- В main roadmap входят только реальные дефекты, contract mismatch, hardening и архитектурные нарушения, подтвержденные по коду.
- Массовые stylistic cleanup и product-функции не должны смешиваться с первыми фазами.
- Если задача меняет auth-модель, WebSocket security-модель или контракт Laravel ↔ Python, её нужно реализовывать отдельным осознанным пакетом, а не "по пути".
Ниже перечислены правки относительно первой версии REFACTOR_PLAN.md.
-
Пункт про отсутствие канала
private:activity-logубран из критических багов. Реальный код используетaccount-activity.{accountId}иactivity-global.{userId}:backend-laravel/app/Events/ActivityLogCreated.phpbackend-laravel/routes/channels.phpfrontend-vue/src/features/activity-live/lib/useActivityLive.tsfrontend-vue/src/features/activity-live/lib/useGlobalActivityLive.tsЭто не backend-баг, а drift документации вCLAUDE.md.
-
Пункт про
python-service/helpers.pyсraw["replied_to_comment_id"]понижен до optional cleanup. Текущее выражение защищено черезraw.get(...)в условии и не является подтвержденным crash bug. -
Поломанный фасад
InstagramClientоставлен в плане, но понижен с critical до low-value cleanup. В проекте нет реальных вызововInstagramClient::..., то есть проблема есть в коде, но не ломает текущий поток. -
Пункт про auto-cleanup в
useCommentGenerationпонижен. Сам composable не делаетonBeforeUnmount, но текущий основной consumer уже вызываетcleanup():frontend-vue/src/features/post-detail/ui/PostDetailModal.vue:98frontend-vue/src/features/post-detail/ui/PostDetailModal.vue:105
-
findOrFailвActivityLogControllerбольше не описывается как гарантированный HTML-ответ. Правильная формулировка: контроллер сейчас полагается на framework-level rendering и не гарантирует единый project envelope для not-found. -
Пункт про WebSocket TLS уточнен. Токен сейчас уходит через
authEndpoint, а не внутри самого ws payload:frontend-vue/src/shared/lib/echo.tsПроблема все равно остается: схема, TLS, transport и env-параметры захардкожены не для production.
-
Путь к composable исправлен:
- правильно:
frontend-vue/src/features/generate-comment/lib/useCommentGeneration.ts - не
model/useCommentGeneration.ts
- правильно:
-
Подсчеты по frontend подтверждены повторно:
.then((response) => response.data)—36вхождений...(x ? { x } : {})—16вхождений
- В security-пункт про token storage добавлен
frontend-vue/src/router/index.ts, где guard тоже зависит отlocalStorage. - В frontend public API cleanup добавлены прямые импорты UI-файлов:
frontend-vue/src/pages/feed/ui/FeedPage.vuefrontend-vue/src/pages/search/ui/SearchPage.vuefrontend-vue/src/pages/login/ui/LoginPage.vuefrontend-vue/src/layouts/MainLayout.vue
- Для Docker hardening уточнено, что
.dockerignoreнужен именно вpython-service/, потому что build context вdocker-compose.ymlзадан как./python-service.
В этом разделе остаются только задачи, которые имеет смысл отдавать следующему агенту как основной рабочий список.
Это задачи, которые реально влияют на корректность, безопасность контракта или стабильность текущего приложения.
Сейчас любой авторизованный пользователь может подписаться на чужой job:
backend-laravel/routes/channels.php:12
Задача:
- убрать
return true - ввести реальную модель владения job
- выбрать безопасный способ авторизации канала
Важно:
- не фиксировать решение заранее только через БД, потому что
jobIdсейчас не хранится как сущность - допустимы варианты через отдельное хранилище ownership, signed token, transient mapping или другой явный механизм
Затронутые файлы:
backend-laravel/routes/channels.phpbackend-laravel/app/Http/Controllers/CommentGenerateController.phpbackend-laravel/app/Events/CommentGenerationProgress.phpfrontend-vue/src/features/generate-comment/lib/useCommentGeneration.ts
Поле proxy существует в данных аккаунта, но фактически нигде не проходит через Laravel → Python → instagrapi.
Что подтверждено:
- в Python login-схеме proxy отсутствует:
python-service/schemas.py - в Python login-flow proxy не применяется:
python-service/main.py - при восстановлении клиента proxy не применяется:
python-service/client.py - в Laravel login-flow proxy тоже не участвует:
backend-laravel/app/Http/Controllers/InstagramAccountController.php
Задача:
- определить единый контракт proxy для добавления аккаунта
- валидировать proxy на Laravel-стороне
- передавать proxy в Python
- применять proxy до логина и до использования session-based клиента
Затронутые файлы:
backend-laravel/app/Http/Controllers/InstagramAccountController.phpbackend-laravel/app/Services/InstagramClientService.phppython-service/schemas.pypython-service/main.pypython-service/client.py
Сейчас ActivityLogController использует findOrFail():
backend-laravel/app/Http/Controllers/ActivityLogController.php:18backend-laravel/app/Http/Controllers/ActivityLogController.php:53
Проблема не в самом findOrFail, а в том, что error-flow зависит от framework default rendering, а не от project-level API envelope.
Задача:
- гарантировать стабильный JSON-ответ для not-found и аналогичных ошибок
- не допускать выхода из стандартного формата
success/error/message
Допустимые пути:
- локально в контроллере
- либо через централизованный exception rendering
Затронутые файлы:
backend-laravel/app/Http/Controllers/ActivityLogController.php- опционально
backend-laravel/bootstrap/app.php
Во frontend уже включен history mode:
frontend-vue/quasar.config.ts:51
Но axios редиректит на hash-route:
frontend-vue/src/boot/axios.ts:25
Задача:
- убрать хардкод
/#/login - привести поведение
axiosinterceptor и router guard к одной схеме
Затронутые файлы:
frontend-vue/src/boot/axios.tsfrontend-vue/src/router/index.ts
Что подтверждено:
forceTLS: falseзахардкожен:frontend-vue/src/shared/lib/echo.ts:17- transport захардкожен в
['ws']:frontend-vue/src/shared/lib/echo.ts:18 VITE_REVERB_SCHEMEесть в.env, но не используется:frontend-vue/.envVITE_REVERB_SCHEMEне типизирован:frontend-vue/src/env.d.ts- Reverb-переменные отсутствуют в
frontend-vue/.env.example
Задача:
- вынести scheme/TLS/transport в env-driven конфиг
- не ломать local dev
- сделать production-ready путь для
wss
Затронутые файлы:
frontend-vue/src/shared/lib/echo.tsfrontend-vue/src/env.d.tsfrontend-vue/.env.example
Подтверждено, что метод строит статистику через серию отдельных запросов:
backend-laravel/app/Repositories/ActivityLogRepository.php:92
Задача:
- сократить число SQL-запросов без изменения внешнего ответа
- сохранить текущую shape-структуру stats payload
Затронутые файлы:
backend-laravel/app/Repositories/ActivityLogRepository.php
Drift уже мешает ревью и следующей автоматизации.
Что точно не совпадает:
- каналы activity events
- структура
device_profiles - структура
account_activity_logs - поля
instagram_accountsвокруг device profile/device model
Затронутые файлы:
CLAUDE.md
Сейчас Python image собирается из контекста ./python-service:
docker-compose.yml:49
При отсутствии .dockerignore в образ попадает лишнее, включая venv/.
Задача:
- добавить минимальный
.dockerignoreдля Python build context
Затронутые файлы:
python-service/.dockerignore
Это задачи, которые желательно выполнить в той же волне, но только после Must Fix.
Подтвержденное нарушение слоя:
frontend-vue/src/shared/ui/media-card/MediaCard.vuefrontend-vue/src/shared/ui/media-display/MediaDisplay.vuefrontend-vue/src/shared/ui/media-display/useMediaStyle.ts
Допустимы два пути:
- перенести media-specific UI в
entities/media-post/ui/ - либо опустить используемые типы/константы ниже, если компонент действительно должен остаться
shared
Предпочтительный путь для текущего проекта:
- перенос в
entities/media-post/ui/, так как оба компонента жестко связаны сMediaPostиMEDIA_TYPE
Подтверждено:
logBatch()есть вbackend-laravel/app/Services/ActivityLoggerService.php- метода нет в
backend-laravel/app/Services/ActivityLoggerServiceInterface.php
Задача:
- либо добавить
logBatch()в интерфейс - либо убрать его из публичного контракта, если это сознательно internal helper
Сейчас схема обещает followers_count и following_count, но endpoint их не возвращает:
python-service/schemas.pypython-service/main.py:154backend-laravel/app/Services/InstagramClientService.php:84
Задача:
- либо реально заполнить эти поля
- либо убрать их из схемы и потребителей
Подтверждено, что без timeout остаются методы:
login()getUserInfo()getUserInfoByPk()addLike()searchLocations()commentMedia()
Затронутый файл:
backend-laravel/app/Services/InstagramClientService.php
Сейчас каждый endpoint повторяет однотипный try/except, а generic errors отдаются через str(e).
Задача:
- сохранить текущий exception mapping для известных Instagram/network ошибок
- централизовать обработку неожиданных исключений
- не отдавать наружу избыточные internal details
Затронутые файлы:
python-service/main.pypython-service/utils.py
Подтверждено:
index()иreplies()возвращают success-ответ безmessagestore()уже возвращаетmessage
Затронутый файл:
backend-laravel/app/Http/Controllers/CommentController.php
Задача состоит не в массовом stylistic cleanup, а в соблюдении уже принятого slice public API.
Подтверждено:
- часть файлов импортирует напрямую из
model/ - есть прямые импорты UI-файлов мимо slice API
Минимальный обязательный набор:
- использовать entity barrel там, где он уже достаточен
- дополнить barrel только реально нужными экспортами
- убрать прямые импорты файлов
*.vue, где есть нормальный public entry
Особенно важно проверить:
frontend-vue/src/pages/feed/ui/FeedPage.vuefrontend-vue/src/pages/search/ui/SearchPage.vuefrontend-vue/src/pages/instagram-accounts/ui/InstagramAccountsPage.vuefrontend-vue/src/pages/admin-users/ui/AdminUsersPage.vuefrontend-vue/src/entities/user/index.tsfrontend-vue/src/layouts/MainLayout.vuefrontend-vue/src/pages/login/ui/LoginPage.vue
Не нужно запускать массовую миграцию всех прямых Quasar-компонентов.
Что стоит исправить точно:
q-toggleвfrontend-vue/src/pages/instagram-accounts/ui/InstagramAccountsPage.vue:73ModalComponent, потому что он реально выбивается из принятой обертки и усложняет консистентность
Что не нужно делать автоматически в первой волне:
- переписывать все
q-icon,q-avatar,q-spinner,q-skeleton
Эти задачи имеют смысл только после закрытия Must/Should или если затрагиваемые файлы все равно открываются.
Подтверждено:
- accessor сломан:
backend-laravel/app/Facades/InstagramClient.php - реальных вызовов фасада в проекте нет
Рекомендация:
- либо исправить accessor
- либо удалить фасад как мертвый слой абстракции
Подтверждено:
sendCommentживет вsearchStore- логика hashtag/location частично дублируется
Затронутые файлы:
frontend-vue/src/entities/media-post/model/searchStore.tsfrontend-vue/src/entities/media-post/model/commentStore.ts
Подтверждено:
36повторов.then((response) => response.data)
Это хороший cleanup, но не must-fix.
Подтверждено:
16повторов...(x ? { x } : {})
Это stylistic cleanup, не производительность и не баг.
Подтверждено:
python-service/main.py:237python-service/helpers.py:318
Это observability cleanup, не security task.
replied_to_comment_idвpython-service/helpers.py- однобуквенный callback в
frontend-vue/src/entities/media-post/model/commentStore.ts - прямой импорт
RobotIconв layout/login useCommentGenerationinternal auto-cleanupLlmSetting::setApiKeyAttribute(?string)только если реально меняется lifecycleapi_key
Это не нужно смешивать с ближайшим рефакторингом.
Проблема с token в localStorage подтверждена, но это не локальный frontend refactor, а отдельная full-stack security initiative.
Затронутые зоны:
frontend-vue/src/entities/user/model/authStore.tsfrontend-vue/src/boot/axios.tsfrontend-vue/src/router/index.tsfrontend-vue/src/shared/lib/echo.ts- backend auth flow / sanctum config
Файл большой, но это архитектурная работа, а не defect fix.
Добавлять только после явного design note, чтобы не усиливать anti-bot риски.
Потенциально полезно, но без профилирования это backlog-оптимизация.
Сейчас стратегия основана на времени создания записи, а не на last-access. Это полезный hardening, но не ранняя задача.
Файл не мешает pytest, потому что python-service/pytest.ini ограничивает testpaths директорией tests.
Не считать это рефакторингом по умолчанию:
- редактирование аккаунтов
- CRUD для
device_profiles - дополнительные admin endpoints для activity logs
Это product scope, не cleanup.
Делать только после формализации политики: какие компоненты обязаны идти через wrapper, а какие допустимы как presentation-only.
M1каналcomment-generation.{jobId}M2proxy end-to-endM3единый JSON-envelope для activity endpointsM5Reverb/Echo configM4redirect вhistorymode
M6оптимизацияgetStatsByAccount()S2синхронизацияActivityLoggerServiceInterfaceS3честный контракт/account/infoS4явные timeoutS5централизованный FastAPI error handlingS6единый success-envelope вCommentController
S1убратьshared -> entitiesS7frontend public API cleanupS8wrapper policy + точечные исправленияN2cleanupsearchStoreN3/N4low-risk simplification
M7синхронизацияCLAUDE.mdM8python-service/.dockerignore- backlog items только по отдельному решению
- Не переводить весь проект на cookie-auth без отдельной задачи.
- Не разбивать Python-сервис на пакеты в той же ветке, где чинятся контракты и WebSocket security.
- Не переписывать массово все Quasar-компоненты в wrapper-ы.
- Не тащить в main roadmap мелкие stylistic правки без поведенческой ценности.
- Не менять публичные API ради красоты без явной пользы.
docker compose exec vue npx eslint --fix ./srcdocker compose exec vue npx vue-tsc --noEmit
Ручная проверка:
- неавторизованный редирект работает в
historymode - live updates activity работают через реальные каналы
account-activity.*иactivity-global.* - comment generation subscription не открывается постороннему пользователю
- Reverb/Echo работает с конфигом из env
docker compose exec laravel php artisan test
Ручная проверка:
ActivityLogControllerвсегда отдает ожидаемый JSON-format на not-found/error-pathCommentControllersuccess-ответы консистентны- stats payload не изменился по shape после оптимизации
docker compose exec python pytest
Ручная проверка:
- login/account info/search/comment работают после добавления proxy-пути
- generic exceptions не раскрывают лишние internal details
- proxy применяется до логина и при session-based клиенте
Текущий рабочий фокус для следующего агента:
- Закрыть реальный security gap в
comment-generation.{jobId}. - Довести proxy до рабочего контракта Laravel ↔ Python ↔ instagrapi.
- Починить frontend auth/reverb path под текущий
historymode и env-driven transport config. - Убрать подтвержденное FSD/public API drift во frontend.
- Синхронизировать документацию с реальным кодом, чтобы следующий цикл автоматизации опирался на правду, а не на устаревшие описания.
Все остальное стоит делать только после закрытия этих пяти блоков.