Auth Service — BR 1.4.4
Репо: erp-auth-service Контракт: API + Data Model
Зависимости
Требуется задеплоенный User Service с новыми endpoint’ами
/internal/users/{id}/scopeи/franchises/{id}.
Фаза 1 — JWT payload
- В
JwtService.generateAccessToken— убрать claim’ыrole,store_ids,legal_entity_id. Оставить толькоsub,franchise_id,role_ids,iat,exp - В
JwtService.parse/JwtUser— убрать соответствующие поля. Старые JWT с этими полями парсятся: поля просто игнорируются (backward-compat) - Обновить DTO
JwtUser/UserPrincipal
Фаза 2 — UserScopeCache
- Новый DTO
CachedScope { type: String, legalEntityIds?: List<UUID>, storeIds?: List<UUID> }— Jackson-сериализуемый - Новый service
UserScopeCache:getOrLoad(userId): CachedScope— cache-aside. Redis keyuser_scope:{user_id}, TTL из configauth.scope-cache.ttl-seconds: 60loadAndCache(userId)— fetch изUserServiceClient.getScope(userId)evict(userId)
- TTL в
application.yml— добавить
Фаза 3 — UserServiceClient
- Новый метод
getScope(userId): CachedScope— вызываетGET /internal/users/{id}/scope - Новый метод
getFranchise(franchiseId): FranchiseDto— вызываетGET /api/v1/franchises/{id}(использует service token?) или отдельный internal. Уточнить: нужен internal endpointGET /internal/franchises/{id}? (если нет — можно использовать public с service-token)
Фаза 4 — Response classes
-
UserInfoResponse(для/auth/login+/auth/me):- Убрать:
role,store_ids,legal_entity_id - Добавить:
franchise: { id, type },scope: { type, legal_entity_ids?, store_ids? }, оставитьrole_ids,permissions
- Убрать:
-
ValidateResponse(для/internal/auth/validate):- Убрать
role,store_ids,legal_entity_id - Добавить
scope(+role_ids,permissionsуже были)
- Убрать
Фаза 5 — AuthService
-
login(email, password):- Валидировать через User Service (uses existing endpoint)
- Получить
scopeчерезUserScopeCache.getOrLoad(userId) - Получить
franchiseчерезUserServiceClient.getFranchise(franchiseId)(либо кэш franchise_type отдельно, TTL 300s? — опционально) - Сложить всё в
LoginResponse
-
me():- Аналогично login, но authenticated по JWT
-
validate(token):- Decode JWT → userId, role_ids
- Получить permissions через existing
UserPermissionsCache - Получить scope через
UserScopeCache - Вернуть
ValidateResponse
Фаза 6 — Redis session (если используется)
-
session:{user_id}:{token_hash}— убратьrole, store_ids, legal_entity_idиз сохраняемой JSON-структуры. Оставить{ user_id, role_ids, franchise_id }
Фаза 7 — Тесты (optional)
-
UserScopeCache— hit/miss/expiry -
ValidateResponse— поля корректные после валидации - Регрессия: старые JWT с role-полем не ломают парсинг
Выходные критерии
- Все claim’ы
role,store_ids,legal_entity_idубраны из JWT - Все ответы
/auth/*и/internal/auth/validate— содержатscope+franchise.type(где уместно) - Docker build OK
- Коммит + push