Skip to content

fix(cl2k): make the Poster Healer's scope and review queue reachable - #471

Merged
chodeus merged 3 commits into
developfrom
feat/poster-healer-settings-coverage
Aug 7, 2026
Merged

fix(cl2k): make the Poster Healer's scope and review queue reachable#471
chodeus merged 3 commits into
developfrom
feat/poster-healer-settings-coverage

Conversation

@chodeus

@chodeus chodeus commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Summary

Three related visibility fixes for the Poster Healer, the middle one being an outright bug.

  1. The review page had no nav entry — at all. Its only route in was a badge on the CL2K Maker page that renders when the open count is non-zero. So a run that reports work "left for manual review" pointed at a page with no way to reach it, and when the count was zero even the badge disappeared. It's now in the sidebar under Poster, like CL2K Maker.
  2. "Which drives is this assessing?" now answered where the module is configured — a read-only strip at the top of Settings → Modules → Poster Healer, not only on the Review page.
  3. The Review page is split left/right — what the healer looks at on the left, what needs action on the right, instead of stacking the coverage strip above the queue.

Related issue

N/A — found while chasing a run that reported items for review with nothing reachable to review.

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Breaking change (config migration, schema, endpoint, or UI behavior)
  • Docs only
  • Refactor / internal cleanup

Testing

  • npm run lint, npx prettier --check "src/**/*.{js,jsx,css,json,md}" (whole tree), npx stylelint "src/**/*.css", npm run build → all exit 0
  • npx vitest run → 46 passed (8 new)
  • Backend untouched; ruff check . → exit 0

New CoverageField.test.jsx covers the rendered states (folders + Drives listed, the no-Drive warning, a folder claiming no types still shown, nothing-configured, a failed fetch reported rather than rendering blank, an abort staying silent) and asserts the field passes an AbortSignal that unmount actually aborts.

One test worth calling out

The field-type registration test originally asserted expect(FieldRegistry.getField(field.type)).toBeTruthy(). That assertion cannot fail: getField() returns an UnknownFieldType placeholder for an unregistered type. I only found out by typo'ing the schema's type: to check — 8/8 still passed, and npm run lint also returned 0, because scripts/check-field-types.js only scans the three core schema files and never sees extension types.

So a mistyped extension field type would have shipped as a blank row in Module Settings with nothing failing anywhere. The test now asserts identity against the component, and I re-ran the typo to confirm it goes red.

Screenshots

Not captured. The settings strip renders inside ModuleSettingsPage's own section card (no second outer card, matching Cl2kCoverageField); the Review page becomes a lg:flex-row split with a fixed-width left column that stacks on narrow screens.

Checklist

  • Config schema updated if applicable (backend/util/config.py) — N/A, the field carries no config value and never calls onChange
  • Frontend builds cleanly (cd frontend && npm run build)
  • No new DAPS references introduced
  • Docs / wiki drafts updated if behavior or shape changed — rationale is in the component header and the manifest comment
  • CHANGELOG entry added for user-visible changes — N/A, develop-only extension; release-please runs on main only

The field type is registered from the extension's own manifest at module scope, mirroring how cl2k registers its Save Locations fields — so no shared file is touched and the branch-isolation invariant holds. posterSelfHeal.js now forwards options so callers can pass a signal, which works because #468 landed on main and merged down.

Summary by CodeRabbit

  • New Features

    • Added a live assessed locations panel showing configured folders, cloud drives, and artwork types.
    • Added navigation to the Poster review page.
    • Expanded the review page with a two-column layout and clearer “needing action” counts.
  • Bug Fixes

    • Improved handling of unavailable services, request failures, loading states, and canceled requests.
    • Empty configurations and unrouted artwork types are now clearly reported.

chodeus added 2 commits August 7, 2026 16:02
The coverage strip landed on the Review page, but the question it answers —
"which drives is this tool assessing for id mismatch?" — belongs where the module
is configured. Add it as a read-only field at the top of Settings → Modules →
Poster Healer.

Reuses the existing /api/poster-self-heal/coverage endpoint, so it reports the
heal's real scope rather than re-deriving it from config: a location claiming no
types saves nothing but is still assessed, and Drives show the types that
actually resolve to them.

The field type is registered from the extension's own manifest at module scope,
matching how cl2k registers its Save Locations fields.

The registration test asserts IDENTITY, not truthiness: FieldRegistry.getField()
returns an UnknownFieldType placeholder for an unregistered type, and
scripts/check-field-types.js only scans the three core schema files — so a
typo'd `type:` passes lint and renders a blank settings row. Verified by
typo'ing the schema and watching the test go red.
…the layout

The page had NO sidebar entry — its only route in was a badge on the CL2K Maker
page that renders when the open count is non-zero. So a run reporting work "left
for manual review" pointed at a page with no way to reach it, and when the count
was zero even the badge disappeared. Add it under Poster, like CL2K Maker.

Also split the page: what the healer looks at on the left, what needs action on
the right, instead of stacking the coverage strip above the queue.
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0117aa71-79ca-48b5-9992-5750211a9e41

📥 Commits

Reviewing files that changed from the base of the PR and between adbac4a and 7ba1648.

📒 Files selected for processing (3)
  • frontend/src/extensions/poster_self_heal/CoverageField.test.jsx
  • frontend/src/utils/api/posterSelfHeal.js
  • frontend/src/utils/api/posterSelfHeal.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/utils/api/posterSelfHeal.js
  • frontend/src/extensions/poster_self_heal/CoverageField.test.jsx

📝 Walkthrough

Walkthrough

Adds a live Poster Self-Heal coverage field, integrates it into the settings schema, and displays it in the Poster Healer review page with updated navigation and layout.

Changes

Poster self-heal coverage

Layer / File(s) Summary
Coverage loading and rendering
frontend/src/utils/api/posterSelfHeal.js, frontend/src/extensions/poster_self_heal/CoverageField.jsx, frontend/src/extensions/poster_self_heal/CoverageField.test.jsx, frontend/src/utils/api/posterSelfHeal.test.js
The coverage API accepts request options and always disables caching. The new field loads coverage with abort handling and renders folders, drives, empty locations, unrouted types, loading states, and errors. Tests cover API options, registration, rendering states, errors, and cancellation.
Field registration and settings integration
frontend/src/extensions/poster_self_heal/manifest.jsx, frontend/src/extensions/poster_self_heal/settings_schema.js
The manifest registers poster_self_heal_coverage. The settings schema adds the read-only assessed_locations field.
Review navigation and layout
frontend/src/extensions/poster_self_heal/manifest.jsx, frontend/src/pages/poster/PosterHealReviewPage.jsx
Poster navigation adds Poster Healer Review. The review page places coverage in a sidebar and review actions in the main column. The count label now says “needing action.”

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PosterHealReviewPage
  participant PosterSelfHealCoverageField
  participant posterSelfHealAPI
  participant apiCore

  PosterHealReviewPage->>PosterSelfHealCoverageField: render assessed locations
  PosterSelfHealCoverageField->>posterSelfHealAPI: request coverage with AbortSignal
  posterSelfHealAPI->>apiCore: fetch coverage with caching disabled
  apiCore-->>posterSelfHealAPI: return coverage or error
  posterSelfHealAPI-->>PosterSelfHealCoverageField: update coverage state
  PosterSelfHealCoverageField-->>PosterHealReviewPage: render coverage panel
Loading

Possibly related PRs

  • chodeus/chub#460: Adds the Vitest and React Testing Library infrastructure used by the new coverage field tests.
  • chodeus/chub#467: Adds the coverage API consumed by PosterSelfHealCoverageField.
  • chodeus/chub#451: Changes API GET caching behavior for live status or coverage reads.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes that make Poster Healer coverage and the review queue reachable.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/poster-healer-settings-coverage

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/extensions/poster_self_heal/CoverageField.test.jsx`:
- Around line 100-110: Update the AbortSignal test around
PosterSelfHealCoverageField to inspect the latest mockAPI.coverage invocation
rather than the first, or clear mockAPI.coverage before the test; ensure the
signal is asserted non-aborted before unmount and aborted afterward.

In `@frontend/src/utils/api/posterSelfHeal.js`:
- Around line 7-9: Update the coverage method in the poster self-heal API so
options are spread before the mandatory useCache: false setting. Ensure
caller-provided options remain supported while preventing them from overriding
cache bypass.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8e1c9684-91db-4c40-b17c-ad5180267251

📥 Commits

Reviewing files that changed from the base of the PR and between 3786479 and adbac4a.

📒 Files selected for processing (6)
  • frontend/src/extensions/poster_self_heal/CoverageField.jsx
  • frontend/src/extensions/poster_self_heal/CoverageField.test.jsx
  • frontend/src/extensions/poster_self_heal/manifest.jsx
  • frontend/src/extensions/poster_self_heal/settings_schema.js
  • frontend/src/pages/poster/PosterHealReviewPage.jsx
  • frontend/src/utils/api/posterSelfHeal.js

Comment thread frontend/src/extensions/poster_self_heal/CoverageField.test.jsx
Comment thread frontend/src/utils/api/posterSelfHeal.js Outdated
coverage() spread caller options AFTER useCache: false, so a caller could pass
useCache: true and cache live config state — serving a stale picture of what the
healer is about to assess. Spread options first; useCache last.

Adds posterSelfHeal.test.js covering option forwarding, the mandatory bypass, and
the no-argument call. The bypass test was verified red against the old order.

Also read the LAST coverage() call in the AbortSignal test rather than the first.
Correct either way today — restoreMocks clears mock state between tests, verified
with a probe — but this no longer depends on that setting staying enabled.
@chodeus
chodeus merged commit 4a0c2b6 into develop Aug 7, 2026
12 checks passed
@chodeus
chodeus deleted the feat/poster-healer-settings-coverage branch August 7, 2026 08:28
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