resolveThreads is wrapped, typed, tested, and never called — wire it into the Bottom Thread Bar and Right Panel for per-color match accuracy (ΔE) and alternative suggestions #128

Closed
opened 2026-10-03 02:49:16 +00:00 by Mark · 1 comment
Owner

Finding

POST /v1/threads/resolve takes a list of source hex colors and returns for each one: the best catalog match (with Delta-E) plus 2-3 alternative matches (with their own Delta-E). The client has the function (resolveThreads() at src/lib/easystitch-client.ts:707-711), the types, and 17+ test cases. Zero production callers.

This is the surface that lets a user see "this color match is loose (ΔE 12.4) — here are two closer options." Right now the user has no way to know if a match is tight or loose, and no way to pick a different thread.

Where

  • Service endpoint: POST /v1/threads/resolve (verified working at runtime)
  • Client wrapper: src/lib/easystitch-client.ts:707 (resolveThreads(colors: string[]): Promise<{ matches: ThreadMatch[] }>)
  • Test coverage: src/lib/easystitch-client.test.ts:339-400+ (function is well-tested)
  • Type: src/lib/easystitch-client.ts:84-102 (ThreadMatch, ThreadAlternative)

Suggested fix shape

Two surfaces to wire resolveThreads into:

  1. Bottom Thread Bar entry tooltip — when the user hovers a thread stop, show the source hex, the catalog match, and the ΔE. If ΔE > 3, render a small warning chip ("loose match") and a "Pick closer match" link that opens a popover with the alternatives from ThreadMatch.alternatives.

  2. Right Panel "Stitch Object" detail — when a path is selected, show the thread color assignment with the match confidence (ΔE) and a "Try alternatives" expander that lists the alternatives with their ΔE values. Clicking an alternative calls dispatch({ type: 'UPDATE_OBJECT', ..., colorId: alt.best.code }) to swap the assignment.

The data flow:

  • The digitize response (DigitizeResponse) does not currently include per-region ΔE. Either:
    (a) extend the service to return ΔE per region, or
    (b) have the client call resolveThreads after digitize for the source colors, indexed by region

Option (b) is the smaller change — no service work needed. The client batches the source colors from response.regions.map(r => r.color) and calls resolveThreads once.

Discovered by

Gap analysis (2026-10-02) of unreached service endpoints.

  • #126 (open, triage-approved) — service-sourced thread catalog. This issue is a peer: both consume service data the client currently ignores.
  • Help FAQ at src/pages/Help.tsx:138 claims "color matching ... 2-3 Delta-E" — accurate server-side; this issue is what makes the claim visible to the user.
## Finding `POST /v1/threads/resolve` takes a list of source hex colors and returns for each one: the best catalog match (with Delta-E) plus 2-3 alternative matches (with their own Delta-E). The client has the function (`resolveThreads()` at `src/lib/easystitch-client.ts:707-711`), the types, and 17+ test cases. **Zero production callers.** This is the surface that lets a user see "this color match is loose (ΔE 12.4) — here are two closer options." Right now the user has no way to know if a match is tight or loose, and no way to pick a different thread. ## Where - Service endpoint: `POST /v1/threads/resolve` (verified working at runtime) - Client wrapper: `src/lib/easystitch-client.ts:707` (`resolveThreads(colors: string[]): Promise<{ matches: ThreadMatch[] }>`) - Test coverage: `src/lib/easystitch-client.test.ts:339-400+` (function is well-tested) - Type: `src/lib/easystitch-client.ts:84-102` (`ThreadMatch`, `ThreadAlternative`) ## Suggested fix shape Two surfaces to wire `resolveThreads` into: 1. **Bottom Thread Bar entry tooltip** — when the user hovers a thread stop, show the source hex, the catalog match, and the ΔE. If ΔE > 3, render a small warning chip ("loose match") and a "Pick closer match" link that opens a popover with the alternatives from `ThreadMatch.alternatives`. 2. **Right Panel "Stitch Object" detail** — when a path is selected, show the thread color assignment with the match confidence (ΔE) and a "Try alternatives" expander that lists the alternatives with their ΔE values. Clicking an alternative calls `dispatch({ type: 'UPDATE_OBJECT', ..., colorId: alt.best.code })` to swap the assignment. The data flow: - The digitize response (`DigitizeResponse`) does not currently include per-region ΔE. Either: (a) extend the service to return ΔE per region, or (b) have the client call `resolveThreads` after digitize for the source colors, indexed by region Option (b) is the smaller change — no service work needed. The client batches the source colors from `response.regions.map(r => r.color)` and calls `resolveThreads` once. ## Discovered by Gap analysis (2026-10-02) of unreached service endpoints. ## Related - #126 (open, triage-approved) — service-sourced thread catalog. This issue is a peer: both consume service data the client currently ignores. - Help FAQ at `src/pages/Help.tsx:138` claims "color matching ... 2-3 Delta-E" — accurate server-side; this issue is what makes the claim visible to the user.
Author
Owner

Wired resolveThreads into both surfaces per the issue spec:

  1. Bottom Thread Bar entry tooltip — hover shows source hex, catalog match, and ΔE; loose matches (ΔE > 3) render a warning chip with a Pick closer match popover listing the ThreadMatch.alternatives.
  2. Right Panel Stitch Object detail — selected path shows the assignment with ΔE and a Try alternatives expander; clicking an alternative dispatches UPDATE_OBJECT with colorId: alt.best.code.

Data flow uses option (b): client batches response.regions.map(r => r.color) and calls resolveThreads once after digitize — no service changes needed.

Closes #128.

Wired `resolveThreads` into both surfaces per the issue spec: 1. **Bottom Thread Bar entry tooltip** — hover shows source hex, catalog match, and ΔE; loose matches (ΔE > 3) render a warning chip with a `Pick closer match` popover listing the `ThreadMatch.alternatives`. 2. **Right Panel Stitch Object detail** — selected path shows the assignment with ΔE and a `Try alternatives` expander; clicking an alternative dispatches `UPDATE_OBJECT` with `colorId: alt.best.code`. Data flow uses option (b): client batches `response.regions.map(r => r.color)` and calls `resolveThreads` once after digitize — no service changes needed. Closes #128.
Mark closed this issue 2026-10-03 03:59:59 +00:00
Sign in to join this conversation.
No description provided.