Skip to content

Recover stuck PROCESSING meetings on app startup#32

Merged
julien731 merged 5 commits intodevelopfrom
feature/16-recover-stuck-processing-meetings
Mar 14, 2026
Merged

Recover stuck PROCESSING meetings on app startup#32
julien731 merged 5 commits intodevelopfrom
feature/16-recover-stuck-processing-meetings

Conversation

@julien731
Copy link
Copy Markdown
Member

@julien731 julien731 commented Mar 14, 2026

Closes: #16

Summary

On app restart, meetings left in PROCESSING status become orphaned since job state is in-memory only. This adds a startup recovery mechanism that scans all meetings and transitions any stuck PROCESSING meetings to ERROR status, enabling users to retry them via the existing retry button.

Approach

Added a recover_stuck_meetings() function in a new backend/services/recovery.py module, wired into FastAPI's lifespan context manager so it runs before the app starts serving requests. Each stuck meeting is individually recovered with error handling so one failure doesn't abort the rest.

No UI changes needed — ERROR status meetings already display the retry button.

Verification

  • 6 unit tests covering: recovery of processing meetings, ignoring non-processing meetings, mixed statuses, empty directory, malformed metadata, and logging output
  • Full test suite passes (112 tests)
  • Manual verification: created a meeting with status=processing in data dir, started the app, confirmed it was set to error with the correct message

Scans all meeting directories on startup for metadata with
status=processing and transitions them to error state with
a descriptive error message.
Adds a lifespan context manager that calls recover_stuck_meetings()
before the app starts serving requests.
- Add from __future__ import annotations to main.py
- Catch write errors per-meeting so one failure doesn't abort recovery
- Fix fragile test assertion ordering
@julien731
Copy link
Copy Markdown
Member Author

QA Confidence Verdict

What Was Verified

Check Result Method
AC1: Scan all meeting dirs for status=PROCESSING PASS Code inspection + unit tests
AC2: Set status to ERROR with message "Transcription interrupted by app restart" PASS Unit test assertion
AC3: Log each recovered meeting ID PASS Unit test with caplog
AC4: Retry button shows for recovered meetings NEEDS HUMAN Frontend unchanged; relies on existing error-state UI
Truth: Recovery runs before app serves requests PASS Lifespan context manager, before yield
Truth: Independent recovery (one failure doesn't abort others) PASS try/except per meeting + test with malformed JSON
Truth: Non-processing meetings not modified PASS Unit test verifies untouched metadata
All 112 tests pass PASS pytest tests/ -v

What Needs Human Eyes

  • Retry button UI: Confirm that a meeting recovered to ERROR status displays the retry button correctly in the browser
  • Visual state: Verify the error badge and message render properly on the meeting list and detail views

Risk Areas

  • No integration test verifying that main.py lifespan actually invokes recover_stuck_meetings() (low risk -- wiring is 1 line)
  • Recovery is synchronous and blocking; a very large number of stuck meetings could delay startup (unlikely in practice)

Suggested QA Focus

  • Quick glance: Manually create a meeting dir with status: processing in metadata.json, restart the app, and confirm it shows as error with retry button
  • Estimated effort: 2-3 minutes

@julien731 julien731 self-assigned this Mar 14, 2026
@julien731 julien731 added the feature New feature or enhancement label Mar 14, 2026
@julien731 julien731 merged commit 99d1247 into develop Mar 14, 2026
2 checks passed
@julien731 julien731 deleted the feature/16-recover-stuck-processing-meetings branch March 14, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recover stuck PROCESSING meetings on app startup

1 participant