diff --git a/document-parser/domain/models.py b/document-parser/domain/models.py index 66fc3fe..3faec9a 100644 --- a/document-parser/domain/models.py +++ b/document-parser/domain/models.py @@ -53,6 +53,7 @@ class AnalysisJob: document_filename: str | None = None def mark_running(self) -> None: + """Transition to RUNNING and record the start timestamp.""" self.status = AnalysisStatus.RUNNING self.started_at = _utcnow() @@ -64,6 +65,7 @@ class AnalysisJob: document_json: str | None = None, chunks_json: str | None = None, ) -> None: + """Transition to COMPLETED with conversion results.""" self.status = AnalysisStatus.COMPLETED self.content_markdown = markdown self.content_html = html @@ -73,6 +75,7 @@ class AnalysisJob: self.completed_at = _utcnow() def mark_failed(self, error: str) -> None: + """Transition to FAILED with an error message.""" self.status = AnalysisStatus.FAILED self.error_message = error self.completed_at = _utcnow() diff --git a/document-parser/domain/value_objects.py b/document-parser/domain/value_objects.py index 26e19fc..7c91845 100644 --- a/document-parser/domain/value_objects.py +++ b/document-parser/domain/value_objects.py @@ -39,6 +39,7 @@ class ConversionOptions: images_scale: float = 1.0 def is_default(self) -> bool: + """Return True if all options match their defaults.""" return self == ConversionOptions() @@ -60,6 +61,7 @@ class ChunkingOptions: repeat_table_header: bool = True def is_default(self) -> bool: + """Return True if all options match their defaults.""" return self == ChunkingOptions() diff --git a/document-parser/persistence/analysis_repo.py b/document-parser/persistence/analysis_repo.py index 9d6a7a7..deb08b6 100644 --- a/document-parser/persistence/analysis_repo.py +++ b/document-parser/persistence/analysis_repo.py @@ -42,6 +42,7 @@ _SELECT_WITH_DOC = """ async def insert(job: AnalysisJob) -> None: + """Persist a new analysis job record.""" async with get_connection() as db: await db.execute( """INSERT INTO analysis_jobs (id, document_id, status, created_at) @@ -52,6 +53,7 @@ async def insert(job: AnalysisJob) -> None: async def find_all(*, limit: int = 200, offset: int = 0) -> list[AnalysisJob]: + """Return analysis jobs with document info, newest first.""" async with get_connection() as db: cursor = await db.execute( f"{_SELECT_WITH_DOC} ORDER BY aj.created_at DESC LIMIT ? OFFSET ?", @@ -62,6 +64,7 @@ async def find_all(*, limit: int = 200, offset: int = 0) -> list[AnalysisJob]: async def find_by_id(job_id: str) -> AnalysisJob | None: + """Find an analysis job by ID (with document filename), or return None.""" async with get_connection() as db: cursor = await db.execute(f"{_SELECT_WITH_DOC} WHERE aj.id = ?", (job_id,)) row = await cursor.fetchone() @@ -69,6 +72,7 @@ async def find_by_id(job_id: str) -> AnalysisJob | None: async def update_status(job: AnalysisJob) -> None: + """Persist all mutable fields of an analysis job (status, results, timestamps).""" async with get_connection() as db: await db.execute( """UPDATE analysis_jobs @@ -104,6 +108,7 @@ async def update_chunks(job_id: str, chunks_json: str) -> bool: async def delete(job_id: str) -> bool: + """Delete an analysis job by ID. Returns True if a row was removed.""" async with get_connection() as db: cursor = await db.execute("DELETE FROM analysis_jobs WHERE id = ?", (job_id,)) await db.commit() diff --git a/document-parser/persistence/document_repo.py b/document-parser/persistence/document_repo.py index 04ac473..3c946de 100644 --- a/document-parser/persistence/document_repo.py +++ b/document-parser/persistence/document_repo.py @@ -26,6 +26,7 @@ def _row_to_document(row) -> Document: async def insert(doc: Document) -> None: + """Persist a new document record.""" async with get_connection() as db: await db.execute( """INSERT INTO documents (id, filename, content_type, file_size, page_count, storage_path, created_at) @@ -44,6 +45,7 @@ async def insert(doc: Document) -> None: async def find_all(*, limit: int = 200, offset: int = 0) -> list[Document]: + """Return documents ordered by creation date (newest first).""" async with get_connection() as db: cursor = await db.execute( "SELECT * FROM documents ORDER BY created_at DESC LIMIT ? OFFSET ?", @@ -54,6 +56,7 @@ async def find_all(*, limit: int = 200, offset: int = 0) -> list[Document]: async def find_by_id(doc_id: str) -> Document | None: + """Find a document by its ID, or return None.""" async with get_connection() as db: cursor = await db.execute("SELECT * FROM documents WHERE id = ?", (doc_id,)) row = await cursor.fetchone() @@ -61,6 +64,7 @@ async def find_by_id(doc_id: str) -> Document | None: async def update_page_count(doc_id: str, page_count: int) -> None: + """Update the page count after conversion has determined it.""" async with get_connection() as db: await db.execute( "UPDATE documents SET page_count = ? WHERE id = ?", @@ -70,6 +74,7 @@ async def update_page_count(doc_id: str, page_count: int) -> None: async def delete(doc_id: str) -> bool: + """Delete a document by ID. Returns True if a row was removed.""" async with get_connection() as db: cursor = await db.execute("DELETE FROM documents WHERE id = ?", (doc_id,)) await db.commit() diff --git a/document-parser/services/analysis_service.py b/document-parser/services/analysis_service.py index 74b8b28..93c556f 100644 --- a/document-parser/services/analysis_service.py +++ b/document-parser/services/analysis_service.py @@ -83,12 +83,15 @@ class AnalysisService: return job async def find_all(self) -> list[AnalysisJob]: + """Return all analysis jobs, newest first.""" return await analysis_repo.find_all() async def find_by_id(self, job_id: str) -> AnalysisJob | None: + """Find an analysis job by ID, or return None.""" return await analysis_repo.find_by_id(job_id) async def delete(self, job_id: str) -> bool: + """Delete an analysis job. Returns True if it existed.""" return await analysis_repo.delete(job_id) async def rechunk(self, job_id: str, chunking_options: dict) -> list[ChunkResult]: diff --git a/document-parser/services/document_service.py b/document-parser/services/document_service.py index 3b564a8..d54ebfb 100644 --- a/document-parser/services/document_service.py +++ b/document-parser/services/document_service.py @@ -63,10 +63,12 @@ async def upload(filename: str, content_type: str, file_content: bytes) -> Docum async def find_all() -> list[Document]: + """Return all documents, newest first.""" return await document_repo.find_all() async def find_by_id(doc_id: str) -> Document | None: + """Find a document by its ID, or return None.""" return await document_repo.find_by_id(doc_id)