from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from typing import List from app.models.auth.module_model import Module from app.models.auth.access_model import Access from app.models.auth.module_access_model import ModuleAccess import uuid from app.config.database import get_db from app.services.auth.module_permission_service import ModulePermissionService from app.middleware.auth_middleware import get_current_user, require_access, User from app.schemas.auth.module_schema import ModuleCreate, ModuleUpdate, ModuleResponse from app.controllers.auth.module_controller import ModuleController from app.services.system.audit_log_service import AuditLogService from app.helper.helpers import get_client_ip router = APIRouter() @router.get("/", response_model=List[ModuleResponse]) def list_modules( current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.view")), db: Session = Depends(get_db) ): return ModuleController.list_modules(db) @router.post("/", response_model=ModuleResponse, status_code=201) def create_module( request: Request, module_data: ModuleCreate, current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.manage")), db: Session = Depends(get_db) ): result = ModuleController.create_module(db, module_data) # Professional Audit Logging AuditLogService.log( db=db, module_name="Modules", action_type="CREATE", entity_id=str(result.id), entity_name=result.module_name, description=f"Module '{result.module_name}' created", performed_by_id=str(current_user.id), performed_by_email=current_user.email, ip_address=_get_client_ip(request), new_values=module_data.model_dump() ) return result @router.get("/{module_id}", response_model=ModuleResponse) def get_module( module_id: str, current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.view")), db: Session = Depends(get_db) ): return ModuleController.get_module(db, module_id) @router.put("/{module_id}", response_model=ModuleResponse) def update_module( request: Request, module_id: str, module_data: ModuleUpdate, current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.manage")), db: Session = Depends(get_db) ): # Snapshot before update existing = ModuleController.get_module(db, module_id) old_values = {"name": existing.module_name, "status": existing.status} result = ModuleController.update_module(db, module_id, module_data) AuditLogService.log( db=db, module_name="Modules", action_type="UPDATE", entity_id=module_id, entity_name=result.module_name, description=f"Module '{result.module_name}' updated", performed_by_id=str(current_user.id), performed_by_email=current_user.email, ip_address=_get_client_ip(request), old_values=old_values, new_values=module_data.model_dump(exclude_unset=True) ) return result @router.delete("/{module_id}") def delete_module( request: Request, module_id: str, current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.manage")), db: Session = Depends(get_db) ): # Capture name for the log before it's deleted existing = ModuleController.get_module(db, module_id) module_name = existing.module_name result = ModuleController.delete_module(db, module_id) AuditLogService.log( db=db, module_name="Modules", action_type="DELETE", entity_id=module_id, entity_name=module_name, description=f"Module '{module_name}' deleted", performed_by_id=str(current_user.id), performed_by_email=current_user.email, ip_address=_get_client_ip(request) ) return result # ── Permission Sync Routes ────────────────────────────────────────────────── @router.get("/{module_id}/permissions") def get_module_permissions( module_id: str, current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.view")), db: Session = Depends(get_db) ): # Now using the Service method you just shared! return ModulePermissionService.get_module_permissions(db, module_id) @router.post("/{module_id}/permissions/sync") def sync_module_permissions( module_id: str, current_user: User = Depends(get_current_user), _: bool = Depends(require_access("modules.manage")), db: Session = Depends(get_db) ): try: return ModulePermissionService.sync_permissions(db, module_id) except Exception as e: if isinstance(e, HTTPException): raise e raise HTTPException( status_code=500, detail=f"Permission sync failed: {str(e)}" )