diff --git a/backend/app/api/endpoints/admin.py b/backend/app/api/endpoints/admin.py index 8450e0bd..76786c11 100644 --- a/backend/app/api/endpoints/admin.py +++ b/backend/app/api/endpoints/admin.py @@ -8,7 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from sqlalchemy.orm import selectinload -from app.core.database import get_db +from app.core.admin_database import get_admin_db from app.core.audit import log_audit from app.core.config import settings from app.core.security import get_password_hash, generate_temp_password, create_password_reset_token, decode_token, hash_token @@ -37,7 +37,7 @@ router = APIRouter(prefix="/admin", tags=["admin"]) @router.get("/users", response_model=list[UserResponse]) async def list_users( - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=100), @@ -74,7 +74,7 @@ def _generate_display_code() -> str: @router.post("/users", response_model=AdminUserCreateResponse, status_code=status.HTTP_201_CREATED) async def create_user( data: AdminUserCreate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Create a new user with a temporary password (super admin only). @@ -199,7 +199,7 @@ async def create_user( @router.get("/users/{user_id}", response_model=UserDetailResponse) async def get_user( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)] ): """Get enriched user details (super admin only).""" @@ -317,7 +317,7 @@ async def get_user( async def update_user_role( user_id: UUID, role_data: RoleUpdate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)] ): """Change user role (super admin only).""" @@ -349,7 +349,7 @@ async def update_user_role( async def update_account_role( user_id: UUID, data: AccountRoleUpdate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)] ): """Change a user's account role (super admin only).""" @@ -375,7 +375,7 @@ async def update_account_role( async def update_super_admin_status( user_id: UUID, data: dict, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)] ): """Promote or demote a user to/from super admin (super admin only).""" @@ -414,7 +414,7 @@ async def update_super_admin_status( @router.put("/users/{user_id}/deactivate", response_model=UserResponse) async def deactivate_user( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)] ): """Deactivate a user account (super admin only).""" @@ -443,7 +443,7 @@ async def deactivate_user( @router.put("/users/{user_id}/activate", response_model=UserResponse) async def activate_user( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)] ): """Reactivate a user account (super admin only).""" @@ -467,7 +467,7 @@ async def activate_user( async def move_user_account( user_id: UUID, data: MoveUserAccount, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Move a user to a different account (super admin only).""" @@ -520,7 +520,7 @@ async def _get_user_subscription(user_id: UUID, db: AsyncSession) -> tuple[User, async def update_user_plan( user_id: UUID, data: SubscriptionPlanUpdate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Change a user's subscription plan (super admin only).""" @@ -539,7 +539,7 @@ async def update_user_plan( async def extend_user_trial( user_id: UUID, data: ExtendTrialRequest, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Extend or start a trial for a user's subscription (super admin only).""" @@ -569,7 +569,7 @@ async def extend_user_trial( async def admin_reset_password( user_id: UUID, data: AdminPasswordReset, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Admin-triggered password reset (super admin only). @@ -640,7 +640,7 @@ async def admin_reset_password( @router.put("/users/{user_id}/archive", response_model=UserResponse) async def archive_user( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Archive (soft delete) a user (super admin only).""" @@ -675,7 +675,7 @@ async def archive_user( @router.put("/users/{user_id}/restore", response_model=UserResponse) async def restore_user( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Restore an archived user (super admin only).""" @@ -700,7 +700,7 @@ async def restore_user( @router.get("/users/{user_id}/hard-delete-check", response_model=HardDeleteCheckResponse) async def hard_delete_check( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Check if a user can be hard-deleted (super admin only). Returns blockers.""" @@ -773,7 +773,7 @@ async def hard_delete_check( @router.delete("/users/{user_id}/hard-delete", status_code=status.HTTP_204_NO_CONTENT) async def hard_delete_user( user_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Permanently delete a user (super admin only). User must be archived first.""" @@ -833,7 +833,7 @@ async def hard_delete_user( @router.post("/invites", status_code=status.HTTP_201_CREATED) async def admin_create_invite( data: dict, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Quick-invite a user to an account (super admin only). diff --git a/backend/app/api/endpoints/admin_categories.py b/backend/app/api/endpoints/admin_categories.py index 36aa4abc..bfecc31e 100644 --- a/backend/app/api/endpoints/admin_categories.py +++ b/backend/app/api/endpoints/admin_categories.py @@ -4,7 +4,7 @@ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func -from app.core.database import get_db +from app.core.admin_database import get_admin_db from app.core.audit import log_audit from app.models.user import User from app.models.category import TreeCategory @@ -18,7 +18,7 @@ router = APIRouter(prefix="/admin/categories", tags=["admin-categories"]) @router.get("/global", response_model=list[GlobalCategoryResponse]) async def list_global_categories( - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """List all global categories (account_id IS NULL).""" @@ -46,7 +46,7 @@ async def list_global_categories( @router.post("/global", response_model=GlobalCategoryResponse, status_code=status.HTTP_201_CREATED) async def create_global_category( data: GlobalCategoryCreate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Create a global category.""" @@ -70,7 +70,7 @@ async def create_global_category( async def update_global_category( category_id: UUID, data: GlobalCategoryUpdate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Update a global category.""" @@ -111,7 +111,7 @@ async def update_global_category( @router.delete("/global/{category_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_global_category( category_id: UUID, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Delete (archive) a global category.""" diff --git a/backend/app/api/endpoints/admin_dashboard.py b/backend/app/api/endpoints/admin_dashboard.py index 33d8f564..90859b18 100644 --- a/backend/app/api/endpoints/admin_dashboard.py +++ b/backend/app/api/endpoints/admin_dashboard.py @@ -3,7 +3,7 @@ from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func -from app.core.database import get_db +from app.core.admin_database import get_admin_db from app.models.user import User from app.models.subscription import Subscription from app.models.tree import Tree @@ -16,7 +16,7 @@ router = APIRouter(prefix="/admin/dashboard", tags=["admin-dashboard"]) @router.get("/metrics", response_model=DashboardMetrics) async def get_dashboard_metrics( - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Get platform overview metrics.""" @@ -45,7 +45,7 @@ async def get_dashboard_metrics( @router.get("/activity", response_model=list[ActivityEntry]) async def get_dashboard_activity( - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Get recent audit log entries for activity feed.""" diff --git a/backend/app/api/endpoints/admin_gallery.py b/backend/app/api/endpoints/admin_gallery.py index 8292bfb4..d3cc61d6 100644 --- a/backend/app/api/endpoints/admin_gallery.py +++ b/backend/app/api/endpoints/admin_gallery.py @@ -12,7 +12,7 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import require_admin -from app.core.database import get_db +from app.core.admin_database import get_admin_db from app.models.script_template import ScriptTemplate from app.models.tree import Tree from app.models.user import User @@ -66,7 +66,7 @@ def _script_summary(script: ScriptTemplate) -> dict: @router.get("/featured") async def list_featured( - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """List all featured flows and scripts (super admin only).""" @@ -92,7 +92,7 @@ async def list_featured( @router.get("/items") async def list_all_items( - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """List ALL flows and scripts with their gallery status (super admin only).""" @@ -119,7 +119,7 @@ async def list_all_items( async def toggle_flow_featured( flow_id: UUID, body: FeatureToggle, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Toggle is_gallery_featured on a flow (super admin only).""" @@ -138,7 +138,7 @@ async def toggle_flow_featured( async def update_flow_sort_order( flow_id: UUID, body: SortOrderUpdate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Update gallery_sort_order on a flow (super admin only).""" @@ -157,7 +157,7 @@ async def update_flow_sort_order( async def toggle_script_featured( script_id: UUID, body: FeatureToggle, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Toggle is_gallery_featured on a script (super admin only).""" @@ -176,7 +176,7 @@ async def toggle_script_featured( async def update_script_sort_order( script_id: UUID, body: SortOrderUpdate, - db: Annotated[AsyncSession, Depends(get_db)], + db: Annotated[AsyncSession, Depends(get_admin_db)], current_user: Annotated[User, Depends(require_admin)], ): """Update gallery_sort_order on a script (super admin only)."""