UI batch + I1–I6 service passes + download-event recovery sweep #33

Merged
bvandeusen merged 0 commits from dev into main 2026-05-29 22:46:16 -04:00
bvandeusen commented 2026-05-29 22:33:54 -04:00 (Migrated from git.fabledsword.com)

Summary

  • UI batch — subscriptions hub scroll fix, bold plain-text post titles + provenance now links the posts feed (not the modal), dramatic 3D showcase cascade + IR-parity masonry hover, viewer-local timestamps everywhere, front-and-center active-downloads panel with live mm:ss timers, live queue-depth bar under the maintenance backfill buttons, in-context anchored posts feed with bidirectional infinite scroll, useTabQuery composable.
  • Dashboards + DRY pass — scheduler health strip, failing-source rollup, 24h activity sparkline, credential-staleness nudge, 1600px max-width, richer Downloads filters; extracted useAsyncAction, api/_responses._bad, async_session_factory, ImportSettings.load() classmethod, Importer._get_or_create, conftest fixture hoist.
  • Service improvements I1–I6 — I1 dedicated fast-fail ruff lint lane; I2 vitest component smoke tests (5 high-risk components); I3 always-on PipelineStatusChip in TopNav; I4 useInfiniteScroll composable (6 consumers migrated); I5 removed all GS/IR migration tooling (−2,412 lines) + alembic 0027 drops migration_run; I6 tests/test_fe_be_contract.py pins FE enum mirrors (downloadStatus.js, platformColor.js) to backend _ALLOWED_STATUSES / known_platform_keys().
  • Download-event recovery sweep — new recover_stalled_download_events Beat task (every 5 min, 30-min threshold past download_source.time_limit=1200s) flips stranded pending/running events to error and unsticks the source. Operator diagnostic 2026-05-29 confirmed 43 sources stranded by this gap (in-flight guard at scan.py:168 was skipping them every tick, with no recovery for non-terminal download_event rows); they unstick on the first sweep after deploy.
  • Credentials Verify button + live download-activity polling, copy buttons in the download detail modal, tooltip readability fix, retired-kind + source:* tag purge, ASYNC109 noqa.

Includes alembic 0027 (drops migration_run). Deploy must run migrations.

Test plan

  • Deploy and confirm alembic upgrade head runs cleanly; \d migration_run errors as "not found" after.
  • Click a post card → lands on that post in-context in the posts feed; scroll up loads newer, down loads older.
  • Active-downloads panel shows running/queued with a live elapsed timer; maintenance queue bar shows pending count under each backfill button.
  • Absolute timestamps render in viewer-local tz (not UTC).
  • Settings → Maintenance: legacy-migration card is gone; /api/migrate/* 404s.
  • TopNav pipeline chip shows scheduler health + running/queued/failing counts; click for the popover.
  • Within ~5 min of Beat coming up post-deploy, the 43 stranded sources unstick (Subscriptions health column flips from "never" → amber).

🤖 Generated with Claude Code

## Summary - **UI batch** — subscriptions hub scroll fix, bold plain-text post titles + provenance now links the posts feed (not the modal), dramatic 3D showcase cascade + IR-parity masonry hover, viewer-local timestamps everywhere, front-and-center active-downloads panel with live mm:ss timers, live queue-depth bar under the maintenance backfill buttons, **in-context anchored posts feed with bidirectional infinite scroll**, `useTabQuery` composable. - **Dashboards + DRY pass** — scheduler health strip, failing-source rollup, 24h activity sparkline, credential-staleness nudge, 1600px max-width, richer Downloads filters; extracted `useAsyncAction`, `api/_responses._bad`, `async_session_factory`, `ImportSettings.load()` classmethod, `Importer._get_or_create`, conftest fixture hoist. - **Service improvements I1–I6** — I1 dedicated fast-fail ruff lint lane; I2 vitest component smoke tests (5 high-risk components); I3 always-on `PipelineStatusChip` in TopNav; I4 `useInfiniteScroll` composable (6 consumers migrated); I5 removed all GS/IR migration tooling (−2,412 lines) + **alembic 0027** drops `migration_run`; I6 `tests/test_fe_be_contract.py` pins FE enum mirrors (`downloadStatus.js`, `platformColor.js`) to backend `_ALLOWED_STATUSES` / `known_platform_keys()`. - **Download-event recovery sweep** — new `recover_stalled_download_events` Beat task (every 5 min, 30-min threshold past `download_source.time_limit=1200s`) flips stranded `pending`/`running` events to `error` and unsticks the source. Operator diagnostic 2026-05-29 confirmed **43 sources stranded** by this gap (in-flight guard at `scan.py:168` was skipping them every tick, with no recovery for non-terminal `download_event` rows); they unstick on the first sweep after deploy. - Credentials Verify button + live download-activity polling, copy buttons in the download detail modal, tooltip readability fix, retired-kind + `source:*` tag purge, ASYNC109 noqa. **Includes alembic 0027** (drops `migration_run`). Deploy must run migrations. ## Test plan - [ ] Deploy and confirm `alembic upgrade head` runs cleanly; `\d migration_run` errors as "not found" after. - [ ] Click a post card → lands on that post in-context in the posts feed; scroll up loads newer, down loads older. - [ ] Active-downloads panel shows running/queued with a live elapsed timer; maintenance queue bar shows pending count under each backfill button. - [ ] Absolute timestamps render in viewer-local tz (not UTC). - [ ] Settings → Maintenance: legacy-migration card is gone; `/api/migrate/*` 404s. - [ ] TopNav pipeline chip shows scheduler health + running/queued/failing counts; click for the popover. - [ ] Within ~5 min of Beat coming up post-deploy, the 43 stranded sources unstick (Subscriptions health column flips from "never" → amber). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledCurator#33