Fix Client Groups circular imports and module dependencies
This commit is contained in:
@@ -5,9 +5,10 @@ from fastapi.responses import RedirectResponse
|
|||||||
|
|
||||||
from app.core.db.common import CommonSessionLocal
|
from app.core.db.common import CommonSessionLocal
|
||||||
from app.core.security.csrf import get_or_create_csrf_token, validate_csrf
|
from app.core.security.csrf import get_or_create_csrf_token, validate_csrf
|
||||||
from app.core.security.deps import get_current_user
|
from app.core.security.session_auth import get_current_user
|
||||||
from app.core.templating import templates
|
from app.core.templating import templates
|
||||||
from app.modules.core.rbac.service import get_user_permissions, get_user_roles, require_permission
|
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
||||||
|
from app.modules.core.rbac.permission_guard import require_permission
|
||||||
from app.modules.client_groups.service import GROUP_TYPES, create_group, get_group, list_group_clients, list_groups, update_group
|
from app.modules.client_groups.service import GROUP_TYPES, create_group, get_group, list_group_clients, list_groups, update_group
|
||||||
from app.modules.clients.access import build_scope
|
from app.modules.clients.access import build_scope
|
||||||
from app.modules.clients import repository
|
from app.modules.clients import repository
|
||||||
|
|||||||
@@ -1,4 +1,29 @@
|
|||||||
from .api import router as api_router
|
"""Clients module.
|
||||||
from .ui import router as ui_router
|
|
||||||
|
Routers are exposed lazily so importing ``app.modules.clients.models`` does
|
||||||
|
not initialise the clients API, UI, importer, and related modules. This keeps
|
||||||
|
the existing ``api_router`` and ``ui_router`` public exports while preventing
|
||||||
|
circular imports with client groups.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
__all__ = ["api_router", "ui_router"]
|
__all__ = ["api_router", "ui_router"]
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(name: str) -> Any:
|
||||||
|
if name == "api_router":
|
||||||
|
from .api import router
|
||||||
|
|
||||||
|
return router
|
||||||
|
|
||||||
|
if name == "ui_router":
|
||||||
|
from .ui import router
|
||||||
|
|
||||||
|
return router
|
||||||
|
|
||||||
|
raise AttributeError(
|
||||||
|
f"module {__name__!r} has no attribute {name!r}"
|
||||||
|
)
|
||||||
@@ -30,11 +30,16 @@ from app.modules.core.iam.models import User
|
|||||||
from app.modules.core.rbac.models import Role, UserRole
|
from app.modules.core.rbac.models import Role, UserRole
|
||||||
from app.modules.documents.models import PermanentClientDocument
|
from app.modules.documents.models import PermanentClientDocument
|
||||||
from app.modules.consultants.service import sync_primary_client_consultant_link
|
from app.modules.consultants.service import sync_primary_client_consultant_link
|
||||||
from app.modules.client_groups.service import get_group
|
|
||||||
from app.modules.clients.models import Client
|
from app.modules.clients.models import Client
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _get_client_group(*args, **kwargs):
|
||||||
|
# Imported lazily to prevent clients ↔ client_groups circular imports.
|
||||||
|
from app.modules.client_groups.service import get_group
|
||||||
|
return get_group(*args, **kwargs)
|
||||||
def _payload_from_schema(data):
|
def _payload_from_schema(data):
|
||||||
payload = data.model_dump(exclude_none=True) if hasattr(data, "model_dump") else data.dict(exclude_none=True)
|
payload = data.model_dump(exclude_none=True) if hasattr(data, "model_dump") else data.dict(exclude_none=True)
|
||||||
# primary_consultant_id belongs to ClientConsultantLink, not the clients table.
|
# primary_consultant_id belongs to ClientConsultantLink, not the clients table.
|
||||||
@@ -50,7 +55,7 @@ def _validate_client_group_assignment(db, *, payload: dict, existing_row=None):
|
|||||||
group_id = payload.get("client_group_id")
|
group_id = payload.get("client_group_id")
|
||||||
tenant_id = payload.get("tenant_id") or getattr(existing_row, "tenant_id", None)
|
tenant_id = payload.get("tenant_id") or getattr(existing_row, "tenant_id", None)
|
||||||
if group_id:
|
if group_id:
|
||||||
group = get_group(db, tenant_id=int(tenant_id), group_id=int(group_id))
|
group = _get_client_group(db, tenant_id=int(tenant_id), group_id=int(group_id))
|
||||||
if not group or not group.is_active:
|
if not group or not group.is_active:
|
||||||
raise HTTPException(status_code=400, detail="Selected client group is invalid or inactive for this firm.")
|
raise HTTPException(status_code=400, detail="Selected client group is invalid or inactive for this firm.")
|
||||||
if payload.get("is_group_head") and group_id:
|
if payload.get("is_group_head") and group_id:
|
||||||
|
|||||||
Reference in New Issue
Block a user