fix(web): подключённый аккаунт не появлялся в списке
Владелец подключил первый аккаунт Antigravity на сервере, получил
«Авторизация успешно завершена» — и не увидел его в разделе «Аккаунты».
Учётные данные сохранялись правильно: save_profile_auth и load_profile_auth
симметричны, get_profile_status после записи отдаёт authenticated=True —
проверено исполнением. Не совпадало другое: состояние профилей берётся из
кэша UnifiedHealthService, а фоновый цикл веб-сервера обновляет снапшот с
force_scan=False и кэш не трогает.
Измерено на изолированном каталоге:
до входа ag-w1 -> not_configured
сразу после входа ag-w1 -> not_configured
после refresh(force=False) ag-w1 -> not_configured <- цикл делает это
после refresh(force=True) ag-w1 -> not_tested
То есть аккаунт не появился бы никогда, пока хаб не перезапустят.
Теперь после успешного входа выполняется пересбор с force_scan=True — во всех
четырёх точках завершения: device-flow, ручная вставка адреса, опрос
redirect-потока и код Claude. Ошибка пересбора логируется и сам вход не
роняет.
Функция объявлена на уровне модуля: вложенной она была видна не всем точкам,
и device-flow получал NameError внутри обработки успеха. Мой тест этого не
поймал, потому что проверял только redirect-путь — нашла проверка ruff.
Проверено: not_configured -> not_tested сразу после входа, без ручного
обновления; путь device-flow исполняется без NameError. 432 passed, ruff
чисто.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
0800ca94e0
commit
681c899cfd
1 changed files with 27 additions and 0 deletions
|
|
@ -236,6 +236,27 @@ def do_set_model(profile_id: str, model: str, role_id: Optional[str] = None) ->
|
|||
return False, "Не удалось сохранить файл конфигурации"
|
||||
|
||||
|
||||
# Подключённый аккаунт обязан появиться в списке сразу.
|
||||
#
|
||||
# Учётные данные сохраняются на диск, но состояние профилей берётся из кэша
|
||||
# UnifiedHealthService, а фоновый цикл веб-сервера обновляет снапшот с
|
||||
# force_scan=False, то есть кэш не трогает. Проверено исполнением: после входа
|
||||
# профиль оставался not_configured и при обычном refresh, и переходил в
|
||||
# not_tested только при force_scan=True. Владелец видел «аккаунт подключён» и
|
||||
# пустой список аккаунтов.
|
||||
#
|
||||
# Функция объявлена на уровне модуля намеренно: как вложенная она была видна
|
||||
# не всем точкам завершения входа, и device-flow получал NameError внутри
|
||||
# обработки успеха.
|
||||
def _rescan_after_auth() -> None:
|
||||
try:
|
||||
from antigravity_provider.router.state_store import HubStateStore
|
||||
|
||||
HubStateStore.get().refresh(force_scan=True)
|
||||
except Exception as exc: # пересбор не должен ронять сам вход
|
||||
logger.warning("Не удалось пересобрать снапшот после входа: %s", exc)
|
||||
|
||||
|
||||
class ActionExecutor:
|
||||
"""Shared execution layer for Desktop and Web actions."""
|
||||
|
||||
|
|
@ -310,6 +331,7 @@ class ActionExecutor:
|
|||
|
||||
status = getattr(session, 'status', 'unknown')
|
||||
if status == 'completed':
|
||||
_rescan_after_auth()
|
||||
return {'ok': True, 'message': 'Аккаунт подключён', 'data': {'status': status}}
|
||||
if status in ('failed', 'timeout'):
|
||||
reason = getattr(session, 'error_msg', None) or 'Авторизация не завершена'
|
||||
|
|
@ -402,6 +424,8 @@ class ActionExecutor:
|
|||
if not session:
|
||||
return {'ok': False, 'message': 'Сессия авторизации не найдена или уже завершена'}
|
||||
ok, msg = session.handle_auth_code(raw_value)
|
||||
if ok:
|
||||
_rescan_after_auth()
|
||||
else:
|
||||
from antigravity_provider.router.profile_oauth import get_oauth_session
|
||||
|
||||
|
|
@ -409,6 +433,8 @@ class ActionExecutor:
|
|||
if not session:
|
||||
return {'ok': False, 'message': 'Сессия авторизации не найдена или уже завершена'}
|
||||
ok, msg = session.handle_manual_callback_url(raw_value)
|
||||
if ok:
|
||||
_rescan_after_auth()
|
||||
return {'ok': ok, 'message': msg}
|
||||
|
||||
if action == 'poll_redirect_auth':
|
||||
|
|
@ -420,6 +446,7 @@ class ActionExecutor:
|
|||
return {'ok': False, 'message': 'Сессия авторизации не найдена'}
|
||||
status = getattr(session, 'status', 'unknown')
|
||||
if status == 'completed':
|
||||
_rescan_after_auth()
|
||||
return {'ok': True, 'message': 'Аккаунт подключён', 'data': {'status': 'completed'}}
|
||||
if status in ('failed', 'cancelled'):
|
||||
return {'ok': False, 'message': session.error_msg or 'Авторизация не удалась'}
|
||||
|
|
|
|||
Loading…
Reference in a new issue