保守で見ている会員管理システムがある。
ある日、お客さんから相談が来た。会員の方に、セミナーの受付を手伝ってもらうことになった。会員登録したメールアドレスのまま、受付の画面に入れるか。あわせて、管理の面で問題は起きないか。
ひとつ目の答えは、すぐ出た。できる。
このシステムの管理者は2段に分けてある。全部を扱える「全権」と、当日の受付だけができる「受付」。受付は会員名簿を読めない。画面で隠すだけじゃなく、データベースのルールでも止めてある。管理画面でアドレスを「受付」で登録すれば、その人は受付として入れる。登録は1行。
でも、ふたつ目の質問は、コードを見ないと答えられない。
AI が持ってきたのは「不具合です」と、2行の差分
AI にコードを読ませた。返事は数分で来た。
「会員の方を受付に登録すると、その方のマイページが表示されなくなります。不具合です。先に直してから登録しましょう」
原因の場所まで付いてた。マイページに、こう書いてある。簡略化すると、こう。
// 管理者なら、名簿から会員を選んで見られる
const browseAll = isAdmin;
この isAdmin には、受付も入る。受付は名簿を読めないので、読みに行って拒否されて、空になる。会費を払ってくれてる会員の方の画面に、「会員登録を完了してください」が出る。
直し方も付いてた。
const browseAll = isFullAdmin;
2か所、2行。5分。
僕は、そのまま「直してから登録しましょう」と返すつもりだった。
送る前に、ひとつ引っかかった
返事を書きながら、ふと思った。
受付の権限を足したとき、会員が受付を兼ねる使い方なんて、考えてたっけ?
git log を開いた。
マイページのこの行を書いたのは8月21日。受付の権限を足したのは9月1日。

8月21日の時点で、isAdmin は「全権の管理者」のことだった。受付という人は、まだいない。11日後に受付を足して、isAdmin の意味が広がった。でも、会員の画面は「管理者は会員じゃない」前提のまま残った。いまの受付の方は受付専用のアドレスで入ってるので、一度も表に出なかった。
壊れてたわけじゃない。会員が受付を兼ねる組み合わせが、設計の外だった。
2行の差分が、約束するもの
そう分かると、2行の差分の見え方が変わった。
マージした瞬間に、「会員が管理者を兼ねても動く」が仕様になる。そこから先は、会員の画面を直すたびに、兼ねた場合も確かめることになる。

isAdmin を見てる会員側の画面は、数えたら4か所あった。いま直すなら、4か所の見直しで済む。でも本当に増えるのは、この先ずっと続く確認のほう。
会員は退会する。管理者の登録は、だれかが外すまで残る。同じアドレスにすると、退会したのに権限だけ残ることも起きる。
それに、一度動いた組み合わせは、あとで止められない。止めたら、今度はそれが不具合として戻ってくる。
5分で済むのは、直す作業だけだった。
権限まわりは、だれが何を見ていいかを先に決めておく話でもある。自社アプリで確かめるときのチェックリストは、こちらにまとめてる。
▼関連記事
「ログインできる」と「そのデータを見ていい」は別。自社アプリの権限を確かめるチェックリスト
送った返事は、コードを書かない答え
結局、返事を書き直した。
受付用に、新しくアドレスを1つ作ってください。そのアドレスを「受付」で登録すれば入れます。
コードの変更は0行。

返事を送ったあと、最初の相談を読み返した。最後に、「別のアドレスを用意したほうがいいか」という一言が入ってた。
お客さんのほうが、先に答えの近くにいた。
いつの間にか、負担が増えてませんか?
あとで、この件を考え直した。たぶん僕は、これまでも同じことをやってきた。
保守を持ってると、「ちょっとこれ、できますか」はよく来る。PR は小さいし、レビューも通る。マージすれば「できた」で終わる。
重さが来るのは何か月かあと。別の画面を直すとき、テストの組み合わせを考えるときに、少しずつ。定額の保守だと、増えたぶんは請求にも作業記録にも出ない。気づいてるのは、コードを持ってる本人だけ。
もうひとつ。「管理者と会員は別のアドレス」は、このシステムでは当たり前の前提だった。でも、仕様書にもコメントにも書いてなかった。書いてあったのは isAdmin という変数名だけ。書いてない前提は、目の前の「できますか?」にだいたい負ける。
頼む側に、コードの中の前提まで分かってもらうのは無理がある。だから、言葉にして渡すのはエンジニアの仕事だと思ってる。
AI だと、もっと早く増える
今回、最初に「不具合です」と言ったのは AI だった。
AI は、原因から差分まで数分で持ってくる。2行の修正なら、テスト込みでもすぐ終わる。あとはマージするだけ。作るのが面倒、という昔の歯止めが無い。
AI で下がったのは、作る手間。持ち続ける手間は、前と変わってない。
今回 git log を開いたのは、僕だった。あそこで開かなければ、そのままマージしてたと思う。
それで、決めたこと
この件のあと、うちの会社の対応方針をこう決めた。お客さんからのご相談でも、自分たちの開発でも同じ。
1. 直す前に、4つに分ける
見つかった挙動が、不具合か、仕様どおりか、想定外の使い方か、新しいご要望か。目安は git log。書いた日に、その使い方があったか。

2. コードより先に、運用の答えを出す
直す案も出す。ただし、増える確認を具体的に添えて、選んでもらう。決めるのは、お客さん。
3. 崩さない前提を、お客さんが読める言葉で書いておく
このシステムでも、仕様書の先頭に「崩さない前提」を書き足した。1番目は「管理者と会員は別のアドレスで管理する」。次に同じ相談が来たら、ここを見せれば答えられる。型にすれば判断は減ると前に書いたのと、同じ話。
4. 例外を足すなら、消す条件も一緒に決める
コードに「移行が済んだら消す」とコメントした例外は、うちの手元にもまだ残ってる。消す条件を書いてあっても、残る。
決めたことを書き残す、という点では、入れられないセキュリティ対策をどう扱うかも同じ形で書いた。
▼関連記事
入れられないセキュリティ対策は、どう扱う?——allow_url_fopenを例に、決め方と報告書への残し方
断るときは、代わりを1つ
今回、「直しません」とは一言も言ってない。「アドレスを1つ作ってください」と言っただけ。お客さんは困ってないし、僕のコードも増えてない。
いつのまにかしんどくなってるなら、最近「直せます」と言ったものを1つ思い出してみてほしい。その挙動を書いた日に、その使い方はありましたか?


