ハコヅミを作る #50:見つかった 13 件を、7つ同時に直そうとして止まる

前回(#49)までで、5つの観点のレビューが終わりました。直すと決めたものは、Issue にして 13 件です。

今回は、それを直します。

  • 13 件を、どう分けたか
  • 7つ同時に動かして、止まる
  • 直しの中身:持ち物チェックの送信、古い編集画面、二重送信

13 件

重さ 中身
高 ログイン後の戻り先のすり抜け
高 持ち物チェックの送信(続けて押すと逆に保存される、失敗するとエラーの画面になる)
高 ログインのライブラリの入口を、使うものだけに絞る
高 守りのテストの空振り
高 規約・ポリシーの文
中 古い編集画面からの保存
中 二重送信、期間の欄
中 足し忘れに気づく仕組み
中 テストの小さな直しと、方針の文
中 小さな守り
低 小さな直し4つ
公開の前 依存パッケージの版上げ、凍結された人のアカウントを消す

ベータ版の前に直すのは、下の2つを除いた 11 件です。


最初の1件で、自分のテストを疑う

最初に直したのは、戻り先のすり抜けです。小さくて、外から悪用できるものなので、先にしました。

直し方は、「タブを断る」を足すだけでは、また別の文字で抜けます。最後に、ブラウザと同じ読み方で URL にして、行き先が自分のサイトのままかを確かめる形にしました。文字の形を1つずつ断るのをやめて、結果を見ます。

ここで、前々回の反省を使いました。足したテストを、直す前のコードで流してみる。4つが落ちました。直したあとは、全部通ります。

当たり前の確かめに見えます。ただ、今まではやっていませんでした。「直した、テストを足した、通った」で終わりです。そのテストが、直す前から通っていたかもしれない、とは考えていませんでした。守りのテストの空振りは、まさにそれでした。

この確かめは、このあとの全部の直しでやっています。


守りのテストを直したら、全部通った

次に、空振りしていた守りのテストを直しました。

直し方は、送り先の名前を合わせるだけではありません。同じ送信を、持ち主が送ると成功することも、一緒に確かめます。

  • ほかの人が送る → 断られて、値が変わらない
  • 同じ送信を、持ち主が送る → 通って、値が変わる

これで、送り先の名前がまた変わっても、空振りに気づけます。持ち主の送信まで断られるようになるからです。

15 の送信を、この形で書き直しました。結果は、最初に流したときから、全部通りました。守りの抜けは、ありません。

コードを読んだ2つのモデルが「守れている」と言っていたので、予想どおりではあります。それでも、テストが本当に確かめる形になって、初めて「守れている」と言えます。


7つ同時に動かす

残りは、まだたくさんあります。#28 から、実装はバックグラウンドの作業に任せることが増えました。今回は、7つの作業を、同時に動かすことにしました。

それぞれに、別の作業用のフォルダを持たせます。同じファイルを触る Issue は、同じ作業にまとめるか、順番にします。E2E は、同じポートを使うので、1つずつ順番に流れるように、順番待ちの仕組みも用意してもらいました。

準備は、よくできていました。

上限に当たる

動かし始めて、しばらくすると、全部が止まりました。使用量の上限です。

上限が戻ってから、再開しました。作業の途中のものは、それぞれのフォルダに残っています。「どこまでやったかを見て、続きから」と伝えれば、続けられます。

また止まりました。同じ理由です。

7つの作業は、それぞれがコードを読み、考え、書きます。同時に動かすと、使用量も7倍の速さで減ります。しかも、上限に当たると、全部が同時に、途中で止まります。

3回目に止まったところで、同時に動かすのは2つまでに変えました。上限に当たっても、巻き添えは少なくて済みます。

速く終わらせようとして、かえって時間がかかりました。7つを同時に動かすのは、人間が7人いるのとは違います。全員が、同じ1つの財布から払っています。

報告が来ない

止まり方は、もう1つありました。

ある作業が、画面イメージを撮り終えているのに、報告を出しません。「自分の処理の終わりを、待っている」と言ったままです。

あとで分かった原因は、こうです。その作業は、E2E を流して、「結果の行が出るまで、15 秒おきに見に行く」という繰り返しを動かしていました。ところが、E2E は、サーバーの起動に失敗して、結果の行を出さずに終わっていました。待っている行は、永久に出ません。

繰り返しは、4 時間あまり回り続けていました。

気づいたのは、私です。画面に「実行中」の表示が残っていました。Claude Code に聞くと、「動いているものは、何もない」と答えます。画面の写しを見せて、やっと見つかりました。

Claude Code は、動いているものを、E2E やサーバーの名前で探していました。ただの繰り返しは、引っかかりません。「ない」と答えたのは、「探したやり方では、見つからなかった」という意味でした。

  • 待つ処理には、回数か時間の上限を付ける
  • 「ない」と答える前に、名前を決めずに、広く探す

どちらも、言われてみれば当たり前です。作業に渡す決まりに、足しました。

画像は、先に見る

報告を待たずにできることも、ありました。画面イメージの画像は、もうフォルダにあります。作業の報告が来なくても、画像を開いて、案を比べることはできます。

そこで、報告が固まっているあいだに、画像を見て、案を選びました。報告があとから届いて、分かっていなかった点が埋まります。


直しの中身

持ち物チェック:押した順に、1つずつ送る

続けて押すと逆に保存される問題は、送る値を「今の状態の逆」から、**「押した時点の、チェックボックスの状態」**に変えれば直ります。

ただ、それだけでは足りませんでした。2回の送信を同時に出すと、サーバーに着く順番が、入れ替わることがあります。先に押したほうが、あとから保存されます。

そこで、送信は1つずつ、押した順に送るようにしました。前の応答が返ってから、次を送ります。

もう1つ、作業が見つけたことがあります。今までは、保存のあとに、画面を読み直していました。この読み直しが失敗すると、SvelteKit は、ページごと読み込み直しに行きます。電波がないと、ブラウザの「オフラインです」の画面になります。

エラーの画面をやめても、これでは同じことです。保存の応答に、新しい持ち物チェックを入れて返す形にして、読み直しをやめました。通信も、1回の押しで2往復だったのが、1往復になります。

失敗したときは、押した項目を元に戻して、画面の下に知らせを出します。

持ち物チェックの画面。ケトル、まな板、ランタンの3つの項目の下に、赤い字で「保存できていません」と出ている。画面の下には、赤い帯で「保存できませんでした 「ケトル」ほか 2 件 電波のよいところで、もう一度押してください。」と、「閉じる」のボタン

電波が切れているときに、3つ押したところ

出し方は、2つの案から選びました。項目のすぐ下に文を全部出す案と、画面の下に帯で出す案です。選んだのは、帯です。持ち物チェックは、長い一覧を下へ送りながら使います。項目の下に出すだけだと、画面を送ったあとでは、気づけません。

古い編集画面:選んでもらう

スマホと PC で、同じキャンプの編集の画面を開いている。片方でプランを変えたあと、もう片方でメモだけ直して保存する。すると、プランが元に戻って、チェックが全部消えます。

直し方は、編集の画面を開いた時点のプランと料理を、一緒に送ることにしました。今と違っていたら、保存を止めます。

Issue に書いた案は、「保存せずに、開き直してもらう」でした。作業は、もう1つ案を足してきました。

キャンプ情報の編集の画面の下のほう。赤い枠の中に「ほかの画面で変更されたため、保存していません」の見出しと説明。その下に「プランと料理はそのままで保存」のボタンと、「保存せずに開き直す」のボタン。枠の下に、ふつうの「保存」と「キャンセル」のボタン

古い画面から保存しようとしたとき

**「プランと料理はそのままで保存」**です。プランと料理は、ほかの画面で変えた内容のままにして、メモなど、ほかの入力だけを保存します。

この問題が起きるのは、たいてい「メモだけ直したかった」場面です。開き直すしかないと、書いたメモを、スマホで打ち直すことになります。こちらを選びました。

仕上げの段階で、作業がもう1つ見つけています。入力欄で Enter を押すと、ブラウザは、フォームの中でいちばん先にある送信のボタンを使います。知らせを保存のボタンの上に置いたので、Enter で「プランと料理はそのままで保存」が送られてしまう。見た目の順番はそのままに、HTML の中の順番だけを入れ替えて、直してありました。

二重送信と、期間の欄

保存のボタンを続けて押すと、2件できる。これは、登録と編集のフォーム 13 個を、共通の部品に置き換えて直しました。送信中の2回目は、送りません。

期間の欄は、開始日だけ選んで保存すると、「日帰り」として保存されていました。保存を止めて、カレンダーを開きます。

キャンプの登録の画面の予定期間の欄。欄には「2026/10/10(土)〜(終了日を選んでください)」と出ていて、赤い枠になっている。その下に、赤い字で「終了日を選んでください(同じ日をもう一度押すと、日帰り)」。さらに下に、カレンダーが開いていて、10 日が選ばれている

開始日だけ選んで、保存を押したとき

新しいテスト 16 件を、直す前のコードで流すと、13 件が落ちて、3 件が通りました。通った3件は、直す前でも通るのが正しいものです(入力のエラーのあとに保存し直せる、など)。「全部落ちた」ではなく、「落ちるはずのものが落ちて、通るはずのものが通った」と確かめられました。


ぶつかる

別々に進めた直しは、最後にぶつかります。

古い編集画面の直しと、二重送信の直しは、どちらも、キャンプの編集の画面を触っていました。片方をマージすると、もう片方が食い違います。

これは、分ける段階で分かっていたことです。「あとからマージするほうで、合わせる」と決めてありました。合わせたあとで、E2E の全件を流しました。3つの直しを組み合わせた状態で流すのは、これが初めてです。482 件、通りました。


本番に出す

11 件のうち、8 件をまとめて本番に出しました。テストと文書だけの2件は、受入で閉じています。残りの1件(小さな守り)は、開発環境の実物で試さないと決められない部分があるので、あとに回しました。

データベースの形は、変わっていません。どれも、今あるデータには触らない直しです。

レビューを始めてから、本番に出すまで、1日でした。


振り返り

セカンドオピニオンのレビューを、4回に分けて書いてきました。

回 中身
#47 計画(新しいセッション、2つのモデル、頼み方の文)
#48 バグとセキュリティ
#49 規約、データの出入り、テスト
#50 直す

やってよかったか、と聞かれれば、よかったです。

重いもの(ほかの人のデータに届く、データが消える)は、見つかりませんでした。 これは、「見つからなかった」という結果そのものに、価値があります。外の目で探して、なかった、と言えます。

見つかったのは、作っている本人には見えにくいものでした。通っているテスト、自分で書いた規約、「入れたはず」の仕組み。どれも、疑う理由がないものです。

手間は、新しいセッションを開いて、頼み方の文を7回貼ることだけでした。別のモデルが使えなくても、同じモデルの新しいセッションと、もう1つの手に入るモデルで、十分に意味がありました。

1つ、残っていることがあります。2つのモデルは、同じ会社の、同じ系列です。そろって見落としているものは、この見直しでは見つかりません。一般に公開する前に、もう一度考えます。


おわりに

  • 直したら、足したテストを、直す前のコードで流す。落ちるはずのものが落ちることを見る
  • バックグラウンドの作業を増やすと、速くなるのではなく、使用量が速く減る。同時に動かす数は、止まったときの巻き添えで決める
  • 待つ処理には、上限を付ける。待っている相手が、黙って終わっていることがある
  • 「動いているものはない」と言われたら、どう探したかを聞く
  • 別々に直したものは、最後に組み合わせて、全部を流す
  • 見直しの結果で、いちばん価値があるのは、「重いものはなかった」と言えること

次回は、ベータ版の前の、残りの準備です。

← トップページに戻る