Files
gh-christianlouis-docuelevate/app/utils/file_queries.py
T
copilot-swe-agent[bot] 8edc11da04 refactor: extract shared file-status query logic into utility function
- Created app/utils/file_queries.py with apply_status_filter function
- Updated app/api/files.py to use shared function
- Updated app/views/files.py to use shared function
- Removed unused 'or_' import from app/api/files.py
- Added comprehensive tests in tests/test_file_queries.py
- All tests pass (10 new tests, 14 existing tests verified)

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-10 20:40:11 +00:00

73 lines
2.7 KiB
Python

"""
Shared file query utilities for filtering files by processing status.
This module contains reusable query logic for filtering FileRecord objects
based on their processing status (pending, processing, failed, completed).
"""
from typing import Optional
from sqlalchemy import or_
from sqlalchemy.orm import Query, Session
from app.models import FileRecord, ProcessingLog
def apply_status_filter(query: Query, db: Session, status: Optional[str]) -> Query:
"""
Apply status filter to a FileRecord query.
This function modifies a SQLAlchemy query to filter files based on their
processing status by examining associated ProcessingLog entries.
Args:
query: The base SQLAlchemy query for FileRecord objects
db: Database session for creating subqueries
status: Status filter to apply. Valid values:
- "pending": Files with no ProcessingLog entries
- "processing": Files with in_progress logs
- "failed": Files with failure logs
- "completed": Files with success logs but no failures or in_progress
- None: No filter applied (returns query unchanged)
Returns:
Modified query with status filter applied
Examples:
>>> query = db.query(FileRecord)
>>> query = apply_status_filter(query, db, "completed")
>>> files = query.all()
"""
if not status:
return query
# Subquery to get file IDs matching the status
if status == "pending":
# Files with no logs
subq = db.query(ProcessingLog.file_id).distinct()
query = query.filter(~FileRecord.id.in_(subq))
elif status == "processing":
# Files with in_progress logs
subq = db.query(ProcessingLog.file_id).filter(ProcessingLog.status == "in_progress").distinct()
query = query.filter(FileRecord.id.in_(subq))
elif status == "failed":
# Files with failure logs
subq = db.query(ProcessingLog.file_id).filter(ProcessingLog.status == "failure").distinct()
query = query.filter(FileRecord.id.in_(subq))
elif status == "completed":
# Files with success logs but no failures or in_progress
success_files = db.query(ProcessingLog.file_id).filter(ProcessingLog.status == "success").distinct().subquery()
failed_files = (
db.query(ProcessingLog.file_id)
.filter(or_(ProcessingLog.status == "failure", ProcessingLog.status == "in_progress"))
.distinct()
.subquery()
)
query = query.filter(FileRecord.id.in_(db.query(success_files.c.file_id))).filter(
~FileRecord.id.in_(db.query(failed_files.c.file_id))
)
return query