Underlay toggle in Auto-Digitize Settings is silently dropped — value never reaches the service #117

Closed
opened 2026-09-30 01:48:43 +00:00 by Mark · 1 comment
Owner

Bug: Toggling "Underlay" in Auto-Digitize Settings has no effect on the digitize service call

Reproduction (verified 2026-09-25)

  1. Open Workspace → upload image → Auto-Digitize Settings panel opens.
  2. Click the "Underlay" toggle to turn it on.
  3. Click "Run Auto-Digitize".
  4. Observe the network request: the settings.underlay field is absent.
  5. Click the toggle to turn it off, click Run again.
  6. Observe: identical network request body. The toggle did nothing.

Expected

When the user toggles Underlay on, the service request should include underlay: true (or whatever the service contract expects). When off, underlay: false. The output should differ.

Actual

src/lib/digitize-adapters.ts:36-57 toServiceSettings() builds the service payload:

return {
  stitchPreference: mapStitchPreference(workspaceSettings.stitchPreference),
  fillDensityMm: 0.4,
  satinStitchSpacingMm: 0.4,
  runningStitchSpacingMm: 4.0,
  minStitchLengthMm: Math.max(0.5, workspaceSettings.minStitchLength),
  maxStitchLengthMm: 8.0,
  hoopSizeMm: { w: dims.width, h: dims.height },
  maxColors,
  machineProfile: "brother-pr10",
};

No underlay field. The reducer at useWorkspace.ts:169 correctly updates state.autoDigitizeSettings.underlay, and the toggle's onChange correctly dispatches SET_AUTO_DIGITIZE_SETTING. But the mapper drops the value before it reaches digitize().

Root cause

toServiceSettings() does not include underlay in its returned object. The mapper is incomplete — the UI control is wired to state, state is updated, but the state→service translation is missing.

  1. Add underlay: workspaceSettings.underlay to the returned object in toServiceSettings().
  2. Verify the back-end's DigitizeSettings Pydantic model accepts an underlay field. If not, file a back-end issue to add it.
  3. If the back-end does not support underlay, either:
    • File a back-end issue to add the field, or
    • Disable the toggle in the UI with a tooltip "underlay support pending back-end" (consistent with the existing autoThreadMatch disabled state)
  4. Add a unit test asserting the mapper includes underlay for both true and false toggle states.
  5. Add a Playwright regression: toggle Underlay, click Run, assert the request body's settings.underlay reflects the toggle state.

Severity

Medium. The toggle silently does nothing. Users who learn about this control have no idea they're being ignored.

Labels

  • bug
  • triage-approved
  • front-end
  • tech-debt

Filed 2026-09-25 by user-driven bughunt session. Supersedes umbrella #115.

## Bug: Toggling "Underlay" in Auto-Digitize Settings has no effect on the digitize service call ### Reproduction (verified 2026-09-25) 1. Open Workspace → upload image → Auto-Digitize Settings panel opens. 2. Click the "Underlay" toggle to turn it on. 3. Click "Run Auto-Digitize". 4. Observe the network request: the `settings.underlay` field is absent. 5. Click the toggle to turn it off, click Run again. 6. Observe: identical network request body. The toggle did nothing. ### Expected When the user toggles Underlay on, the service request should include `underlay: true` (or whatever the service contract expects). When off, `underlay: false`. The output should differ. ### Actual `src/lib/digitize-adapters.ts:36-57` `toServiceSettings()` builds the service payload: ```ts return { stitchPreference: mapStitchPreference(workspaceSettings.stitchPreference), fillDensityMm: 0.4, satinStitchSpacingMm: 0.4, runningStitchSpacingMm: 4.0, minStitchLengthMm: Math.max(0.5, workspaceSettings.minStitchLength), maxStitchLengthMm: 8.0, hoopSizeMm: { w: dims.width, h: dims.height }, maxColors, machineProfile: "brother-pr10", }; ``` No `underlay` field. The reducer at `useWorkspace.ts:169` correctly updates `state.autoDigitizeSettings.underlay`, and the toggle's `onChange` correctly dispatches `SET_AUTO_DIGITIZE_SETTING`. But the mapper drops the value before it reaches `digitize()`. ### Root cause `toServiceSettings()` does not include `underlay` in its returned object. The mapper is incomplete — the UI control is wired to state, state is updated, but the state→service translation is missing. ### Recommended fix 1. Add `underlay: workspaceSettings.underlay` to the returned object in `toServiceSettings()`. 2. Verify the back-end's `DigitizeSettings` Pydantic model accepts an `underlay` field. If not, file a back-end issue to add it. 3. If the back-end does not support `underlay`, either: - File a back-end issue to add the field, **or** - Disable the toggle in the UI with a tooltip "underlay support pending back-end" (consistent with the existing `autoThreadMatch` disabled state) 4. Add a unit test asserting the mapper includes `underlay` for both `true` and `false` toggle states. 5. Add a Playwright regression: toggle Underlay, click Run, assert the request body's `settings.underlay` reflects the toggle state. ### Severity **Medium.** The toggle silently does nothing. Users who learn about this control have no idea they're being ignored. ### Labels - bug - triage-approved - front-end - tech-debt Filed 2026-09-25 by user-driven bughunt session. Supersedes umbrella #115.
Mark closed this issue 2026-09-30 02:04:44 +00:00
Author
Owner

Closed via commit dfa4359 on Mark/Kimi_Agent_Brother_10_Digitizing_app main.

The mapper fix itself landed in 2b2f630 (umbrella #115), which added underlay: workspaceSettings.underlay to toServiceSettings() and a corresponding underlay?: boolean field on AutoDigitizeSettings (see src/lib/digitize-adapters.ts:60 and src/lib/easystitch-client.ts:31). The back-end DigitizeSettings Pydantic model already accepts underlay: bool | None = None at Mark/easystitch-service models.py:108 (forward-compatible wire field, ignored by _translate_settings until the engine adopts it), so no back-end issue is needed.

What was still missing was an end-to-end assertion that the toggle state survives the full UI → state → mapper → wire pipeline. dfa4359 adds tests/e2e/issue-117-underlay.spec.ts, a Playwright regression that:

  1. Captures the request body of POST /api/easystitch/v1/digitize via page.route() (Playwright's request.postData() / postDataBuffer() both return empty for fetch()-issued multipart uploads because the browser hands the body off as a Blob; routing the path through page.route() is what lets us see the buffered multipart envelope before it leaves the page).
  2. Toggles the "Underlay" switch between three runs and asserts the JSON-stringified settings multipart part reflects each state.

Captured live payloads (tests/e2e/.playwright-output/issue-117-underlay-payloads.json):

  • default (workspace reducer seeds underlay: true): "underlay": true
  • after toggle off: "underlay": false
  • after toggle back on: "underlay": true

Test passes against the live dev server (vite on :3000, easystitch-service on :8080). Unit tests in src/lib/digitize-adapters.test.ts (19/19) and the full shakedown are unaffected — this is a new test file with no production code change.

Closed via commit `dfa4359` on `Mark/Kimi_Agent_Brother_10_Digitizing_app` `main`. The mapper fix itself landed in `2b2f630` (umbrella #115), which added `underlay: workspaceSettings.underlay` to `toServiceSettings()` and a corresponding `underlay?: boolean` field on `AutoDigitizeSettings` (see `src/lib/digitize-adapters.ts:60` and `src/lib/easystitch-client.ts:31`). The back-end `DigitizeSettings` Pydantic model already accepts `underlay: bool | None = None` at `Mark/easystitch-service` `models.py:108` (forward-compatible wire field, ignored by `_translate_settings` until the engine adopts it), so no back-end issue is needed. What was still missing was an end-to-end assertion that the toggle state survives the full UI → state → mapper → wire pipeline. `dfa4359` adds `tests/e2e/issue-117-underlay.spec.ts`, a Playwright regression that: 1. Captures the request body of `POST /api/easystitch/v1/digitize` via `page.route()` (Playwright's `request.postData()` / `postDataBuffer()` both return empty for fetch()-issued multipart uploads because the browser hands the body off as a Blob; routing the path through `page.route()` is what lets us see the buffered multipart envelope before it leaves the page). 2. Toggles the "Underlay" switch between three runs and asserts the JSON-stringified `settings` multipart part reflects each state. Captured live payloads (`tests/e2e/.playwright-output/issue-117-underlay-payloads.json`): - default (workspace reducer seeds `underlay: true`): `"underlay": true` - after toggle off: `"underlay": false` - after toggle back on: `"underlay": true` Test passes against the live dev server (`vite` on :3000, `easystitch-service` on :8080). Unit tests in `src/lib/digitize-adapters.test.ts` (19/19) and the full shakedown are unaffected — this is a new test file with no production code change.
Sign in to join this conversation.
No description provided.