Files
orion/app/routes/admin_pages.py
Samir Boulahtit 9db0da25ec feat: implement code quality dashboard with architecture violation tracking
Implement comprehensive code quality dashboard (Phase 2-4) to track and manage
architecture violations found by the validation script.

Backend Implementation:
- Add JSON output support to validate_architecture.py script
- Create CodeQualityService with scan management, violation tracking, and statistics
- Implement REST API endpoints for code quality management:
  * POST /admin/code-quality/scan - trigger new architecture scan
  * GET /admin/code-quality/scans - list scan history
  * GET /admin/code-quality/violations - list violations with filtering/pagination
  * GET /admin/code-quality/violations/{id} - get violation details
  * POST /admin/code-quality/violations/{id}/assign - assign to developer
  * POST /admin/code-quality/violations/{id}/resolve - mark as resolved
  * POST /admin/code-quality/violations/{id}/ignore - mark as ignored
  * POST /admin/code-quality/violations/{id}/comments - add comments
  * GET /admin/code-quality/stats - dashboard statistics
- Fix architecture_scan model imports to use app.core.database

Frontend Implementation:
- Create code quality dashboard page (code-quality-dashboard.html)
  * Summary cards for total violations, errors, warnings, health score
  * Status breakdown (open, assigned, resolved, ignored)
  * Trend visualization for last 7 scans
  * Top violating files list
  * Violations by rule and module
  * Quick action links
- Create violations list page (code-quality-violations.html)
  * Filterable table by severity, status, rule ID, file path
  * Pagination support
  * Violation detail view links
- Add Alpine.js components (code-quality-dashboard.js, code-quality-violations.js)
  * Dashboard state management and scan triggering
  * Violations list with filtering and pagination
  * API integration with authentication
- Add "Code Quality" navigation link in admin sidebar (Developer Tools section)

Routes:
- GET /admin/code-quality - dashboard page
- GET /admin/code-quality/violations - violations list
- GET /admin/code-quality/violations/{id} - violation details

Features:
- Real-time scan execution from UI
- Technical debt score calculation (0-100 scale)
- Violation workflow: open → assigned → resolved/ignored
- Trend tracking across multiple scans
- File and module-level insights
- Assignment system with priorities and due dates
- Collaborative comments on violations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 09:40:14 +01:00

559 lines
18 KiB
Python

# app/routes/admin_pages.py
"""
Admin HTML page routes using Jinja2 templates.
These routes return rendered HTML pages (response_class=HTMLResponse).
Separate from admin API routes which return JSON data.
All routes require admin authentication except /login.
Authentication failures redirect to /admin/login.
Routes:
- GET / → Redirect to /admin/login
- GET /login → Admin login page (no auth)
- GET /dashboard → Admin dashboard (auth required)
- GET /vendors → Vendor list page (auth required)
- GET /vendors/create → Create vendor form (auth required)
- GET /vendors/{vendor_code} → Vendor details (auth required)
- GET /vendors/{vendor_code}/edit → Edit vendor form (auth required)
- GET /vendors/{vendor_code}/domains → Vendor domains management (auth required)
- GET /vendors/{vendor_code}/theme → Vendor theme editor (auth required)
- GET /users → User management page (auth required)
- GET /imports → Import history page (auth required)
- GET /settings → Settings page (auth required)
- GET /platform-homepage → Platform homepage manager (auth required)
- GET /content-pages → Content pages list (auth required)
- GET /content-pages/create → Create content page (auth required)
- GET /content-pages/{page_id}/edit → Edit content page (auth required)
- GET /code-quality → Code quality dashboard (auth required)
- GET /code-quality/violations → Violations list (auth required)
- GET /code-quality/violations/{violation_id} → Violation details (auth required)
"""
from fastapi import APIRouter, Request, Depends, Path
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from typing import Optional
from app.api.deps import (
get_current_admin_from_cookie_or_header,
get_current_admin_optional,
get_db
)
from models.database.user import User
router = APIRouter()
templates = Jinja2Templates(directory="app/templates")
# ============================================================================
# PUBLIC ROUTES (No Authentication Required)
# ============================================================================
@router.get("/", response_class=RedirectResponse, include_in_schema=False)
async def admin_root(
current_user: Optional[User] = Depends(get_current_admin_optional)
):
"""
Redirect /admin/ based on authentication status.
- Authenticated admin users → /admin/dashboard
- Unauthenticated users → /admin/login
"""
if current_user:
# User is already logged in as admin, redirect to dashboard
return RedirectResponse(url="/admin/dashboard", status_code=302)
return RedirectResponse(url="/admin/login", status_code=302)
@router.get("/login", response_class=HTMLResponse, include_in_schema=False)
async def admin_login_page(
request: Request,
current_user: Optional[User] = Depends(get_current_admin_optional)
):
"""
Render admin login page.
If user is already authenticated as admin, redirect to dashboard.
Otherwise, show login form.
"""
if current_user:
# User is already logged in as admin, redirect to dashboard
return RedirectResponse(url="/admin/dashboard", status_code=302)
return templates.TemplateResponse(
"admin/login.html",
{"request": request}
)
# ============================================================================
# AUTHENTICATED ROUTES (Admin Only)
# ============================================================================
@router.get("/dashboard", response_class=HTMLResponse, include_in_schema=False)
async def admin_dashboard_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render admin dashboard page.
Shows platform statistics and recent activity.
"""
return templates.TemplateResponse(
"admin/dashboard.html",
{
"request": request,
"user": current_user,
}
)
# ============================================================================
# VENDOR MANAGEMENT ROUTES
# ============================================================================
@router.get("/vendors", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendors_list_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendors management page.
Shows list of all vendors with stats.
"""
return templates.TemplateResponse(
"admin/vendors.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/vendors/create", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_create_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendor creation form.
"""
return templates.TemplateResponse(
"admin/vendor-create.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/vendors/{vendor_code}", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_detail_page(
request: Request,
vendor_code: str = Path(..., description="Vendor code"),
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendor detail page.
Shows full vendor information.
"""
return templates.TemplateResponse(
"admin/vendor-detail.html",
{
"request": request,
"user": current_user,
"vendor_code": vendor_code,
}
)
@router.get("/vendors/{vendor_code}/edit", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_edit_page(
request: Request,
vendor_code: str = Path(..., description="Vendor code"),
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendor edit form.
"""
return templates.TemplateResponse(
"admin/vendor-edit.html",
{
"request": request,
"user": current_user,
"vendor_code": vendor_code,
}
)
# ============================================================================
# VENDOR DOMAINS ROUTES
# ============================================================================
@router.get("/vendors/{vendor_code}/domains", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_domains_page(
request: Request,
vendor_code: str = Path(..., description="Vendor code"),
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendor domains management page.
Shows custom domains, verification status, and DNS configuration.
"""
return templates.TemplateResponse(
"admin/vendor-domains.html",
{
"request": request,
"user": current_user,
"vendor_code": vendor_code,
}
)
# ============================================================================
# VENDOR THEMES ROUTES
# ============================================================================
@router.get("/vendors/{vendor_code}/theme", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_theme_page(
request: Request,
vendor_code: str = Path(..., description="Vendor code"),
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendor theme customization page.
Allows admins to customize colors, fonts, layout, and branding.
"""
return templates.TemplateResponse(
"admin/vendor-theme.html",
{
"request": request,
"user": current_user,
"vendor_code": vendor_code,
}
)
# ============================================================================
# USER MANAGEMENT ROUTES
# ============================================================================
@router.get("/users", response_class=HTMLResponse, include_in_schema=False)
async def admin_users_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render users management page.
Shows list of all platform users.
"""
return templates.TemplateResponse(
"admin/users.html",
{
"request": request,
"user": current_user,
}
)
# ============================================================================
# IMPORT MANAGEMENT ROUTES
# ============================================================================
@router.get("/imports", response_class=HTMLResponse, include_in_schema=False)
async def admin_imports_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render imports management page.
Shows import history and status.
"""
return templates.TemplateResponse(
"admin/imports.html",
{
"request": request,
"user": current_user,
}
)
# ============================================================================
# SETTINGS ROUTES
# ============================================================================
@router.get("/settings", response_class=HTMLResponse, include_in_schema=False)
async def admin_settings_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render admin settings page.
Platform configuration and preferences.
"""
return templates.TemplateResponse(
"admin/settings.html",
{
"request": request,
"user": current_user,
}
)
# ============================================================================
# CONTENT MANAGEMENT SYSTEM (CMS) ROUTES
# ============================================================================
@router.get("/platform-homepage", response_class=HTMLResponse, include_in_schema=False)
async def admin_platform_homepage_manager(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render platform homepage manager.
Allows editing the main platform homepage with template selection.
"""
return templates.TemplateResponse(
"admin/platform-homepage.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/content-pages", response_class=HTMLResponse, include_in_schema=False)
async def admin_content_pages_list(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render content pages list.
Shows all platform defaults and vendor overrides with filtering.
"""
return templates.TemplateResponse(
"admin/content-pages.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/content-pages/create", response_class=HTMLResponse, include_in_schema=False)
async def admin_content_page_create(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render create content page form.
Allows creating new platform defaults or vendor-specific pages.
"""
return templates.TemplateResponse(
"admin/content-page-edit.html",
{
"request": request,
"user": current_user,
"page_id": None, # Indicates this is a create operation
}
)
@router.get("/content-pages/{page_id}/edit", response_class=HTMLResponse, include_in_schema=False)
async def admin_content_page_edit(
request: Request,
page_id: int = Path(..., description="Content page ID"),
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render edit content page form.
Allows editing existing platform or vendor content pages.
"""
return templates.TemplateResponse(
"admin/content-page-edit.html",
{
"request": request,
"user": current_user,
"page_id": page_id,
}
)
# ============================================================================
# DEVELOPER TOOLS - COMPONENTS & TESTING
# ============================================================================
@router.get("/components", response_class=HTMLResponse, include_in_schema=False)
async def admin_components_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render UI components library page.
Reference for all available UI components.
"""
return templates.TemplateResponse(
"admin/components.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/icons", response_class=HTMLResponse, include_in_schema=False)
async def admin_icons_page(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render icons browser page.
Browse and search all available icons.
"""
return templates.TemplateResponse(
"admin/icons.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/testing", response_class=HTMLResponse, include_in_schema=False)
async def admin_testing_hub(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render testing hub page.
Central hub for all test suites and QA tools.
"""
return templates.TemplateResponse(
"admin/testing-hub.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/test/auth-flow", response_class=HTMLResponse, include_in_schema=False)
async def admin_test_auth_flow(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render authentication flow testing page.
Tests login, logout, token expiration, and protected routes.
"""
return templates.TemplateResponse(
"admin/test-auth-flow.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/test/vendors-users-migration", response_class=HTMLResponse, include_in_schema=False)
async def admin_test_vendors_users_migration(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render vendors and users migration testing page.
Tests CRUD operations, data migration, and form validation.
"""
return templates.TemplateResponse(
"admin/test-vendors-users-migration.html",
{
"request": request,
"user": current_user,
}
)
# ============================================================================
# CODE QUALITY & ARCHITECTURE ROUTES
# ============================================================================
@router.get("/code-quality", response_class=HTMLResponse, include_in_schema=False)
async def admin_code_quality_dashboard(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render code quality dashboard.
Shows architecture violations, trends, and technical debt score.
"""
return templates.TemplateResponse(
"admin/code-quality-dashboard.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/code-quality/violations", response_class=HTMLResponse, include_in_schema=False)
async def admin_code_quality_violations(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render violations list page.
Shows all violations with filtering and sorting options.
"""
return templates.TemplateResponse(
"admin/code-quality-violations.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/code-quality/violations/{violation_id}", response_class=HTMLResponse, include_in_schema=False)
async def admin_code_quality_violation_detail(
request: Request,
violation_id: int = Path(..., description="Violation ID"),
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
"""
Render violation detail page.
Shows violation details, code context, assignments, and comments.
"""
return templates.TemplateResponse(
"admin/code-quality-violation-detail.html",
{
"request": request,
"user": current_user,
"violation_id": violation_id,
}
)