Skip to content

Make file analysis actually async and surface status in the UI#23

Merged
csengor merged 4 commits into
kaplanPRO:0.6.x-devfrom
csengor:feat/analysis-polling
May 16, 2026
Merged

Make file analysis actually async and surface status in the UI#23
csengor merged 4 commits into
kaplanPRO:0.6.x-devfrom
csengor:feat/analysis-polling

Conversation

@csengor
Copy link
Copy Markdown
Member

@csengor csengor commented May 16, 2026

Summary

  • Fix the blocking analyze request. NewProjectReportThread(self).run() was running the analysis synchronously in the request worker (.run() executes in the current thread; .start() is what spawns a new one). Switched to .start() and wrapped the thread body in try/finally: connection.close() so the per-thread DB connection is released.
  • Surface analysis progress in the UI. Reports are now rendered as a 3-column table (Created / Status / open) with the same look as the Files and Reference tables. The project view no longer filters out non-Complete reports, so in-progress ones appear too.
  • Eliminate the manual refresh. Clicking Analyze immediately injects a "Ready for Processing" row into the Reports table; the existing 5-second polling now updates that row's status badge as the report moves 1 → 2 → 3. The "Your report is ready. Please refresh this page" toast is gone. On page load, any row that isn't Complete resumes polling, so a mid-flight refresh keeps tracking the same report.
  • Fix the report-page breadcrumb. It was using daisyUI's breadcrumb (singular) on a bare <ul>, which rendered as a plain bulleted list with no separators. Switched to the wrapping <div class="text-sm breadcrumbs"><ul>…</ul></div> pattern used by every other breadcrumbed template.

Test plan

  • python manage.py test — 256 tests pass (existing test that asserted the bug, test_save_with_status_1_triggers_thread, was updated to mock .start()).
  • ruff check . and ruff format --check . — clean.
  • In a browser: right-click a file → Analyze. Confirm the POST returns in well under a second, a "Ready for Processing" row appears immediately, the badge transitions through "Processing" and lands on "Complete" without a page reload, and no toast fires.
  • Refresh the project page mid-analysis. Confirm the in-progress row is server-rendered, and the on-load JS picks polling back up so the badge keeps updating.
  • Open a finished report and confirm the breadcrumb (Projects > {project} > Report — {date}) renders with > separators and the same styling as the project page.

🤖 Generated with Claude Code

csengor and others added 4 commits May 15, 2026 23:01
`ProjectReport.save()` was invoking `NewProjectReportThread(self).run()`,
which executes the thread body in the current thread instead of spawning
a new one. The analyze view blocked for the full difflib pass before
returning, making the frontend polling (project.js:checkReport) wait
5s for nothing on the first check.

Switch to `.start()` so analysis runs in a real OS thread and the
existing polling/status-endpoint pair actually does work across the
1 → 2 → 3 transition. Wrap the thread body in try/finally to release
the implicit Django DB connection the worker thread opens, otherwise
each Analyze click leaks one connection. Update the model test that
was asserting the bug (`.run()`) to assert `.start()`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the Files and Reference table layout (Created / Status / open
action) and surfaces report.get_status_display so async processing
states (Ready for Processing, Processing, Complete) are visible.
Inject a "Ready for Processing" row into the Reports table the moment
Analyze fires, then update its status badge as polling sees the report
move 1 → 2 → 3. Removes the manual-refresh toast entirely and the
status=3 filter on the project view, so in-progress reports also render
on initial page load. On load, any non-Complete row resumes polling so
a mid-flight refresh keeps tracking the same report.
The report page was using the singular `breadcrumb` class on a bare
`<ul>`, which is not daisyUI's component and rendered as a plain
bulleted list with no separators. Switch to the wrapping
`<div class="text-sm breadcrumbs"><ul>...</ul></div>` pattern and link
styling used by every other breadcrumbed template (project, tm,
newproject, newtm, tm-import).
@csengor csengor merged commit 17f7385 into kaplanPRO:0.6.x-dev May 16, 2026
2 checks passed
@csengor csengor deleted the feat/analysis-polling branch May 16, 2026 09:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant