Fix broker session showing connected after Zerodha token expiry
- Set connected=FALSE (was TRUE) when expiring broker session so the dashboard correctly reflects disconnected state - Notify user by email when their Zerodha session expires so they know to reconnect before the next SIP execution Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
247a1c5107
commit
1b14e7b23e
@ -162,7 +162,7 @@ def expire_user_broker_session(user_id: str):
|
|||||||
cur.execute(
|
cur.execute(
|
||||||
"""
|
"""
|
||||||
UPDATE user_broker
|
UPDATE user_broker
|
||||||
SET connected = TRUE,
|
SET connected = FALSE,
|
||||||
access_token = NULL,
|
access_token = NULL,
|
||||||
auth_state = 'EXPIRED'
|
auth_state = 'EXPIRED'
|
||||||
WHERE user_id = %s
|
WHERE user_id = %s
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from fastapi.responses import HTMLResponse
|
|||||||
|
|
||||||
from app.broker_store import expire_user_broker_session
|
from app.broker_store import expire_user_broker_session
|
||||||
from app.services.auth_service import get_user_for_session
|
from app.services.auth_service import get_user_for_session
|
||||||
|
from app.services.email_service import send_email_async
|
||||||
from app.services.live_equity_service import (
|
from app.services.live_equity_service import (
|
||||||
capture_live_equity_snapshot,
|
capture_live_equity_snapshot,
|
||||||
get_live_equity_curve,
|
get_live_equity_curve,
|
||||||
@ -48,14 +49,24 @@ def _capture_request_token(request: Request, request_token: str):
|
|||||||
store_request_token(user["id"], token)
|
store_request_token(user["id"], token)
|
||||||
|
|
||||||
|
|
||||||
def _clear_broker_session(user_id: str):
|
def _clear_broker_session(user_id: str, email: str | None = None):
|
||||||
expire_user_broker_session(user_id)
|
expire_user_broker_session(user_id)
|
||||||
clear_session(user_id)
|
clear_session(user_id)
|
||||||
|
if email:
|
||||||
|
try:
|
||||||
|
body = (
|
||||||
|
"Your Zerodha session has expired and your broker connection has been disconnected.\n\n"
|
||||||
|
"Please log in to QuantFortune and reconnect your Zerodha account to resume your strategy.\n\n"
|
||||||
|
"If your strategy was running, it has been paused until you reconnect."
|
||||||
|
)
|
||||||
|
send_email_async(email, "Action required: Zerodha session expired", body)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _raise_kite_error(user_id: str, exc: KiteApiError):
|
def _raise_kite_error(user_id: str, exc: KiteApiError, email: str | None = None):
|
||||||
if isinstance(exc, KiteTokenError):
|
if isinstance(exc, KiteTokenError):
|
||||||
_clear_broker_session(user_id)
|
_clear_broker_session(user_id, email=email)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=401, detail="Zerodha session expired. Please reconnect."
|
status_code=401, detail="Zerodha session expired. Please reconnect."
|
||||||
) from exc
|
) from exc
|
||||||
@ -139,7 +150,7 @@ async def holdings(request: Request):
|
|||||||
try:
|
try:
|
||||||
data = fetch_holdings(session["api_key"], session["access_token"])
|
data = fetch_holdings(session["api_key"], session["access_token"])
|
||||||
except KiteApiError as exc:
|
except KiteApiError as exc:
|
||||||
_raise_kite_error(user["id"], exc)
|
_raise_kite_error(user["id"], exc, email=user["username"])
|
||||||
return {"holdings": [normalize_holding(item) for item in data]}
|
return {"holdings": [normalize_holding(item) for item in data]}
|
||||||
|
|
||||||
|
|
||||||
@ -152,7 +163,7 @@ async def funds(request: Request):
|
|||||||
try:
|
try:
|
||||||
data = fetch_funds(session["api_key"], session["access_token"])
|
data = fetch_funds(session["api_key"], session["access_token"])
|
||||||
except KiteApiError as exc:
|
except KiteApiError as exc:
|
||||||
_raise_kite_error(user["id"], exc)
|
_raise_kite_error(user["id"], exc, email=user["username"])
|
||||||
equity = data.get("equity", {}) if isinstance(data, dict) else {}
|
equity = data.get("equity", {}) if isinstance(data, dict) else {}
|
||||||
return {"funds": {**equity, "raw": data}}
|
return {"funds": {**equity, "raw": data}}
|
||||||
|
|
||||||
@ -168,7 +179,7 @@ async def equity_curve(request: Request, from_: str = Query("", alias="from")):
|
|||||||
holdings = fetch_holdings(session["api_key"], session["access_token"])
|
holdings = fetch_holdings(session["api_key"], session["access_token"])
|
||||||
funds_data = fetch_funds(session["api_key"], session["access_token"])
|
funds_data = fetch_funds(session["api_key"], session["access_token"])
|
||||||
except KiteApiError as exc:
|
except KiteApiError as exc:
|
||||||
_raise_kite_error(user["id"], exc)
|
_raise_kite_error(user["id"], exc, email=user["username"])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
capture_live_equity_snapshot(
|
capture_live_equity_snapshot(
|
||||||
@ -177,7 +188,7 @@ async def equity_curve(request: Request, from_: str = Query("", alias="from")):
|
|||||||
funds_data=funds_data,
|
funds_data=funds_data,
|
||||||
)
|
)
|
||||||
except KiteApiError as exc:
|
except KiteApiError as exc:
|
||||||
_raise_kite_error(user["id"], exc)
|
_raise_kite_error(user["id"], exc, email=user["username"])
|
||||||
|
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
default_start = (now - timedelta(days=90)).date()
|
default_start = (now - timedelta(days=90)).date()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user