Skip to content

Duplicating a slot in the builder fails when the slot has a value in a Number field #512

Closed

Description

@richshaw

What happens

On the Build tab, choosing Duplicate on a slot that has a number in a Number field (a "Qty" column, say) adds nothing. The status rail shows "qty" must be a number.

The builder keeps every slot value as a string (toBuildRow → toStringValues in src/components/build-shared/useBuildState.ts). duplicateRow copies those strings, and addRow POSTs them to /api/signups/[id]/slots unchanged. So 12 goes up as "12". Nothing on the server converts it: SlotValuesSchema is z.record(z.string(), z.unknown()), and validateOneValue in src/services/slot-fields.ts requires typeof value === 'number'.

The comment in duplicateRow says "addRow re-serializes for the API", but it doesn't. Its sibling saveRowValues, which cell edits use, does convert number fields with Number(...) and drops empty ones. That's why editing a number works and duplicating doesn't.

An empty Number cell turns into '', which the server reads as missing. So Duplicate only fails when the source slot has a number in it, and then it fails every time.

The same gap is in handleAddSlot (src/components/build-wysiwyg/BuildWysiwyg.tsx), which seeds the group field's value as a string. The builder's group picker only offers date, enum and text fields, so the builder can't reach it today. A group-by set over the API could.

Fix, in outline

  • Move the number conversion out of saveRowValues into a small helper (e.g. toTypedValues(fields, values)).
  • Call it from saveRowValues and from addRow before the POST, so Duplicate, Add slot and anything else that goes through addRow send typed values.
  • Fix the misleading comment in duplicateRow.

Watch for

  • The existing duplicateRow tests in useBuildState.test.ts assert the uncoerced body, with text values only. Update them, don't just add alongside.
  • Open PR Fetch fields when a settings save names one the Build tab hasn't loaded #508 also touches useBuildState.ts, so whichever lands second has a small merge to do.
  • The issue about refused cell edits leaving a row stuck (filed alongside this one) changes editCell and saveRowValues in the same file.

Done when

  • A hook test duplicates a slot with a Number field set to 12 and the POST body holds qty: 12 (a number). An empty Number cell is left out of the body.
  • Duplicate on such a slot adds the copy in the running app.
  • pnpm lint && pnpm typecheck && pnpm knip && pnpm test pass.

Found by the pipeline's bugs scout in the builder (src/components/build-shared, build-wysiwyg), at 82a180f. Checked by a hook test capturing the POST body plus a DB test calling addSlot with { qty: "12" } (refused) and { qty: 12 } (accepted). https://claude.ai/code/session_014HtUS4AnW9zrtSroCVsxmB

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions