株式会社ジーニーの28卒春期2Daysインターンシップに参加してきました

はじめに

2026年3月29日から30日にかけて行われた、株式会社ジーニーの28卒春期2Daysインターンシップ に参加してきたので、その振り返りを書いていく。

実は、これが私にとって初めてのインターンシップ参加であった。

参加までの経緯

きっかけは1月18日に東京国際フォーラムで開催された「外資就活Expo」の横で同時開催されていた「Engineer Guild Fes(EGF)」まで遡る。 ちなみに、このイベントはAtCoder経由で知った。

【2026/1/18(日)】リアル合同説明会「外資就活Expo」& 同時開催・エンジニアの未来をつくる文化祭「Engineer Guild Fes」 | 外資就活ドットコムgaishishukatsu.com favicon

このイベントで、株式会社ジーニーのトークセッションに参加し、企業ブースに立ち寄った際に、春のインターンシップの案内を頂いた。

その後、同社主催の2月の企業説明会にて正式に応募、選考面談とコーディングテストを経て、参加の内定に至った。

内定後、インターン2日前に事前交流会が行われた。 ここでは、同じインターンに参加する同期のメンバーの一部と交流することができ、インターン当日の流れも説明された。

インターンシップ当日の流れ

両日ともに都内の西新宿にある本社オフィスにて、オフラインで開催された。

オフィスの受付入ってすぐの景色
オフィスの受付入ってすぐの景色

1日目

事前に受付を済ませ、11時からインターン開始。 同じ日程での参加者は15人で、5人ずつの3チームに分かれることになった。

最初に会社説明や事業内容の紹介、メンターの方の自己紹介が行われた後、昼食のマックを食べながら、アイスブレイクも兼ねて同じチームのメンバーと自己紹介を行った。

意外にも都内出身者は私だけで、中部・関西からはるばる参加してきた方が多かった印象。


一通り交流が終わると、貸与されるPCのセットアップの後に、いよいよこのインターンシップでの課題についての説明が始まった。 ちなみに、PCはMacBook Proだった。 Macってろくに使ったことなかったけど案外使いやすいかも

どうやら、システム開発・運用保守チームのメンバーとして、CS(Customer Success)チームが日々使用するレポートページをより良くするために、改善案を考えてその実装を行うという内容のようだ。

詳細は次項の「課題の詳細とチームの取り組み」のセクションで説明するが、今回はこのテーマに沿って、「①既存機能の改修やリファクタリング」「②要件定義書に沿った新機能の開発」「③要件をチーム内で独自に設定した自由な機能開発」 の3つの課題に取り組むことになった。


開発の進め方は、チーム内でリーダーを選出し、リーダーが最初にタスクを一人一人に割り当て、各自はそのタスクに対して実装を進めていき、終わったら未着手のタスクをリーダーに確認して、次のタスクを割り当ててもらうという流れで行うことになった。

チームメンバーは全員バックエンド(Go / Gin)の経験がほぼなかったため、とりあえず課題1の「既存機能の改修やリファクタリング」について、タスク1つを1人ずつが担当して、フロントエンドとバックエンドの両面からの実装に慣れていくところから始めた。

1日目はAIツールを極力使わないルールだったこともあり、チーム内でのコミュニケーションを密に取りながら、試行錯誤して実装を進めていった。

しかし、やはり経験のない技術スタックでの開発はなかなか大変で、1日目は課題1のタスクを完了させるだけで精一杯であった。


17時半で一旦開発は終了し、ここからは本社オフィスの見学ツアーをさせていただけることになった。

今回のインターンの作業エリアにもなっている受付のあるフロアは、いろいろなドラマの撮影にも使われているらしい。執務室は普通の企業にもあるようなテーブルとチェアが並んでいるのだが、よく見るとモニターは34インチの曲面ディスプレイが使われていたり、キーボードは左右分割のものになっていたりと、各々のこだわりのある環境が整えられていることが分かった。 個人的には、モニターの土台に会計監査六法を置いている席があったのが印象深かった...

また別フロアの会議室やダイニングスペースも見せてもらったが、オフィスとは思えないようなおしゃれな感じで、特に会議室は、ポーカーテーブルや卓球台がテーブルになっている部屋や、ワイナリーが置かれている部屋など、ユニークな場所が多くて面白かった。

とある会議室。卓球台がテーブルになっている。
とある会議室。卓球台がテーブルになっている。

18時半、オフィス見学ツアーを終え、今日は解散。

同じチームメンバーのうちの3人と、オフィス近くのレストランで夕食を取ることができた。

2日目

2日目は朝10時集合。

今日はAIツールも駆使しながら、ゴリゴリ開発を行っていく。 開発スピードは格段に上がり、午前中で課題2の実装を完了させ、課題3の設計案の議論まで進めることができた。

12時ごろに弁当が支給され、昼食を取りつつ、引き続き開発を行う。

13時頃からは、順番に人事担当の方と個別に面談が行われた。 ここでは、今後の本選考の流れの説明を受けたり、将来のキャリアについての相談などをさせていただいたりした。

15時半ごろからは、成果発表に向けたスライドを並行して作成していく。 Google Slideを用いて、自分の担当箇所を中心に、アピールポイントや工夫した点などをまとめていった。

17時、開発時間終了。 チームごとに成果発表を行い、社員のメンターの方からフィードバックを頂く時間が設けられた。

フィードバックの後に、今回の課題に対する想定解答例や、実際の業務での類似のケーススタディなども紹介していただけた。

19時までで、今回のインターンシップの内容はおしまい。 ここからは参加メンバーや社員の方々と自由に交流ができる懇親会となった。

懇親会の食事
懇親会の食事

20時頃、全体解散。 私含む一部のメンバーは30分ほどさらに残って、社員の方とさらにお話をさせていただくことができた。

課題の詳細

CS(Customer Success)チームが日々使用するレポートページの改善」というテーマで、大きく分けて以下の3つの課題に取り組んだ。 ここでいう顧客(Customer)は、CSチームがサポートしているECサイトの運営者を指す。

  1. レポート一覧の改善(既存機能の改修)
    • 既存のレポート一覧画面のパフォーマンス改善・リファクタリング(N+1問題の解消や不要なレンダリングの削減)
    • 新規機能として、レポートの検索機能を実装
    • 実装済みのCSVダウンロード機能に、文字コードの指定やファイル名にタイムスタンプを付与する機能の追加
  2. 時間別レポートの新規作成
    • PRD(要件定義書)を基に、時間軸でPVやCVRなどのメトリクス(指標)の変動を確認できるチャート・グラフ付きのレポート画面を新規実装
  3. サマリーレポートの自由実装
    • 想定され得るCSからの要望について、チームで独自に要件定義を行ってゼロからレポート画面を設計・実装する自由課題

自分の作業内容

リーダーは他の方が務めてくださったものの、チーム内でGitの運用に一番慣れていたのが私だったため、ブランチ運用やPull Request(PR)の管理などは私が中心となって行うことが多かった。

結果的には、各作業ブランチからdevelopブランチへのPRを私が管理する形になったため、コードの品質管理や大量に発生したConflict処理なども私が主に担当することになった。これがマジで大変だった...

以下では、私が担当したタスク内容と、実装を進める中で直面した課題や工夫した点についてまとめる。

担当したタスク

課題1

CSVエクスポート時にタイムスタンプを付与する機能を追加

レポート一覧画面において、一覧データをCSVとしてダウンロードする既存機能に対して、ファイル名の末尾に、ダウンロード時のタイムスタンプをyyyyMMdd_HHmmssの形式で付与する機能を追加した。

具体的には、dayjsというJavaScriptのライブラリを用いて、dayjs().format('YYYYMMDD-HHmmss')のようにして現在日時をフォーマットし、テンプレートリテラルでファイル名の末尾に埋め込む形で実装した。

これにより、複数回同じCSVをダウンロードしてもファイル名が重複しないようになった。

N+1問題の解消

従来のコードでは、バックエンドのSQLクエリにおいて、

  1. レポート閲覧可能なアカウントの一覧をaccountsテーブルから取得
  2. 各アカウントに対して、レポートの関連データをreportsテーブルから個別に取得

といった計算量 O(N)O(N) の処理が行われていたため、アカウント数が増えるとクエリの回数も大きく増えてしまうという、いわゆる「N+1問題」が発生していた。


そこで、accountsreportsとをidが一致するレコードでINNER JOINすることで、一度のクエリでレポートの関連データをまとめて取得できるようにし、計算量を O(1)O(1) に削減することができた。

また、フロントエンドにおけるレンダリングでは、JSXのreturn文の中で直接mapを利用してコンポーネントを構築した上で、useMemoを用いてメモ化することで、状態の変更があっても必要な部分だけが再レンダリングされるようにした。

useEffect/useMemo/useCallback/memo の適切な使用

従来のコードではuseStateuseEffectなどに過度に依存していたため、React Hooksの適切な使用により、パフォーマンス最適化と不要な再レンダリングの抑止を図った。 具体的には、以下のような変更を行った。

  1. useEffectの見直し: useEffectを使用していた箇所のうち、Effectが必要ない部分を見直し、単純な状態管理や計算であれば、直接レンダリングの中で行うように変更した。これにより、状態の変更に伴う副作用の発生を抑え、コードのシンプルさとパフォーマンスの両立を図った。
  2. useMemoの導入: 重い計算や参照を固定したい値のメモ化にuseMemoを導入した。
  3. memo (React.memo) の導入: レンダリングの最適化のため、子コンポーネントをmemoでラップして、不要なレンダリングを防いだ。
  4. useCallbackの導入: 各入力のアクションハンドラや、子コンポーネントに渡す関数をuseCallbackで定義するように変更した。依存する値が変わらない限り、関数インスタンスを再利用するようにした。

課題2

時間別レポートページの新規ルーティング実装

課題2に着手する上でのベースとなる、新規ページのルーティングの実装を担当した。

  1. 新規ページの作成: とりあえず新規ページコンポーネントとして、/reports/time-seriesのパスに対応する TimeSeriesReportPage を作成した。内部では Material UI コンポーネントを使用して、フィルタリング用の入力フォーム(アカウント選択や日付指定など)やテーブル、Rechartsを用いたグラフなど、時間別レポートに必要な各種 UI やロジックを軽く実装しておいた。
  2. TanstackRouterを使用してルーティング実装: こちらはこのタスクの必須条件ということで、router.tsx@tanstack/react-routercreateRouteを利用し、パス/reports/time-seriesに対するルートtimeSeriesRouteを定義した。最終的にrootRoute.addChildren内にこのルートを追加し、ルーターcreateRouterで管理されるようにしている。
  3. ナビゲーションの追加: サイドバーコンポーネントを記述したsidebar.tsxで定義されているメニュー配列表へ、新しく「時間別レポート」のオブジェクトを追加した。これにより、ユーザーはサイドバーのメニューから新規ページへ遷移できるようになった。

課題2の残りの部分については、私がConflictと格闘している間に他のチームメンバーが実装を進めてくれていた。圧倒的感謝。

課題3

課題3に取り組むにあたって、私たちのチームで想定した顧客要望は以下の通りである。

  1. ECサイトの売り上げとPV数等の関連性を知りたい
  2. CSチーム内で企業ごとに分析データの比較を行いたい
  3. データアナリストのような専門家でなくても、簡単にデータから分析をできるようにしたい
  4. 作成した分析レポートをダウンロードして共有できるようにしたい

1.については、新たに「売上レポート」というページを作成して、売上データの推移や評価指標のグラフ化を行うことで、PV数やCVRなどの指標と売上の関連性を視覚的に把握できるようにした。

2.については、これまでに作成した「時間別レポート」や「売上レポート」のページの企業選択フィルタを、複数のアカウントが選択可能な仕様に変更し、複数企業のデータを同一グラフ内で比較できるようにした。

3.については、新たに「サマリーレポート」というページを作成し、KPIの全体概況表示や期間比較機能などを実装したうえで、各KPIの数値を分析して「CVRが低下している」などの具体的なテキストとアラートを自動生成する機能も実装した。「自動」と言いつつ、ただの条件分岐と対応テキストのハードコーディングだが...

4.については、上記のサマリーレポートや売上レポートのページにおいて、CSVやPDFなどの形式でレポートをダウンロードできる機能を実装した。


これらのタスクに関しても、基本的な実装は他のチームメンバーが行ってくれたのだが、機能統合の過程で私は以下のような細かい調整を行っていた。

JSTオフセットのタイムゾーン計算バグの修正

「売上レポート」ページ内で日付指定のデータの集計を行う際に、レコードのタイムスタンプをday.jsでパースする処理に「一律で +9 時間 のJSTオフセットを足す」という独自の関数が組み込まれていた。 しかし、JavaScriptの実行環境やフロントエンドのライブラリでは、デフォルトでローカルのタイムゾーンを考慮して時間をフォーマットするので、ここでさらに +9 時間してしまうと、時間が二重にズレて集計されるバグ(「データが翌日のものとしてグラフに表示される」など)が発生してしまう。

そこで、+9 時間の加算を削除し、純粋にdayjs(timestampMicro / 1000)のみで正しい時間を取得できるように修正した。

加えて、7日間や30日間での期間指定の計算ロジックを、「現在時刻からマイナス nn 日」という雑な計算から、 startOf('day')endOf('day')を使った正確な「1日の始まり~終わり」の取得へと修正した。

UI/UXの改善とリファクタリング

  • アカウント選択のAutocomplete化(検索機能の向上): 時間別レポート等でのアカウントを絞り込むフィルターについて、単純なプルダウン(Selectコンポーネント)から、文字入力でインクリメンタルサーチが可能なAutocompleteコンポーネントへと修正した。これにより、膨大な顧客アカウントリストから、アカウント名の一部を入力するだけで瞬時に目的の顧客を見つけてフィルタリングすることができる。

  • ステータスサマリーの追加: 「売上レポート」や「サマリーレポート」ページの画面上部に、現在のフィルター条件で絞り込まれたレポートのステータス(CV / leave / error)それぞれの合計件数が一目で分かるように、チップによるサマリー表示を追加した。これにより、ユーザは現在のレポートの全体的な状況を瞬時に把握できるようになった。

成果発表とフィードバック

2日目の夕方には、チームで作成したスライドを基に、デモも交えながら成果発表を行った。

社員のメンターの方からのフィードバックでは、UI/UXが実際の業務アプリのようで質が高く、「ツールを使うCS側に寄り添った細やかな実装ができていた」とお褒めの言葉を頂くことができた。


以下、他チームの発表で印象に残ったポイントをまとめておく。

  • バックエンドのAPIの構成を起点として、フロントエンドのコンポーネント構成やルーティングを設計していくという、いわゆるイベント駆動型の開発スタイルを実践していたチームがあった。
    • これにより、バックエンドとフロントエンドをきれいに切り分けて開発を進めることができていて、コードの保守性や拡張性の観点で優れた設計になっていた。
  • サマリーレポートのテキストの生成にChatGPTを活用する。
    • セキュリティとかデータ保護の観点で不安があるけど、これはチーム内で「出来たらいいよね」という話にはなっていた。
  • 課題3において、Google Analyticsのようなアクセスサマリーを実装していたチームがあった。訪問元サイト別に折れ線積み上げグラフを作成することで、流入元の可視化を行っていた。
    • このアイデアは思いつかなかったので、非常に参考になった。

インターンシップを通しての感想

初めてのインターンシップ参加ということで最初は緊張していたのだが、全体的にオープンな雰囲気で、参加者のみならず社員の方もフレンドリーに接してくださったおかげで、すぐに打ち解けることができた。

特に、同じチームメンバーとは対面で密にコミュニケーションを取りながら、実装の方針やコードの内容について議論し、協力して課題に取り組むことができた。 これはオンラインでの開発ではなかなか得られない、オフラインならではの貴重な経験だったと感じている。

また、実際の企業のオフィスに訪問することで、今のIT企業の働く環境や雰囲気を肌で感じることができたのも、非常に有意義だった。


技術的な学びとしては、やはりチーム開発の経験ができたことが大きかった。

今まではほとんど個人開発しかしてこなかったので、Gitを用いた本格的なブランチ運用や、Pull Requestを通じたコードレビューの経験ができたのは良かったと思う。

今回はベースの構成のファイル数が少なかったこともあって、チーム間で同じファイルを編集する場面が多く頻繁にConflictが発生してしまったのだが、これを解消するために、コードの内容を理解しながらどの変更を残すべきか、どの変更を捨てるべきか、あるいは両方の変更を組み合わせるべきかなどを判断して、手動でマージしていくという経験は、今後のチーム開発においても非常に役立つものになると感じた。


また、「テストコードを書く」ことについての知見が得られたのも大きかった。

これまでの個人開発だと、「ブラウザ上で動いてるからいいじゃん」のような感じで、テストコードをちゃんと書いたことはなかったのだが、バックエンドハンドラのテストコードを書いてみると、「この関数はこういう入力に対してこういう出力を返すべき」という仕様をコード上で明確に定義できるようになり、コードの品質や保守性が格段に向上することを実感できた。

今回は手が回らなかったのだが、フロントエンドのコンポーネントのテストコードも、外部の状態に依存しない純粋関数として定義して、ユニットテストを充実させることで、リファクタリングの際の安心感が増すなど、コードの品質向上に大きく寄与することが期待できると感じた。Vitestとかも使ってみたい

おわりに

今回のインターンシップを通じて、実際の企業での開発現場を体験し、チーム開発の経験を積むことができたのは大きな収穫だったと感じている。

また、社員の方々や他の参加者との交流を通じて、業界の雰囲気や働く環境についても理解を深めることができた。

同期のメンバーの方やジーニー社の社員の方々には大変お世話になりました。 ありがとうございました!