A Number field can't be changed to Text or a List without blanking every slot's value first

オープン
#783 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
typescript
領域
backend, database

調査の方向性

Start in updateField in src/services/slot-fields.ts, where it checks each slot's stored value with validateOneValue under the signup lock. The change converts stored numbers with String(n) for Number-to-Text and Number-to-List, then validates the converted values. Tests go in slot-fields.db.test.ts, and the issue says it is waiting on a maintainer decision (pipeline:proposed) and overlaps with #780, so confirm approval first.

索引モデルが issue の本文から書いたものです。

説明

bug pipeline:proposed pipeline:ux

Needs your OK: this changes what happens when an organizer changes a Number field's type: stored numbers would be turned into text instead of the change being refused. Swap pipeline:proposed for pipeline:ready to have it built.

What happens

updateField in src/services/slot-fields.ts checks every slot's stored value against the field's new type with validateOneValue, and refuses with conflict "change would invalidate existing slot values" if any fails. Number values are stored as JSON numbers, and the text and enum checks require typeof value === 'string'. So a Number field with even one value in it can never become Text or a List.

The organizer can't convert the values first either. While the field is still Number, updateSlot refuses a string (""qty" must be a number"). The only way through is to clear every value, change the type, and type them all in again.

Who hits it:

  • The Build tab. InlineFieldForm offers every type when editing a field. Changing "Quantity" from Number to Text (to allow "2 dozen") shows the raw server text "change would invalidate existing slot values".
  • AI assistants. The update_field MCP tool's description says "fix those values with update_slot first". For Number to Text or a List that advice can't work, because update_slot refuses the string.

Number to a List fails even when the list's choices include the numbers as strings ('2').

Fix, in outline

  • In updateField, where it already reads the signup's slot rows under the lock: when the field is going from number to text or enum, convert each stored number with String(n).
  • Validate the converted values against the new config, not the raw ones. Refuse as today if any still fails (text longer than maxLength, a number missing from the list's choices).
  • If they all pass, write the converted values back to those slots in the same transaction as the field update.
  • Fix the update_field description only if what it says stops being true.

Watch for

  • Don't loosen validateOneValue to accept numbers in text or list fields. That leaves mixed types in slots.values.
  • Other refusals stay. Narrowing a list, shortening maxLength, and Text to Date are refused on purpose (#289). Tests in slot-fields.db.test.ts pin them and must keep passing.
  • Overlap with #780, which changes how slot-fields.ts takes the signup write lock. Whichever lands second has a small merge.
  • Help pages. Run the help-pages skill's affected-articles.mjs and update any article that says a type change is refused.
  • Activity log. If slot values are rewritten, consider whether the field-update activity row should say so. Follow how updateField records today.

Choices this makes

  • Convert, not refuse. Default: convert Number to Text or a List automatically, because no information is lost. The alternative is a clearer error message only.
  • Text to Number stays refused. Default: leave it as is. Parsing "2 dozen" or "1,5" as a number guesses, and a wrong guess changes data silently.
  • Number formatting. Default: String(n) (so 2.5 becomes "2.5"), not the page's display format. It's predictable and round-trips.

Done when

  • A DB test: a Number field with values 2 and 3.5 changes to Text, and the slots now hold "2" and "3.5".
  • A DB test: Number to a List with choices ['2', '3.5'] succeeds and converts. With choices ['2'] it's refused with conflict and nothing changes.
  • pnpm lint && pnpm typecheck && pnpm knip && pnpm test and pnpm test:db pass.

Found by the pipeline's bugs scout in the slot field services (src/services/slot-fields.ts, src/mcp/tools/fields.ts), at 8e63fab. Checked by an independent verifier with a scratch DB test: Number to Text and Number to a List were both refused, updateSlot refused the string, and only blanking the value let the change through. https://claude.ai/code/session_016YZ9SUw2vvaNxfSUsArR5B

主要言語
TypeScript
スター
19
フォーク
4
平均マージ
19時間 27分
マージ済み PR(30日)
199

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

richshaw/OpenSignup のほかの issue

richshaw/OpenSignup の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。