Skip to content
This repository was archived by the owner on May 18, 2026. It is now read-only.

fix(sets): parts-error dark-mode text + polling test coverage#232

Open
Goosterhof wants to merge 1 commit into
mainfrom
claude/charming-newton-YoFxk
Open

fix(sets): parts-error dark-mode text + polling test coverage#232
Goosterhof wants to merge 1 commit into
mainfrom
claude/charming-newton-YoFxk

Conversation

@Goosterhof
Copy link
Copy Markdown
Owner

Review of last 24 h commits (da6344d · c01c909 · f740da1 · 70fcafe)

This PR fixes two issues surfaced during review of the commits merged in the past 24 hours.


Commits reviewed

Commit Subject
da6344d feat(sets): poll the parts endpoint when a sync is still in flight (#229)
c01c909 docs(records): file permit for dark-mode contrast violations (#231) — includes all dark-mode source fixes
f740da1 docs(records): inspection report — PRs #225 #226 #227 (#228)
70fcafe fix(sets): correct PartsSyncPending type and clean up partsSyncing on early returns (#230)

Finding 1 — parts-error block: near-invisible text in dark mode

da6344d added a parts-error block to SetDetailPage.vue:

<div v-else-if="partsError" bg="brick-red-light" class="brick-border brick-shadow" ...>
  <p font="bold">{{ partsError }}</p>
</div>

brick-red-light is a static hex (#F8D0CF) defined in uno.config.ts — it does not adapt to theme. With no explicit text color on the <p>, the element inherits --brick-page-text, which is light gray (~#e2e2e2) in dark mode. Light gray on light pink is near-invisible.

The dark-mode fix commit (c01c909) did not touch this block because it was added to a different branch after the dark-mode permit was scoped. The follow-up permit audit listed SetDetailPage.vue:417 (the missing-parts rows) but the parts-error block at line 354 was not on any audit list.

Fix: text="brick-ink" forces #000000 on the error paragraph in both themes — same pattern the form inputs use with focus:text-brick-ink when they flip to a yellow background.


Finding 2 — polling logic in loadParts() has no behavioral tests

da6344d added significant new branches to loadParts():

  • discriminating PartsSyncPending vs SetWithParts response shapes
  • a 15-attempt polling loop with 2 s sleep intervals
  • a timeout path (attempt 15 → partsError = syncTimeout)
  • a hard-failure path (catch → partsError = syncFailed)
  • the disabled-while-loading guard on the Load parts button

None of these paths had unit or integration test coverage. The 100% Istanbul metric did not flag the gap because src/apps/**/pages/** is explicitly excluded from the coverage scope (pages are verified via integration tests, not Istanbul). The integration test suite has no scenarios for pending/timeout/failure responses.

Fix: Four new unit tests using vi.useFakeTimers() to drive the 2 s poll interval:

Test What it exercises
should disable load parts button while a request is in flight partsLoading disables the button before the first response arrives
should show sync message then display parts after polling resolves pending envelope → 2 s sleep → resolved response → parts rendered
should show a timeout error after exhausting all poll attempts 14 sleep cycles + attempt 15 → syncTimeout error block
should show a failure error when the parts request throws catch path → syncFailed error block

Findings not fixed here (out of scope / pre-existing)

  • bg="brick-red-light" on the missing-parts rows (line 419) and availability badge (line 506) in SetDetailPage.vue — these are pre-existing and already logged in the dark-mode construction journal as follow-up candidates. No --brick-surface-danger token exists yet; fixing them properly requires a new permit.
  • bg="red-100", bg="yellow-300", bg="red-200" in AddSetPage, PartsMissingPage, PartsPage, PartsUnsortedPage — also in the dark-mode journal's follow-up list.
  • src/apps/**/pages/** exclusion from Istanbul coverage — this is intentional per the project's coverage strategy and is not a defect.

Gauntlet

format:check · lint · lint:vue · type-check · test:coverage 100% (1385/1385 tests) · knip · build — all pass.


Generated by Claude Code

The parts-error block introduced in the polling feature used bg="brick-red-light"
(a static #F8D0CF hex) with no explicit text color, so in dark mode the inherited
--brick-page-text (light gray) rendered near-invisible against the light-pink
background. Add text="brick-ink" to force readable black text on that surface in
both themes, consistent with how other light-bg/forced-dark-text pairs work in
the design system (e.g. focused form inputs use focus:text-brick-ink).

Also adds four unit tests that were missing for the loadParts() polling logic
introduced in da6344d: disabled-button-while-in-flight, sync-message-during-poll,
parts-resolved-after-poll, timeout-after-max-attempts, and hard-failure. Pages
are excluded from the Istanbul coverage scope, so the 100% metric did not catch
the gap. Tests use vi.useFakeTimers() to drive the 2s poll interval without
real-time waits.

https://claude.ai/code/session_01TzyjXD9NFTqHie3RECxqit
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying lego-storage-frontend with  Cloudflare Pages  Cloudflare Pages

Latest commit: ae41e23
Status: ✅  Deploy successful!
Preview URL: https://d3ce97b2.lego-storage-frontend.pages.dev
Branch Preview URL: https://claude-charming-newton-yofxk.lego-storage-frontend.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying brick-inventory-showcase with  Cloudflare Pages  Cloudflare Pages

Latest commit: ae41e23
Status: ✅  Deploy successful!
Preview URL: https://7fcdde8a.brick-inventory-showcase.pages.dev
Branch Preview URL: https://claude-charming-newton-yofxk.brick-inventory-showcase.pages.dev

View logs

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants