Safie Engineers' Blog!

Safieのエンジニアが書くブログです

Next.js × FastAPIで「脱スプレッドシート」。25新卒研修3ヶ月で作った備品貸出管理システム 前編

はじめに

この記事はSafie Engineers' Blog! Advent Calendar 20日目の記事です。

こんにちは、セーフィー株式会社に25新卒として入社した緑川です。

我々新卒エンジニア7人「宝舟」は、今年2025年の4月から7月にかけて新卒研修として社内の課題を解決するプロダクトの開発を行いました。

その研修で開発した「Treasure Collection」について、この記事と明日公開の後編にて説明します。

注目した課題

セーフィーはクラウドカメラサービスの会社なので、オフィスでは多くのカメラや周辺機器が使われています。特に品質保証を行うクオリティマネジメントオフィスでは、検証用カメラや関連機器の管理、貸出を行っています。その記録はスプレッドシートを使って行われていました。

各備品の所在を把握したり、必要な人が借りるためには記録が重要です。しかし備品の数が増えるにつれ、スプレッドシートのメンテナンスは大きな負担になっています。

どう解決するか?

ヒアリングによって上記の課題を認識した結果、

備品の所在や貸し借りを正確かつ簡単に記録できるシステムを研修で作ることになりました。

そうして作ったのが、「Treasure Collection」です。

主な機能は、以下の3つです。

  1. 備品管理者が備品の情報を登録できる
  2. 検索機能によって任意の条件に合った備品を検索できる
  3. 貸出申請・承認を通じて貸し借りを管理できる

このアプリによって、ユーザーは使いたい備品を簡単に見つけて、貸出を申請することができます。

備品の管理者は申請を承認するだけで貸出情報を記録することができ、今誰が持っているのか常に把握することができます。

アプリのイメージ

Treasure Collectionがどんなアプリなのか、各画面の紹介を通して説明していきます。

備品一覧画面

備品の検索

Treasure Collectionのトップページには、登録されている備品が一覧表示されます。

中心に備品の情報や現在の状態を示すカードが縦に並んでいます。備品はカテゴリごとにグルーピングされて表示されます。

左側にあるのが、表示する備品を絞り込むための検索バーです。備品情報にテキストで検索をかけられるほか、カテゴリや貸出状況、自分が借りているかどうかなどで検索を行うことができます。

この検索機能を使うことでユーザーは任意の条件の備品を簡単に見つけることができます。

備品の登録

各カテゴリの見出し部分にある、「備品追加」ボタンから新しく備品を追加することができます。

こちらが備品の登録画面です。備品に紐づく情報は、以下の通りです。

  • カテゴリ
    • 「カメラ」、「ルーター」など、備品の大まかな種別
  • 管理者
    • その備品を管理していて、貸出を承認する権限をもつユーザー
  • 保管場所
    • その備品が普段保管されている場所
  • 備考
  • プロパティ
    • カテゴリに紐づく備品の詳細情報
    • カメラの場合、「メーカー」、「シリアルナンバー」、「機種名」など

管理者はこれらの情報を入力して備品を新規登録します。この備品の登録は依然として負担のかかる作業となっていますが、少しでも簡略化するためにCSVによる一括登録もサポートしています。

貸出申請

備品一覧画面から貸出申請も行うことができます。備品カードの一番右か、備品詳細モーダルにある貸出申請ボタンをクリックすることで貸出申請モーダルを開くことができます。

備品を借りたいユーザーは、ここに借りる目的や返却予定日を入力して貸出申請します。ここで入力した目的や予定日は貸出申請メッセージに含まれるため、管理者が可否を判断しやすくなっています。

カテゴリ管理画面

カテゴリ管理機能は、Treasure Collectionの中でも工夫したポイントでした。

カテゴリは運用開始後も新しく増えることが予想されるので、備品の管理権限を持つユーザーが柔軟に追加できれば便利になります。

また、備品に紐づく情報はカテゴリによって異なることが予想されます。例えば、ケーブルであれば「長さ」の情報が欲しく、ディスプレイであれば「解像度」が欲しいです。このようなカテゴリによって異なる備品情報も備品管理者から編集できたほうがいいと考え、できたのがカテゴリ管理機能です。

画像の表は、カテゴリの名前と、それに紐づく情報が並んだものです。備品管理者の権限を持つユーザーに限り、これを編集することができます。

このカテゴリに紐づく情報のことをTreasure Collectionでは「プロパティ」と呼びます。プロパティは名前と入力が必須かどうかを指定することができます。上の画像は「カメラ」カテゴリに指定されたプロパティを編集する画面で、シリアルナンバー、メーカー、付属品などの情報が紐づけられるように指定されています。

備品の貸し出し

このシステムでも最も重要な貸出処理について説明します。

以下の手順を踏むことで、備品の貸し出しがシステムに記録されます。

  1. ユーザーが借りたい備品に対して、貸出申請を出す
  2. 専用Slackチャンネルに、管理者にメンションされた申請メッセージが送信される
  3. 管理者は申請を承認または拒否する
  4. 承認された場合、ユーザーは管理者から備品を受け取ってから受け取り完了ボタンを押す

貸し借りの申請・承認は普段社内で使われているSlackからできるので、メッセージに気づきやすく、関連するやり取りもそのまま行えます。

上の画像は貸出申請メッセージのイメージです。管理者が承認または拒否のボタンを押すことで手続きが終了します。それだけであれば、アプリを開く必要もありません。

そのほか機能

返却リマインダー

人力で返却の催促をするのが大変だという話は初期から聞いていて、その解決策を形にしたのがこの機能です。期限が過ぎた備品の返却を促すメッセージがSlackで毎朝送信されます。メッセージにはアプリの備品詳細画面へのリンクがあるので、すぐに返却処理を行うことができます。

CSVバックアップ

毎日システムに登録された全備品とその貸し借りの情報をCSVファイルとして出力します。人間が読み書きしやすいように体裁が整えられて出力されるので、もしシステムが止まってもGoogle スプレッドシートにアップロードするだけで暫定的な備品管理体制が用意できます。

技術説明

Treasure Collectionの開発のために使ったものや、技術的な工夫点について説明します。

技術選定

以下のような言語やツールを使用しています。全体として課題解決のための開発スピードを重視し、メンバーが触ったことのあるものを中心に採用しました。

フロントエンド

フレームワークとしてNext.jsを使用しています。メンバーにReactの経験がある人がいたこと、開発しやすさのために素のReactよりNextの方がいいという意見が出たことから採用しました。複数のページがあるアプリケーションのため特にApp Routerの機能が役立ちました。

バックエンド

セーフィーで開発しているサービスで実際に使用されていること、Pythonの使用経験がある人が多かったことからバックエンドはFastAPIで開発しています。Pythonの充実したライブラリを活かして比較的簡単に開発できること、APIドキュメントが自動的に作成されることなどが便利でした。

データベースにはPostgreSQLを採用しました。これは、カテゴリとプロパティの機能の実現のためにJSONのカラムをサポートしているのが魅力的だったからです。

インフラ

アプリケーションはAWS上にデプロイされ、Terraformで管理しています。

インフラの構成図がこちらです。システムが止まって貸し借りができない、ということがないように耐障害性を重視し冗長化しています。

備品とその貸出情報は定期的にCSVとしてバックアップされるので、万が一の場合でもスプレッドシートを使った貸出管理に戻すことができるようになっています。

そのほか、Dockerを使って環境構築やデプロイを単純化したり、GitHub Actionsを使ってテストやフォーマットチェックを確実に行えるようにするなど、様々なツールを使って開発手順の効率化にも取り組みました。7人での開発だったこともあり、大きく効果を感じられました。

まとめ

研修で開発した備品の貸し出し管理アプリであるTreasure Collectionについて説明してきました。多くの研修メンバーにとってユーザーとやり取りをしながら大がかりなアプリケーションを開発するのは初の試みで、大きな経験を得ることができました。このTreasure Collectionは執筆時現在も継続的に開発中で、議論しながら改善や新機能開発を行っています。

より詳しい振り返りや今後の展望については翌日公開の後編にて、メンバーの中さんより詳しく説明します。お楽しみに!

© Safie Inc.