Store all mode results (OCR, Describe, Freeform) in a single job record

- DB: add describe_text and freeform_text columns (ALTER TABLE IF NOT EXISTS)
- Backend: commit and review endpoints accept/persist all three text fields
- App: accumulate results per mode in state; tabs appear when >1 mode run;
  all results sent on Commit Job
- JobDetail: tabbed text panel shows whichever fields are populated, all editable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Aaron Roberts
2026-06-10 12:28:01 +01:00
parent 4ab87d2e6f
commit ae0ac3af59
4 changed files with 163 additions and 46 deletions

View File

@@ -45,6 +45,15 @@ def init_db():
cur.execute("""
CREATE INDEX IF NOT EXISTS ocr_jobs_submitted_at_idx ON ocr_jobs(submitted_at DESC)
""")
# Add columns introduced after initial schema (safe to run repeatedly)
cur.execute("""
ALTER TABLE ocr_jobs
ADD COLUMN IF NOT EXISTS describe_text TEXT
""")
cur.execute("""
ALTER TABLE ocr_jobs
ADD COLUMN IF NOT EXISTS freeform_text TEXT
""")
# Unique constraint: prevent duplicate (author, chapter, page) submissions.
# Applies only when all three fields are non-null.
cur.execute("""

View File

@@ -607,6 +607,8 @@ class ReviewRequest(BaseModel):
book: Optional[str] = None
chapter: Optional[str] = None
page: Optional[str] = None
describe_text: Optional[str] = None
freeform_text: Optional[str] = None
def _job_row_to_dict(row) -> Dict[str, Any]:
@@ -628,6 +630,8 @@ async def commit_job(
chapter: str = Form(""),
page: str = Form(""),
ocr_text: str = Form(""),
describe_text: str = Form(""),
freeform_text: str = Form(""),
mode: str = Form("plain_ocr"),
):
"""Commit an OCR job: save the image and insert a DB record."""
@@ -660,13 +664,13 @@ async def commit_job(
"""
INSERT INTO ocr_jobs
(id, author, book, chapter, page, image_path, original_filename,
ocr_text, mode, status)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, 'unreviewed')
ocr_text, describe_text, freeform_text, mode, status)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 'unreviewed')
RETURNING *
""",
(job_id, author or None, book or None, chapter or None,
page or None, image_path, original_filename,
ocr_text or None, mode),
ocr_text or None, describe_text or None, freeform_text or None, mode),
)
row = cur.fetchone()
except Exception as exc:
@@ -852,7 +856,9 @@ async def review_job(job_id: str, body: ReviewRequest):
author = %s,
book = %s,
chapter = %s,
page = %s
page = %s,
describe_text = %s,
freeform_text = %s
WHERE id = %s
RETURNING *
""",
@@ -863,6 +869,8 @@ async def review_job(job_id: str, body: ReviewRequest):
body.book or None,
body.chapter or None,
body.page or None,
body.describe_text,
body.freeform_text,
job_id,
),
)