refactor: independent sessions for page-split + URL-based pipeline navigation

Page-split now creates independent sessions (no parent_session_id),
parent marked as status='split' and hidden from list. Navigation uses
useSearchParams for URL-based step tracking (browser back/forward works).
page.tsx reduced from 684 to 443 lines via usePipelineNavigation hook.

Box sub-sessions (column detection) remain unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-24 17:05:33 +01:00
parent f34340de9c
commit f931091b57
9 changed files with 368 additions and 391 deletions

View File

@@ -238,7 +238,7 @@ async def list_sessions_db(
"""
pool = await get_pool()
async with pool.acquire() as conn:
where = "" if include_sub_sessions else "WHERE parent_session_id IS NULL"
where = "" if include_sub_sessions else "WHERE parent_session_id IS NULL AND (status IS NULL OR status != 'split')"
rows = await conn.fetch(f"""
SELECT id, name, filename, status, current_step,
document_category, doc_type,

View File

@@ -191,12 +191,12 @@ async def get_session_info(session_id: str):
if session.get("ground_truth"):
result["ground_truth"] = session["ground_truth"]
# Sub-session info
# Box sub-session info (zone_type='box' from column detection — NOT page-split)
if session.get("parent_session_id"):
result["parent_session_id"] = session["parent_session_id"]
result["box_index"] = session.get("box_index")
else:
# Check for sub-sessions
# Check for box sub-sessions (column detection creates these)
subs = await get_sub_sessions(session_id)
if subs:
result["sub_sessions"] = [

View File

@@ -238,8 +238,8 @@ async def detect_page_split(session_id: str):
"duration_seconds": round(duration, 2),
}
# Mark parent session as split (store info in crop_result for backward compat)
await update_session_db(session_id, crop_result=split_info)
# Mark parent session as split and hidden from session list
await update_session_db(session_id, crop_result=split_info, status='split')
cached["crop_result"] = split_info
await _append_pipeline_log(session_id, "page_split", {
@@ -346,6 +346,7 @@ async def auto_crop(session_id: str):
cropped_png=png_buf.tobytes() if ok else b"",
crop_result=crop_info,
current_step=5,
status='split',
)
logger.info(
@@ -461,8 +462,6 @@ async def _create_page_sub_sessions(
name=sub_name,
filename=parent_filename,
original_png=page_png,
parent_session_id=parent_session_id,
box_index=pi,
)
# Pre-populate: set cropped = original (already cropped)
@@ -540,8 +539,6 @@ async def _create_page_sub_sessions_full(
name=sub_name,
filename=parent_filename,
original_png=page_png,
parent_session_id=parent_session_id,
box_index=pi,
)
# start_step=2 → ready for deskew (orientation already done on spread)
@@ -553,7 +550,6 @@ async def _create_page_sub_sessions_full(
"id": sub_id,
"filename": parent_filename,
"name": sub_name,
"parent_session_id": parent_session_id,
"original_bgr": page_bgr,
"oriented_bgr": None,
"cropped_bgr": None,