Ревью по результатам выполнения архитектурных задач #67-#71.
Ревьюер: iArch | Исполнитель: iCloudDev
| Задача | Статус | Вердикт |
|---|---|---|
| #67 API Gateway | ✅ Сделано | Принято с замечаниями |
| #68 JWT централизация | ✅ Сделано | Принято с замечаниями |
| #69 Retry + Circuit Breaker | ✅ Сделано | Принято |
| #70 GetIt → Riverpod | ✅ Сделано | Принято |
| #71 CORS Calculator | ✅ Сделано | Принято |
Коммиты: c014213e (flutter-app)
Что сделано:
api_constants.dart — единый baseUrl = 'https://mapp.stage-plus.ru/api/v1'wss://mapp.stage-plus.ru/wscalculatorUrl/calculate → baseUrl/calculator/calculateВердикт: ✅ Принято
Замечания (minor):
/calculator/*, /chats/*, /specs/* реально работает на уровне K8s Ingress.Коммиты: c499abeb (iam-service)
Что сделано:
stageplus_auth/ (в backend, скорее всего копируется в другие сервисы)decode_token, TokenUser, get_current_user, get_current_manager, get_current_admindeps.py во всех сервисах → re-export из stageplus_auth/internal/verify для gateway auth_requestВердикт: ✅ Принято — выбран Вариант B (shared library) вместо Варианта A (gateway-only). Это валидный подход.
Замечания:
python-jose[cryptography]==3.3.0. Если JWT декодируется через stageplus_auth, то jose должен быть зависимостью только этой библиотеки, а не каждого сервиса напрямую. Не блокер, но стоит почистить.from jose import jwt в chat car_client.py — зачем JWT decode в клиенте для получения данных об авто? Вероятно, legacy-код. Нужно убрать.stageplus_auth копируется как директория в каждый сервис (не pip-пакет). При изменении логики нужно обновлять во всех репо. Рекомендация на будущее — вынести в отдельный репо + pip install.Коммиты: 471d778b (chat-service), fecddb71 (calculator-service)
Что сделано:
resilient_http/ с ResilientClient и CircuitBreakerhttpx + tenacity (retry с exponential backoff)chat-service/app/services/car_client.pychat-service/app/services/iam_client.pycalculator-service/app/specs_client.pyCOPY resilient_http/tenacity>=8.2 добавлен в requirementsВердикт: ✅ Принято — качественная реализация
Замечания (minor):
resilient_http/ дублируется между chat-service и calculator-service (copy-paste). Аналогично stageplus_auth — на будущее стоит вынести в shared package.push_client.py в chat-service — не проверил, использует ли тоже ResilientClient. Стоит проверить.Коммит: 9fe27c04 (flutter-app)
Что сделано:
service_locator.dart переименован в providers.dartGetIt.instance / sl<T>() заменены на Riverpod providersget_it удалён из pubspec.yaml (подтверждено: grep не находит)main.dart — убран setupServiceLocator(), обёрнут в ProviderScopeВердикт: ✅ Принято — масштабный рефакторинг, выполнен корректно
Замечания: нет
Коммит: 034b5edb (calculator-service)
Что сделано:
config.py с Settings (pydantic-settings)cors_origins вынесены в конфиг с дефолтами: admin-stage.miniapp.zubat.ru, mapp-stage.miniapp.zubat.ru, localhost:5173, localhost:3000allow_origins=["*"] заменён на settings.cors_originsCORS_ORIGINSВердикт: ✅ Принято
Замечания: нет
Не выполнены:
| # | Задача | Приоритет |
|---|---|---|
| #72 | Redis HA — разделить cache и pubsub | P2 |
| #73 | Rate limiting на auth/send-code | P2 |
| #74 | Убрать неиспользуемый Celery | P2 |
| #75 | Contract testing | P3 |
| #76 | Гарантия доставки сообщений | P3 |
| #77 | Structured logging (JSON) | P3 |
| #78 | Унификация feature-архитектуры Flutter | P3 |
Примечание: OTP rate limiting (#73) реализован в отдельном коммите 802c465a в IAM, но задача в Vikunja не закрыта. Нужно проверить и закрыть.
resilient_http/ скопирован в 2 сервисаstageplus_auth/ скопирован в 2+ сервисаfrom jose import jwt в chat-service/app/services/car_client.py — не нужен, если auth через stageplus_authcelery в backend requirements — мёртвая зависимость