feat(case): add GET /case/{id} detail view and Jinja template; link from dashboard table; eager-load related data; 404 handling and logging

This commit is contained in:
HotSwapp
2025-10-06 19:21:58 -05:00
parent 6174df42b4
commit 2e49340663
2 changed files with 239 additions and 2 deletions

View File

@@ -15,7 +15,7 @@ from starlette.middleware.sessions import SessionMiddleware
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import or_
from dotenv import load_dotenv
from starlette.middleware.base import BaseHTTPMiddleware
@@ -314,3 +314,58 @@ async def admin_panel(request: Request, db: Session = Depends(get_db)):
"request": request,
"user": user
})
@app.get("/case/{case_id}")
async def case_detail(
request: Request,
case_id: int,
db: Session = Depends(get_db),
):
"""
Case detail view.
Displays detailed information for a single case and its related client and
associated records (transactions, documents, payments).
"""
# Check authentication
user = get_current_user_from_session(request.session)
if not user:
return RedirectResponse(url="/login", status_code=302)
# Fetch case with related entities eagerly loaded to avoid lazy-load issues
case_obj = (
db.query(Case)
.options(
joinedload(Case.client),
joinedload(Case.transactions),
joinedload(Case.documents),
joinedload(Case.payments),
)
.filter(Case.id == case_id)
.first()
)
if not case_obj:
logger.warning("Case not found: id=%s", case_id)
return templates.TemplateResponse(
"case.html",
{
"request": request,
"user": user,
"case": None,
"error": "Case not found",
},
status_code=404,
)
logger.info("Rendering case detail: id=%s, file_no='%s'", case_obj.id, case_obj.file_no)
return templates.TemplateResponse(
"case.html",
{
"request": request,
"user": user,
"case": case_obj,
},
)