feat: Add A-Z filter for clients/suppliers in Telegram bot
- Add A-Z alphabetical filter keyboard for clients and suppliers lists (same pattern as company selection, without emoji) - Increase clients/suppliers list pagination from 10 to 20 items per page - Remove emoji from company A-Z filter button for consistency - Add 6 new callback handlers: clients_alpha_menu, clients_alpha:LETTER, clients_alpha_page:PAGE:LETTER, and supplier equivalents - Dashboard service and models updates - Telegram bot: email handlers, auth, DB operations, internal API improvements - Frontend: dashboard cards updates (CashFlow, Clienti, Furnizori, Treasury) - Frontend: SolduriCompactCard and CollapsibleCard improvements - DashboardView enhancements - start.sh and run-with-restart.sh script updates - IIS web.config and service worker updates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -105,7 +105,8 @@ class BackendAPIClient:
|
||||
async def verify_user(
|
||||
self,
|
||||
oracle_username: str,
|
||||
linking_code: str
|
||||
linking_code: str,
|
||||
server_id: Optional[str] = None
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Verify user exists in Oracle and get JWT token.
|
||||
@@ -139,7 +140,8 @@ class BackendAPIClient:
|
||||
"/api/telegram/auth/verify-user",
|
||||
json={
|
||||
"linking_code": linking_code,
|
||||
"oracle_username": oracle_username
|
||||
"oracle_username": oracle_username,
|
||||
"server_id": server_id
|
||||
}
|
||||
)
|
||||
|
||||
@@ -185,12 +187,13 @@ class BackendAPIClient:
|
||||
logger.error(f"Failed to refresh token: {e}")
|
||||
return None
|
||||
|
||||
async def verify_email(self, email: str) -> dict:
|
||||
async def verify_email(self, email: str, server_id: Optional[str] = None) -> dict:
|
||||
"""
|
||||
Verify if email exists in Oracle database
|
||||
|
||||
Args:
|
||||
email: Email address to verify
|
||||
server_id: Optional Oracle server ID (for multi-server mode)
|
||||
|
||||
Returns:
|
||||
dict with 'success' (bool), 'username' (str or None), and 'message' (str)
|
||||
@@ -204,7 +207,7 @@ class BackendAPIClient:
|
||||
|
||||
response = await self.client.post(
|
||||
"/api/telegram/auth/verify-email",
|
||||
json={"email": email}
|
||||
json={"email": email, "server_id": server_id}
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
@@ -229,7 +232,8 @@ class BackendAPIClient:
|
||||
email: str,
|
||||
password: str,
|
||||
telegram_user_id: int,
|
||||
session_token: str
|
||||
session_token: str,
|
||||
server_id: Optional[str] = None
|
||||
) -> dict:
|
||||
"""
|
||||
Login via email + password with session token
|
||||
@@ -239,6 +243,7 @@ class BackendAPIClient:
|
||||
password: Oracle password
|
||||
telegram_user_id: Telegram user ID
|
||||
session_token: Signed token from code validation
|
||||
server_id: Optional Oracle server ID (for multi-server mode)
|
||||
|
||||
Returns:
|
||||
Login response with JWT tokens and user data
|
||||
@@ -256,7 +261,8 @@ class BackendAPIClient:
|
||||
"email": email,
|
||||
"password": password,
|
||||
"telegram_user_id": telegram_user_id,
|
||||
"session_token": session_token
|
||||
"session_token": session_token,
|
||||
"server_id": server_id
|
||||
},
|
||||
timeout=30.0 # 30 seconds timeout
|
||||
)
|
||||
@@ -298,6 +304,52 @@ class BackendAPIClient:
|
||||
"message": "Eroare de conexiune"
|
||||
}
|
||||
|
||||
async def switch_server(
|
||||
self,
|
||||
jwt_token: str,
|
||||
oracle_username: str,
|
||||
new_server_id: str,
|
||||
oracle_password: str = None
|
||||
) -> dict:
|
||||
"""
|
||||
Switch the active Oracle server for the authenticated user.
|
||||
|
||||
Args:
|
||||
jwt_token: Current JWT access token (used for authentication)
|
||||
oracle_username: Oracle username of the current user
|
||||
new_server_id: Target Oracle server ID
|
||||
oracle_password: Oracle password on the new server (required if servers have different passwords)
|
||||
|
||||
Returns:
|
||||
Dict with success, access_token, refresh_token, message
|
||||
"""
|
||||
try:
|
||||
if not self.client or self.client.is_closed:
|
||||
self.client = AsyncClient(base_url=self.base_url, timeout=REQUEST_TIMEOUT)
|
||||
|
||||
payload = {"oracle_username": oracle_username, "new_server_id": new_server_id}
|
||||
if oracle_password:
|
||||
payload["oracle_password"] = oracle_password
|
||||
|
||||
response = await self.client.post(
|
||||
"/api/telegram/auth/switch-server",
|
||||
json=payload,
|
||||
headers=self._get_auth_headers(jwt_token)
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(f"Switch server HTTP error: {e.response.status_code}")
|
||||
try:
|
||||
return {"success": False, "message": e.response.json().get("detail", "Eroare")}
|
||||
except Exception:
|
||||
return {"success": False, "message": "Eroare la schimbarea serverului"}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Switch server error: {e}")
|
||||
return {"success": False, "message": "Eroare de conexiune"}
|
||||
|
||||
async def get_user_companies(self, jwt_token: str) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Get list of companies the user has access to.
|
||||
|
||||
Reference in New Issue
Block a user