from __future__ import annotations from datetime import datetime from sqlalchemy import Select, select from sqlalchemy.orm import Session, selectinload from app.models.client_access import ClientAccount, ClientFeatureAccess, ClientUser def client_access_query() -> Select[tuple[ClientAccount]]: return ( select(ClientAccount) .options(selectinload(ClientAccount.users), selectinload(ClientAccount.features)) .order_by(ClientAccount.name) ) def list_client_accounts(db: Session) -> list[ClientAccount]: return db.scalars(client_access_query()).all() def serialize_client_user(user: ClientUser) -> dict: return { "id": user.id, "client_account_id": user.client_account_id, "full_name": user.full_name, "email": user.email, "role": user.role, "status": user.status, "is_new_user": user.is_new_user, "last_login_at": user.last_login_at, "created_at": user.created_at, } def serialize_client_feature(feature: ClientFeatureAccess) -> dict: return { "id": feature.id, "client_account_id": feature.client_account_id, "feature_key": feature.feature_key, "feature_name": feature.feature_name, "feature_group": feature.feature_group, "description": feature.description, "enabled": feature.enabled, "updated_at": feature.updated_at, "created_at": feature.created_at, } def serialize_client_account(client: ClientAccount) -> dict: users = [serialize_client_user(user) for user in client.users] features = [serialize_client_feature(feature) for feature in client.features] active_users = sum(1 for user in users if user["status"] == "active") new_users = sum(1 for user in users if user["is_new_user"]) enabled_features = sum(1 for feature in features if feature["enabled"]) return { "id": client.id, "tenant_id": client.tenant_id, "name": client.name, "client_code": client.client_code, "status": client.status, "powerbi_workspace": client.powerbi_workspace, "notes": client.notes, "created_at": client.created_at, "users": users, "features": features, "active_user_count": active_users, "new_user_count": new_users, "enabled_feature_count": enabled_features, "total_feature_count": len(features), } def build_client_access_export(clients: list[ClientAccount]) -> dict: serialized_clients = [serialize_client_account(client) for client in clients] client_rows = [] user_rows = [] feature_rows = [] for client in serialized_clients: client_rows.append( { "client_id": client["id"], "tenant_id": client["tenant_id"], "client_name": client["name"], "client_code": client["client_code"], "client_status": client["status"], "powerbi_workspace": client["powerbi_workspace"], "active_user_count": client["active_user_count"], "new_user_count": client["new_user_count"], "enabled_feature_count": client["enabled_feature_count"], "total_feature_count": client["total_feature_count"], } ) for user in client["users"]: user_rows.append( { "client_id": client["id"], "client_name": client["name"], "user_id": user["id"], "full_name": user["full_name"], "email": user["email"], "role": user["role"], "status": user["status"], "is_new_user": user["is_new_user"], "last_login_at": user["last_login_at"], "created_at": user["created_at"], } ) for feature in client["features"]: feature_rows.append( { "client_id": client["id"], "client_name": client["name"], "feature_id": feature["id"], "feature_key": feature["feature_key"], "feature_name": feature["feature_name"], "feature_group": feature["feature_group"], "enabled": feature["enabled"], "updated_at": feature["updated_at"], } ) return { "generated_at": datetime.utcnow(), "client_rows": client_rows, "user_rows": user_rows, "feature_rows": feature_rows, "clients": serialized_clients, }