diff --git a/backend/api/v1/modules/core/invites/service.py b/backend/api/v1/modules/core/invites/service.py index 447ad72d..04c6fd1a 100644 --- a/backend/api/v1/modules/core/invites/service.py +++ b/backend/api/v1/modules/core/invites/service.py @@ -78,25 +78,48 @@ class InviteService: # Crear invite en el Hub para que el usuario use el form del workspace hub_invite_token: Optional[str] = None invite_url: str = "" - try: - async with httpx.AsyncClient(timeout=10.0) as client: - login_resp = await client.post( - f"{settings.HUB_URL}api/v1/auth/login", - json={"username": settings.HUB_ADMIN_EMAIL, "password": settings.HUB_ADMIN_PASSWORD}, - ) - if login_resp.status_code == 200: - svc_token = login_resp.json().get("access_token", "") - hub_resp = await client.post( - f"{settings.HUB_URL}api/v1/hub/invites", - json={"email": str(data.email), "tenant_slug": tenant_slug}, - headers={"Authorization": f"Bearer {svc_token}"}, + if not settings.HUB_ADMIN_EMAIL or not settings.HUB_ADMIN_PASSWORD: + logger.error( + "[invite] HUB_ADMIN_EMAIL o HUB_ADMIN_PASSWORD no configurados — " + "el invite NO se creará en el Hub y se usará el fallback local. " + "Configura HUB_ADMIN_EMAIL y HUB_ADMIN_PASSWORD en .env" + ) + else: + try: + async with httpx.AsyncClient(timeout=10.0) as client: + login_resp = await client.post( + f"{settings.HUB_URL}api/v1/auth/login", + json={"username": settings.HUB_ADMIN_EMAIL, "password": settings.HUB_ADMIN_PASSWORD}, ) - if hub_resp.status_code in (200, 201): - hub_data = hub_resp.json() - hub_invite_token = hub_data.get("invite_token") or _extract_token_from_url(hub_data.get("invite_url", "")) - invite_url = hub_data.get("invite_url", "") - except Exception as exc: - logger.warning("Hub invite creation failed (non-blocking): %s", exc) + if login_resp.status_code != 200: + logger.error( + "[invite] Hub login falló: status=%s body=%s — " + "verifica HUB_ADMIN_EMAIL=%s y HUB_ADMIN_PASSWORD en .env", + login_resp.status_code, + login_resp.text[:200], + settings.HUB_ADMIN_EMAIL, + ) + else: + svc_token = login_resp.json().get("access_token", "") + hub_resp = await client.post( + f"{settings.HUB_URL}api/v1/hub/invites", + json={"email": str(data.email), "tenant_slug": tenant_slug}, + headers={"Authorization": f"Bearer {svc_token}"}, + ) + if hub_resp.status_code in (200, 201): + hub_data = hub_resp.json() + hub_invite_token = hub_data.get("invite_token") or _extract_token_from_url(hub_data.get("invite_url", "")) + invite_url = hub_data.get("invite_url", "") + else: + logger.error( + "[invite] Hub invite creation falló: status=%s body=%s tenant=%s email=%s", + hub_resp.status_code, + hub_resp.text[:300], + tenant_slug, + data.email, + ) + except Exception as exc: + logger.error("[invite] Hub invite creation excepción (non-blocking): %s", exc) # Fallback: URL del workspace (Hub) si la creación de invitación en Hub falló if not invite_url: