友人のPriyaは34床の医療フロアのシフト管理を担当しており、この2年間、誰も順番通りに読まないグループテキストでのシフト交代依頼に対応し続けてきました。彼女が欲しかったのは、休憩中にスマホで開けて、カバーが必要なシフトを投稿でき、チャージナースが手作業でボードを組み直す前に誰かがそれを引き受けられるようなツールでした。私はそれを3週間の夜の時間を使って作りました。これは、それが実際に本番公開された日の記録です——公開、カスタムドメイン、実在のナース、実際のシフト。「テストでは動く」と「朝7時に人手が2人足りない現場で動く」の間にあるギャップが、それ自体一つの教訓になったからです。
午前6時58分 — 公開
前夜のうちにデプロイ先をPriya自身のドメインに設定していたので、この部分は拍子抜けするほど淡々としていました。公開ボタンを押し、ビルドの検証記録がチェックを通過していくのを見守るだけです。
- ルーティングが正しく解決されているか
- シフト受け取り用エンドポイントがスタブではなく実際のレスポンスを返しているか
- SMS通知フックがドライランではなく実際に設定されているか
すべて緑。午前6時58分にPriyaへリンクをテキストで送りました。ちょうど彼女が勤務に入るタイミングだと分かっていたので、1日が始まる前に公開されている様子を見てほしかったのです。
午前7時15分 — 最初の実ユーザーが、私がテストしていなかったことをする
Priyaは20分以内にその晩の空きシフトを投稿しました。予想より早く、コーヒーを飲み終える前に最初の実データが生まれたことになります。次に、Deniseというナースがそのシフトを受け取り、4分後にキャンセルし、また受け取り直しました。理由は分かりません——受け取った後に自分のカレンダーを確認して、歯医者の予約があることに気づいたのかもしれません。アプリはそれを問題なく処理しました。私がテストしていなかったのは、3人が同じ10秒の間に同じシフトを取ろうとするケースでした。3週間の一人テストの間、そんなシナリオは一度も思い浮かびませんでした。この時点でも思い浮かびませんでした。それが現実として起きたのは、この約5時間後のことです。
午前9時40分 — 静かで、その静けさに落ち着かなくなる
2時間半、何も起きませんでした。受け取りも投稿もなく、ログにエラーもありません。それでも私はダッシュボードを4回確認しました。これはやめた方がいい習慣です。使われていないビルドは壊れているわけではなく、まだ使われていないだけであり、それぞれ対処法の異なる別の問題だからです。無理やりタブを閉じて、本業の仕事に戻りました。
午前11時52分 — バグ発生
受け取り用エンドポイントは3件すべてを受理してしまいました。「受け取り済みにする」ロジックを、ロックのないシンプルな「オープンなら更新する」チェックとして書いていたためです。通常の単一ユーザーテストでは、このレースコンディションが発生する余地はまったくありません。しかし、3台の異なる端末から同時にタップされると、発生する余地は十分にあります。3人のナース全員に「シフトを引き受けました」という確認テキストが届きました。そのうちの一人はDeniseで、この日2度目のことであり、今回は彼女も苛立っていました。
これをどうやって発見したか、正直にお伝えします——監視で気づいたのではありません。Priyaが笑い絵文字付きでこうテキストしてきたのです。彼女が本当に笑っていたとは思いませんが、実際、彼女の午後にとっては問題でした。
アプリによると同じシフトに3人割り当てられてるんだけどwww
午後12時10分 — ビルドチャットへ
私は平易な言葉でバグを説明しました。「ほぼ同時にタップすると複数人が1つのシフトを取得できてしまい、本来は1件だけが確定すべきだ」と。最初から自分で修正しようとはしませんでした。理由の一つは駐車場でスマホを操作していたからで、もう一つは失敗の内容を正確に説明する方が、正確に原因を診断するより速いことが多いからです。エージェントはこれを、受け取りテーブルの行ロック欠如が原因だと突き止め、アトミックな条件付き更新への切り替えを提案しました——シフトのステータスがまだ「open」の場合にのみ受け取りが成功し、チェックしてから書き込むのではなく、操作自体が誰が勝つかを決めることで、3つのリクエストが同時に「open」を見てしまう事態を防ぎます。これが一文で表せる本当のバグであり、言われれば当たり前なのに、目に見えるまでは気づけない類のものです。
午後12時34分 — 修正を公開し、Priyaを待たせる
パッチ自体は小さなものでしたが、それでも稼働中のシフト中に本番ドメインへ直接反映することはしませんでした。まずプレビュー版に適用し、その日は勤務していないPriyaのチャージナースの同僚に、3つのブラウザタブから同時に3回タップする同じ操作を試してもらいました。結果は問題なし。1件だけ受け取りが成立し、残り2件には偽の確認ではなく「このシフトは既に他の人が受け取りました」というメッセージが表示されました。バグ発生からおよそ42分後の午後12時34分に本番反映しました。その瞬間は遅く感じましたが、振り返れば速かったと思います。
午後2時〜6時 — 地味だが良い時間帯
- 11件のシフトがさらに投稿された
- 9件が問題なく受け取られた
- 2件は受け取り手がつかず期限切れとなり、Priyaが今も手動で管理しているボードに戻された——それで構いません。このツールは初日にすべてを解決する必要はなく、壊れていた特定の問題を解決すればいいのです
- 0件の二重受け取り追加発生
私は結果を想像するのではなく、数字を見守っていました。これはまったく別の、ずっと落ち着いた作業です。
次回はどうするか
2点あります。
- 最初のビルドプロンプトの段階で、同時受け取りのシナリオを説明しておくべきでした——「複数のユーザーが、同じ操作を、同じ瞬間に行う」というのは一文で書ける程度の要求であり、難しい注文ではありません。自分のテストが本質的に逐次的だったため、思い至らなかっただけです。ボタンは常に一度に一つしか押しませんから。
- 2週目には、誰も文句を言わなかった確認テキストの文言を3回も書き直すなど、SMS通知の文言に過剰に時間をかけすぎました。その一方で、休憩中に一斉にスマホを見つめるナースたちのフロアなら初日に必ず起きるであろう、まさにこの手の並行処理のエッジケースへの投資が不足していました。
次回のローンチでは、誰も批評しないような文章の磨き込みに時間をかけるのではなく、「5人が同時にこれをやったらどうなるか」を問う時間を増やすつもりです。実ユーザーが複数存在するものであれば、いずれ誰かがそれをやるからです。



