diff --git a/app/modules/base.py b/app/modules/base.py index 1108315a..711c375a 100644 --- a/app/modules/base.py +++ b/app/modules/base.py @@ -44,7 +44,7 @@ if TYPE_CHECKING: from fastapi import APIRouter from pydantic import BaseModel -from models.database.admin_menu_config import FrontendType +from app.modules.enums import FrontendType @dataclass diff --git a/app/modules/enums.py b/app/modules/enums.py new file mode 100644 index 00000000..13a950ff --- /dev/null +++ b/app/modules/enums.py @@ -0,0 +1,46 @@ +# app/modules/enums.py +""" +Module system enums. + +This file contains enums used by the module system that need to be +importable without triggering database model imports. + +The FrontendType enum is defined here to break a circular import: +- app.modules.base imports FrontendType +- Previously FrontendType was in models.database.admin_menu_config +- Importing from models.database triggers model discovery +- Model discovery imports module definitions +- Module definitions import from app.modules.base → CIRCULAR + +By defining FrontendType here, we break this cycle. +""" + +import enum + + +class FrontendType(str, enum.Enum): + """Frontend types that can have menu configuration.""" + + ADMIN = "admin" # Admin panel (super admins, platform admins) + VENDOR = "vendor" # Vendor dashboard + + +# Menu items that cannot be hidden - always visible regardless of config +# Organized by frontend type +MANDATORY_MENU_ITEMS = { + FrontendType.ADMIN: frozenset({ + "dashboard", # Default landing page after login + "companies", + "vendors", + "admin-users", + "settings", + "my-menu", # Super admin menu config - must always be accessible + }), + FrontendType.VENDOR: frozenset({ + "dashboard", # Default landing page after login + "settings", + }), +} + + +__all__ = ["FrontendType", "MANDATORY_MENU_ITEMS"] diff --git a/models/database/admin_menu_config.py b/models/database/admin_menu_config.py index 61a44e0e..1c65ea8d 100644 --- a/models/database/admin_menu_config.py +++ b/models/database/admin_menu_config.py @@ -19,8 +19,6 @@ Design: - Only stores non-default state (is_visible=False) to keep table small """ -import enum - from sqlalchemy import ( Boolean, CheckConstraint, @@ -37,30 +35,11 @@ from sqlalchemy.orm import relationship from app.core.database import Base from models.database.base import TimestampMixin - -class FrontendType(str, enum.Enum): - """Frontend types that can have menu configuration.""" - - ADMIN = "admin" # Admin panel (super admins, platform admins) - VENDOR = "vendor" # Vendor dashboard - - -# Menu items that cannot be hidden - always visible regardless of config -# Organized by frontend type -MANDATORY_MENU_ITEMS = { - FrontendType.ADMIN: frozenset({ - "dashboard", # Default landing page after login - "companies", - "vendors", - "admin-users", - "settings", - "my-menu", # Super admin menu config - must always be accessible - }), - FrontendType.VENDOR: frozenset({ - "dashboard", # Default landing page after login - "settings", - }), -} +# Import FrontendType and MANDATORY_MENU_ITEMS from the central location +# and re-export for backward compatibility with existing imports. +# These were moved to app.modules.enums to break a circular import: +# app.modules.base -> models.database -> model discovery -> module definitions -> app.modules.base +from app.modules.enums import FrontendType, MANDATORY_MENU_ITEMS class AdminMenuConfig(Base, TimestampMixin):