いつのまにか、しんどくなるエンジニアへ。「直せます」の前に分けること

夜、付せんとタスクのカードが積み上がった机で首に手を当てるエンジニア。いつのまにか、しんどくなるエンジニアへ

保守で見ている会員管理システムがある。

ある日、お客さんから相談が来た。会員の方に、セミナーの受付を手伝ってもらうことになった。会員登録したメールアドレスのまま、受付の画面に入れるか。あわせて、管理の面で問題は起きないか。

ひとつ目の答えは、すぐ出た。できる。

このシステムの管理者は2段に分けてある。全部を扱える「全権」と、当日の受付だけができる「受付」。受付は会員名簿を読めない。画面で隠すだけじゃなく、データベースのルールでも止めてある。管理画面でアドレスを「受付」で登録すれば、その人は受付として入れる。登録は1行。

でも、ふたつ目の質問は、コードを見ないと答えられない。

AI が持ってきたのは「不具合です」と、2行の差分

AI にコードを読ませた。返事は数分で来た。

「会員の方を受付に登録すると、その方のマイページが表示されなくなります。不具合です。先に直してから登録しましょう」

原因の場所まで付いてた。マイページに、こう書いてある。簡略化すると、こう。

// 管理者なら、名簿から会員を選んで見られる
const browseAll = isAdmin;

この isAdmin には、受付も入る。受付は名簿を読めないので、読みに行って拒否されて、空になる。会費を払ってくれてる会員の方の画面に、「会員登録を完了してください」が出る。

直し方も付いてた。

const browseAll = isFullAdmin;

2か所、2行。5分。

僕は、そのまま「直してから登録しましょう」と返すつもりだった。

送る前に、ひとつ引っかかった

返事を書きながら、ふと思った。

受付の権限を足したとき、会員が受付を兼ねる使い方なんて、考えてたっけ?

git log を開いた。

マイページのこの行を書いたのは8月21日。受付の権限を足したのは9月1日。

8月21日にマイページを書いた時点では、管理者は全権だけだった。9月1日に受付の権限を足し、11月に会員を受付にしたいという相談が来た。書いた日には、その使い方はなかった
8月21日にマイページを書いた時点では、管理者は全権だけだった。9月1日に受付の権限を足し、11月に会員を受付にしたいという相談が来た。書いた日には、その使い方はなかった

8月21日の時点で、isAdmin は「全権の管理者」のことだった。受付という人は、まだいない。11日後に受付を足して、isAdmin の意味が広がった。でも、会員の画面は「管理者は会員じゃない」前提のまま残った。いまの受付の方は受付専用のアドレスで入ってるので、一度も表に出なかった。

壊れてたわけじゃない。会員が受付を兼ねる組み合わせが、設計の外だった。

2行の差分が、約束するもの

そう分かると、2行の差分の見え方が変わった。

マージした瞬間に、「会員が管理者を兼ねても動く」が仕様になる。そこから先は、会員の画面を直すたびに、兼ねた場合も確かめることになる。

差分は2行でも、確かめる相手は3倍になる。今までは会員だけを確かめればよかったが、マージしたあとは会員・受付を兼ねた会員・全権を兼ねた会員の3通りを確かめる
差分は2行でも、確かめる相手は3倍になる。今までは会員だけを確かめればよかったが、マージしたあとは会員・受付を兼ねた会員・全権を兼ねた会員の3通りを確かめる

isAdmin を見てる会員側の画面は、数えたら4か所あった。いま直すなら、4か所の見直しで済む。でも本当に増えるのは、この先ずっと続く確認のほう。

会員は退会する。管理者の登録は、だれかが外すまで残る。同じアドレスにすると、退会したのに権限だけ残ることも起きる。

それに、一度動いた組み合わせは、あとで止められない。止めたら、今度はそれが不具合として戻ってくる。

5分で済むのは、直す作業だけだった。

権限まわりは、だれが何を見ていいかを先に決めておく話でもある。自社アプリで確かめるときのチェックリストは、こちらにまとめてる。

▼関連記事
「ログインできる」と「そのデータを見ていい」は別。自社アプリの権限を確かめるチェックリスト

送った返事は、コードを書かない答え

結局、返事を書き直した。

受付用に、新しくアドレスを1つ作ってください。そのアドレスを「受付」で登録すれば入れます。

コードの変更は0行。

5分で済むのは、直す作業だけ。先に直す案は差分2行だが、その後の確認がずっと増える。受付用のアドレスを1つ作る案は、コードの変更が0行
5分で済むのは、直す作業だけ。先に直す案は差分2行だが、その後の確認がずっと増える。受付用のアドレスを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つ思い出してみてほしい。その挙動を書いた日に、その使い方はありましたか?

この記事を書いた人

tsubasatwi( つばさ)

国立工業高専卒業(新居浜工業高等専門学校)
「イベント×IT×営業」のカスタマーサクセスマネージャーとして活躍。セールス→構築管理運用まで全体プロジェクト管理の豊富な経験あり。

・主にITに関するイベント集客/法人営業/開発を担当
・大手通信会社を中心にエンタープライズのIT導入を担当(B2B)

DMMで日本初の NoCodeサロン を運営
「NoCodeCamp プログラミングを使わないIT開発 」
https://lounge.dmm.com/detail/2549/