Fix #3: Avoid detached SQLAlchemy objects in middleware — store member_id, re-fetch in endpoints
Some checks failed
Deploy Tracker / deploy (push) Failing after 5s
Some checks failed
Deploy Tracker / deploy (push) Failing after 5s
This commit is contained in:
parent
dc6556074e
commit
b67587b647
@ -19,11 +19,11 @@ UPLOAD_DIR = os.environ.get("UPLOAD_DIR", "/data/uploads")
|
||||
MAX_FILE_SIZE = 50 * 1024 * 1024 # 50MB
|
||||
|
||||
|
||||
def _get_member(request: Request) -> Member:
|
||||
member = getattr(request.state, "member", None)
|
||||
if not member:
|
||||
def _get_member_id(request: Request) -> str:
|
||||
member_id = getattr(request.state, "member_id", None)
|
||||
if not member_id:
|
||||
raise HTTPException(401, "Not authenticated")
|
||||
return member
|
||||
return member_id
|
||||
|
||||
|
||||
@router.post("/upload")
|
||||
@ -33,7 +33,7 @@ async def upload_file(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Upload a file and return attachment metadata (not yet linked to a message)."""
|
||||
member = _get_member(request)
|
||||
member_id = _get_member_id(request)
|
||||
|
||||
# Read file
|
||||
content = await file.read()
|
||||
|
||||
@ -53,10 +53,15 @@ def project_file_out(f: ProjectFile) -> ProjectFileOut:
|
||||
updated_at=f.updated_at.isoformat() if f.updated_at else "",
|
||||
)
|
||||
|
||||
def _get_member(request: Request) -> Member:
|
||||
member = getattr(request.state, "member", None)
|
||||
if not member:
|
||||
async def _get_member(request: Request, db: AsyncSession) -> Member:
|
||||
"""Get member from request state, re-fetched from DB to avoid detached objects."""
|
||||
member_id = getattr(request.state, "member_id", None)
|
||||
if not member_id:
|
||||
raise HTTPException(401, "Not authenticated")
|
||||
result = await db.execute(select(Member).where(Member.id == uuid.UUID(member_id)))
|
||||
member = result.scalar_one_or_none()
|
||||
if not member:
|
||||
raise HTTPException(401, "Member not found")
|
||||
return member
|
||||
|
||||
|
||||
@ -97,7 +102,7 @@ async def upload_project_file(
|
||||
description: Optional[str] = Form(None),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
member = _get_member(request)
|
||||
member = await _get_member(request, db)
|
||||
project = await _get_project(slug, db)
|
||||
|
||||
content = await file.read()
|
||||
@ -227,7 +232,7 @@ async def update_project_file(
|
||||
data: ProjectFileUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
member = _get_member(request)
|
||||
member = await _get_member(request, db)
|
||||
project = await _get_project(slug, db)
|
||||
|
||||
result = await db.execute(
|
||||
@ -257,7 +262,7 @@ async def delete_project_file(
|
||||
file_id: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
member = _get_member(request)
|
||||
member = await _get_member(request, db)
|
||||
project = await _get_project(slug, db)
|
||||
|
||||
result = await db.execute(
|
||||
|
||||
@ -132,6 +132,7 @@ async def auth_middleware(request: Request, call_next):
|
||||
return JSONResponse(status_code=401, content={"error": "Invalid or expired token"})
|
||||
|
||||
request.state.member = member
|
||||
request.state.member_id = str(member.id)
|
||||
return await call_next(request)
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user