「1枚に全部写っている」スクリーンショットのほうが、証拠として弱かった

転職用のポートフォリオとして、個人でWebアプリ「Hubpin」を作っています。
制作の経緯は「Hubpin 開発記録」に時系列でまとめています。
設計と判断は自分で行い、実装も原則自分で書いています。AIには手順書・レビュー・調査を任せています。

制作中の自作アプリで、掲載用の証拠スクリーンショットを撮っていたときの判断です。

目次

完璧に見える1枚が撮れた

「未ログインだと管理画面に入れない」ことを示す画像がほしくて、
シークレットウィンドウで /dashboard を直打ちしました。

撮れたのは、アドレスバーが /dashboard のまま、画面はログインフォームという1枚。

「打った URL」と「出た画面」が1枚に両方写っている。これ以上ない証拠に見えました。

採用しかけて、実装を読み直した

return NextResponse.redirect(url)   // URL は必ず /login に変わる

redirect を返しているので、アドレスバーが /dashboard のままになることはありません。
あの1枚は、ブラウザが遷移し切る前の一瞬でした。

何が問題か

公開素材として出すと、こう読まれます。

URL を保ったまま画面だけ差し替えている(= rewrite

実装と違う説明を、自分で用意したことになります。
しかもタイミング次第なので再現性がありません。

採用したのは「対」の2枚

同じシークレットウィンドウで連続して撮りました。

写っているもの
1枚目 未ログインで /dashboard/login に飛ばされている
2枚目 デモログイン後 → /dashboard が見えている

1枚目だけでは「そもそも /dashboard が壊れているだけ」の可能性が消えません。
「入れない」と「入れる」が同じ条件で並んで、初めて保護が効いている証明になります。

同じ形を前にも見ていた

データベースの権限(RLS)を確認したときも同じでした。

  • 他人のデータを更新しようとして 0行
  • 本人なら 7行

0行だけでは「UPDATE 文が壊れているだけ」と区別がつきません。
あのときも、片方だけでは何も言えなかった。

落としどころ

証拠の強さは、写っている情報量ではなく「反証をいくつ潰せるか」で決まる
というのが今回の学びです。

1枚に全部写っているほうが強く見えるのは、見た目の話でしかありませんでした。
そして「採用しかけた」のは自分で、実装を読み直さなければそのまま出していました。

目次