feat: implement full admin panel with dashboard, user management, and platform settings
Adds complete super_admin panel with 9 pages and account owner categories page. Backend includes 5 new DB tables, ~25 API endpoints, settings manager with in-memory cache, and 29 integration tests. Frontend includes reusable admin components (DataTable, Pagination, ActionMenu, etc.) with code-split lazy loading. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,9 @@ from sqlalchemy import select, func
|
||||
from app.core.database import get_db
|
||||
from app.core.audit import log_audit
|
||||
from app.models.user import User
|
||||
from app.models.account import Account
|
||||
from app.schemas.user import UserResponse, RoleUpdate, AccountRoleUpdate
|
||||
from app.schemas.admin import MoveUserAccount
|
||||
from app.api.deps import require_admin
|
||||
|
||||
router = APIRouter(prefix="/admin", tags=["admin"])
|
||||
@@ -167,3 +169,32 @@ async def activate_user(
|
||||
await db.commit()
|
||||
await db.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
@router.put("/users/{user_id}/move-account", response_model=UserResponse)
|
||||
async def move_user_account(
|
||||
user_id: UUID,
|
||||
data: MoveUserAccount,
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
current_user: Annotated[User, Depends(require_admin)],
|
||||
):
|
||||
"""Move a user to a different account (super admin only)."""
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
|
||||
result = await db.execute(select(Account).where(Account.display_code == data.display_code))
|
||||
target_account = result.scalar_one_or_none()
|
||||
if not target_account:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Target account not found")
|
||||
|
||||
old_account_id = user.account_id
|
||||
user.account_id = target_account.id
|
||||
user.account_role = "engineer" # Reset to engineer on move
|
||||
|
||||
await log_audit(db, current_user.id, "user.move_account", "user", user.id,
|
||||
{"old_account_id": str(old_account_id), "new_account_id": str(target_account.id)})
|
||||
await db.commit()
|
||||
await db.refresh(user)
|
||||
return user
|
||||
|
||||
Reference in New Issue
Block a user