こんにちは、株式会社スマートバンクでサーバーサイドエンジニアをやっています、すてにゃん (
id:stefafafan) です。今回は社内で活用している管理画面に対して実施した様々な技術的な改善を紹介していきます。
背景
株式会社スマートバンクではお問い合わせ対応や調査をするために社内向けに管理画面を用意しています。この管理画面は以下のスライドにあるように、ユーザー向けの機能とはリポジトリを分けて運用しています。
この構成を取ることで、プレゼンテーションロジック (UI) とドメインロジックを分離することができ、認知負荷を下げることに貢献していると感じています。
一方でユーザーが直接手に触れる部分はモバイルアプリということもあり、管理画面は意識してメンテナンスしていかないとじわじわと廃れてしまうんじゃないかと最近の私は危惧するようになりました。フロントエンド専任のエンジニアやフロントエンドエキスパートのようなロールも定めていないので、Reactベースの管理画面をどこまで面倒見切れるのかというのがポイントになりそうだと思いました。
カスタマーサポートの業務改善を多くやっているチーム1に在籍している私は管理画面を触る機会が多いので、チームの一員としてオーナーシップをもっていくつかの改善に取り組んでいきました。今回はその取り組みの一部を技術的なポイントに絞って紹介します。
改善サイクルの高速化
最初に取り組んだのは改善サイクルの高速化です。CIの実行が1回あたり12~13分かかっている状況だったのを、4分前後で終わるように高速化しました。
実施したことはシンプルにテストの並列実行数を増やすことです2。
Jestの --maxWorkers オプションに加えて、--shard オプションを指定してテストを分割実行するようにしました。GitHub Actionsの設定は最終的に以下のような形になりました。
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: test-shards: runs-on: ubuntu-latest strategy: matrix: shard: [1/4, 2/4, 3/4, 4/4] steps: # 中略 - name: Get number of CPU cores id: cpu-cores uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2.0.0 - name: Run the tests (shard ${{ matrix.shard }}) run: yarn test --maxWorkers ${{ steps.cpu-cores.outputs.count }} --shard=${{ matrix.shard }}
テストの高速化についてはJest公式ドキュメントの記載やUzabaseさんの記事などを参考にさせていただきました。
開発者体験の向上
次に開発者体験の向上のためにいくつかの改善を実施しました。ここでは依存ライブラリのメンテナンスやAIエージェントを意識した改善を紹介します。
依存ライブラリのメンテナンス
様々なライブラリをアップグレードしました。いくつか例に挙げると以下のようなものがあります。
- Node.js を v20 から v22 へアップグレード
- yarn を v3 から v4 へアップグレード
- ESLint/Prettier を Biome v1 へ移行、その後すかさず v2 へアップグレード
- Vite を v6 から v7 へアップグレード
node-canvasを@napi-rs/canvasへ移行
主要ライブラリを上げることで、パフォーマンスが向上しCIおよび手元環境の立ち上がりが速くなったり、新機能によって開発者体験もよくなりました。 node-canvas の依存を剥がしたことで環境セットアップもよりシンプルになったのでとてもよかったです。
Dependabotが元々全社的に導入されているので、ライブラリが全くアップグレードされていなかったというわけではなかったですが、メジャーバージョンを上げる活動やモダンなライブラリへの移行は人間が意思を持って実行しない限り放置されがちなのでこのようにガッと対応することが大事だと思いました。一方で常にやる気がある人が対応する方針をとるのも難しいので、定期的にトリアージする仕組みも必要に感じています。
AIエージェントを意識した改善
開発者体験という面では、AIエージェントを利用したコーディングの際の体験も意識しています。弊社ではClaude CodeやDevinをヘビーに利用していますが、管理画面についてもAIエージェントがスピーディーに開発できるように以下の改善を実施しました。
- AI向けのドキュメント (CLAUDE.md) の整備
- MCPサーバーの設定の追加 (Playwright と MUI のMCPサーバーを入れています)
特にMCPサーバーについてはClaude Codeに実装をお願いする際に効率的にドキュメントを参照しながら進めてくれる感覚があるので意味のある活動なのではないかと感じています。
将来を見据えたコード品質の担保
仮に今回やる気になって色々と改善したとしても、将来に渡ってそれが継続されるとは限らないので、コード品質をどうにかして担保する必要があります。
Linterルールの有効化
わかりやすいところでまずBiomeの様々なルールを順番に有効にしていく変更をしました(今もしています)。元々少し緩めに運用されていたのと、ESLint→Biome移行のタイミングでも移行することがメインのゴールとなっていたので、しっかりと有効化していこうと思って実施しました。例えば以下のルールは有効化しています。
- noExplicitAny:
any型の禁止 - useAsConstAssertion:
as const推奨 - noInferrableTypes: 推論できる型を明示的に書かない
Linterはとても便利で、既存の実装を全部把握していなくてもルールを有効化することで違反しているコードを一覧することができます。違反しているコードはなるべく一括で修正しますが、時間がかかりそうな場合は特定の行のLintを biome-ignore で無視するようにし、段階的に対応することもできます。
一度ignoreしたコードも、適宜Devinを活用してAIに修正をお願いするということもやりました。最初に1ファイルだけ人間が修正を行い、その内容を見本としてAIに提示してあげることで同じパターンのものを順番に直してもらうということができて、効率的に改善を進められました。
TypeScriptの設定を厳格化
TypeScript コンパイラの設定を改めて見直すという活動も実施しました。コンパイルエラーなくそのまま有効化できた設定は一気に入れましたが、以下の設定についてはいくつかエラーが発生しているため、ひとつずつ確認して対応していっています。
- noUncheckedIndexedAccess: インデックスアクセスをより安全に実施できるようにするための設定
- exactOptionalPropertyTypes: オプショナルなプロパティに対してより厳格にチェックするようになる設定
せっかくTypeScriptを利用しているので、堅牢にできるところはやっていきたいし、CIで自動的に検知できるという点がとても安心できて嬉しいと感じています。特にAIエージェントにコードを書いてもらう際に「緩い」TypeScriptを書いてもらったままレビューで見落とされマージされてしまうというのを避けるためにも、機械的にチェックすることが大事だと思っています。
パッケージのバージョン指定やアップデート周りの調整
package.json に指定されているパッケージは元々全て ^ をprefixとしていました。このprefixがついていると、最も左端のゼロでない数値に対して固定しているだけで、ゆるい設定となっているため、完全に固定することにしました。
現状 yarn を利用しているので、設定ファイルにも以下の設定を追記しました。
defaultSemverRangePrefix: ""
また、 yarn install 時に出力されるログを注視しているとバージョンの不一致などが発生していることに気づいたので、簡単に対処できるものは自分で修正しました。ライブラリ作者へ連絡が必要なものもあったりします。bicstone/ra-language-japanese に関しては issue 上で報告し、実際に対応いただきました。その節はありがとうございました。
他にもDependabotのCooldown設定を入れて、よからぬアップデートが自動マージされるリスクの低下を期待したり、suzuki-shunsuke/pinactを利用してGitHub Actionsのサードパーティアクションをコミットハッシュで固定するといったことも実施しました。
地道な改善ですがこれらの変更はきっと将来に渡って安心して開発・運用に臨めるシステムを作るのに役に立っていると思います。
今後の課題と展望
今回の活動によって一定の成果は得られたと思いますが、まだ道半ばなのと、他にもやりたい改善はあります。特に以下の2点が個人的にはホットです。
- 開発者が管理画面へ手を入れるコストを減らしたい
- カスタマーサポートのメンバーにとってのユーザビリティを上げたい
現状、新しい画面を足すにはまずRailsのバックエンドサーバーに新しいREST APIのエンドポイントを追加し、管理画面にそれに対応した型定義を手で追加した上でReactを書いて画面を作っています。しかしこのまま続けていくとAPIエンドポイント数も膨大になっていきそうですし、型定義の手書きも面倒です3。同じような画面をしょっちゅう作っているならもう少し効率化できそうと思ったりしています。
定型的な実装がメインならどんどん効率化すれば良いですが、管理画面のユーザビリティも気になっています。データベースのテーブルに対するCRUD操作を画面に落とし込んだような管理画面は便利ではありますし、これまでの業務に非常に役立っていますが、本当に最適なのかを改めて考えるべきだと思っています。管理者、特にカスタマーサポートの方の業務フローをモデリングした上でそれに合った画面作りができると一番いいのではないかと思ったりしています。
終わりに
今回お話させていただいた内容は実はCRE Camp #1 でも登壇した時の以下の内容を、技術面で深掘りしたようなものとなりました。
CRE Campは第2回の開催も迫っているので、管理画面に限らず顧客との向き合い方などに関して関心があればぜひこちらもチェックしてみてください。
株式会社スマートバンクでは私のように「サーバーサイドエンジニア」として入社しつつもフロントエンドのコードベースをガッと改善するようなオーナーシップを発揮できるメンバーを募集しております。いつでもカジュアル面談お待ちしております。
- CREチームから顧客体験チームに生まれ変わりました - inSmartBank↩
- 並列数を上げるとその分GitHub Actionsの利用料金が嵩む可能性があるため、ちょうど良い分割数を見つけることが大事です。↩
- スキーマから型定義を自動生成するような仕組みは導入予定です。↩