fix: prevent blank page on rebuild and queue drain on skip/discard
Two bugs fixed: 1. Blank white page after vue SPA rebuild: browsers cached old index.html referencing old asset hashes. Assets are deleted on rebuild, causing 404s for JS/CSS -> blank page. Fix: serve index.html with Cache-Control: no-cache so browsers always fetch fresh HTML. Hashed assets (/assets/chunk-abc123.js) remain cacheable forever. 2. Queue draining to empty on skip/discard: handleSkip and handleDiscard never refilled the local queue buffer. After enough skips, store.current went null and the empty state showed (blank-looking). Fix: both handlers now call fetchBatch() when queue drops below 3, matching handleLabel. Also: sync classifier_adapters LABELS to match current 10-label schema (new_lead + hired, remove unrelated). 48 Python tests pass, 48 frontend tests pass.
This commit is contained in:
parent
a06b133a6e
commit
82eeb4defc
4 changed files with 22 additions and 5 deletions
11
app/api.py
11
app/api.py
|
|
@ -209,5 +209,16 @@ def get_labels():
|
|||
# Static SPA — MUST be last (catches all unmatched paths)
|
||||
_DIST = _ROOT / "web" / "dist"
|
||||
if _DIST.exists():
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
# Serve index.html with no-cache so browsers always fetch fresh HTML after rebuilds.
|
||||
# Hashed assets (/assets/index-abc123.js) can be cached forever — they change names
|
||||
# when content changes (standard Vite cache-busting strategy).
|
||||
_NO_CACHE = {"Cache-Control": "no-cache, no-store, must-revalidate", "Pragma": "no-cache"}
|
||||
|
||||
@app.get("/")
|
||||
def get_spa_root():
|
||||
return FileResponse(str(_DIST / "index.html"), headers=_NO_CACHE)
|
||||
|
||||
app.mount("/", StaticFiles(directory=str(_DIST), html=True), name="spa")
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@ LABELS: list[str] = [
|
|||
"survey_received",
|
||||
"neutral",
|
||||
"event_rescheduled",
|
||||
"unrelated",
|
||||
"digest",
|
||||
"new_lead",
|
||||
"hired",
|
||||
]
|
||||
|
||||
# Natural-language descriptions used by the RerankerAdapter.
|
||||
|
|
@ -40,8 +41,9 @@ LABEL_DESCRIPTIONS: dict[str, str] = {
|
|||
"survey_received": "invitation to complete a culture-fit survey or assessment",
|
||||
"neutral": "automated ATS confirmation such as application received",
|
||||
"event_rescheduled": "an interview or scheduled event moved to a new time",
|
||||
"unrelated": "non-job-search email unrelated to any application or recruiter",
|
||||
"digest": "job digest or multi-listing email with multiple job postings",
|
||||
"new_lead": "unsolicited recruiter outreach or cold contact about a new opportunity",
|
||||
"hired": "job offer accepted, onboarding logistics, welcome email, or start date confirmation",
|
||||
}
|
||||
|
||||
# Lazy import shims — allow tests to patch without requiring the libs installed.
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@
|
|||
import pytest
|
||||
|
||||
|
||||
def test_labels_constant_has_nine_items():
|
||||
def test_labels_constant_has_ten_items():
|
||||
from scripts.classifier_adapters import LABELS
|
||||
assert len(LABELS) == 9
|
||||
assert len(LABELS) == 10
|
||||
assert "interview_scheduled" in LABELS
|
||||
assert "neutral" in LABELS
|
||||
assert "event_rescheduled" in LABELS
|
||||
assert "unrelated" in LABELS
|
||||
assert "digest" in LABELS
|
||||
assert "new_lead" in LABELS
|
||||
assert "hired" in LABELS
|
||||
assert "unrelated" not in LABELS
|
||||
|
||||
|
||||
def test_compute_metrics_perfect_predictions():
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ async function handleSkip() {
|
|||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: item.id }),
|
||||
})
|
||||
if (store.queue.length < 3) await fetchBatch()
|
||||
}
|
||||
|
||||
async function handleDiscard() {
|
||||
|
|
@ -228,6 +229,7 @@ async function handleDiscard() {
|
|||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: item.id }),
|
||||
})
|
||||
if (store.queue.length < 3) await fetchBatch()
|
||||
}
|
||||
|
||||
async function handleUndo() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue