RACCOON TECH BLOG

株式会社ラクーンホールディングスのエンジニア/デザイナーから技術情報をはじめ、世の中のためになることや社内のことなどを発信してます。

新卒技術研修で学習アプリからチーム開発までやった話

こんにちは。2026年4月に入社したエンジニアのWataru Shimodaです。

新卒の技術研修の流れや、最終的にチームでアプリを作るまでの学びを書いていきます。

研修では、先輩が用意してくれた研修用アプリでHTML、CSS、JavaScriptの基礎を学ぶところから始まり、HTTPリクエストの解析、SSHでのサーバー接続、モダンフレームワークを使ったチーム開発まで行いました。

Webの基礎を学ぶ

最初に取り組んだのは、先輩が作ってくれた研修用アプリです。

学習画面

研修用アプリでは、HTML、CSS、JavaScriptなどの基礎を、ブラウザ上で手を動かしながら学べるようになっていました。課題を進めると進捗が保存され、どのコースをどこまで完了したかが画面上で分かるようになっています。

ただ教材を読むだけではなく、自分でコードを書き、画面で結果を確認しながら進められたので、疑問に感じたことを実際に書きながら学ぶことができました。

裏ミッションでHTTPリクエストを読む

エンジニア向けの教材として与えられたのが、裏ミッションです。

研修用アプリの裏ミッション画面

このページを探すためにDevToolsを開き、hidden が設定されているタグを探すところから始まりました。

普通に画面を操作して課題を進めるだけではなく、DevToolsを開いて通信を見たり、APIのリクエスト内容を確認したりしながら進める内容でした。

たとえば、課題を完了したときにどのAPIが呼ばれているのか、リクエストにはどのような値が入っているのか、レスポンスでは進捗がどう返ってくるのかを見ていきました。

アプリ開発のためにSSHでUbuntuサーバーに接続する

エンジニアには、Proxmox上で動いているUbuntuサーバーへのアクセス権限が付与されました(あらかじめ用意された環境です)。

自分のPCからSSHでサーバーに接続し、そこで開発環境を動かします。

研修中に大活躍したのが、SSHのトンネル機能でした。

自分のPCからサーバーへSSH接続しつつ、サーバー上で動いているアプリを自分のPCのポートに転送します。さらに、自分のPC側で待ち受けることで、同じネットワークにいるメンバーが自分のPCへアクセスすれば、サーバー上のアプリを確認できるようにしました。

たとえば、サーバー上で localhost:8888 として動いているアプリを、自分のPCの 8888 番ポートから見られるようにする場合は、次のようなコマンドを使いました。

ssh -p  -L 8888:localhost:8888 {user}@{server-host}

フロントエンド、APIの複数サービスを自分のPCに転送したいときは-L(Local Port Forwarding)オプションを追加するだけでできます。

ssh -p  \
  -L 8888:localhost:8888 \
  -L 3000:localhost:3000 \
  {user}@{server-host}

これで、自分のPCのブラウザから http://localhost:8888 にアクセスすると、SSH越しにUbuntuサーバー上のアプリを確認できます。

さらに、同じネットワークにいるメンバーにも見てもらいたい場合は、localhostではなく、すべてのインターフェース0.0.0.0で待ち受ける設定にします。

ssh -p {ssh-port} -L 0.0.0.0:8888:localhost:8888 {user}@{server-host}

この状態でメンバーが http://{自分のPCのIPアドレス}:8888 にアクセスすると、メンバーのPCからもサーバー上のアプリを確認できます。

イメージとしては、次のような構成です。

SSHトンネルの構成図

SSHトンネルは、単にサーバーへログインするためのものではなく、ネットワーク的に直接届かないサービスへ安全に経路を作るためにも使えると知りました。

Claude Codeを使ってチームでアプリを作る

研修の後半では、Claude Codeを自由に使って、チームごとに好きなアプリを作り、最後にプレゼンする課題がありました。

ここでは、決められた仕様を実装するのではなく、自分たちで「何を作るか」を決めるところから始まりました。

私たちのチームでは、研修が終わったあとも使えるアプリがよいと考えました。そこで、新卒メンバー同士の予定を管理できるカレンダーアプリを作ることにしました。

ただのカレンダーでは既存のアプリとあまり変わらないため、研修後の自分たちが使う場面を考え、イベント参加や割り勘機能を入れることにしました。

主な機能は以下です。

使用した技術

次の技術を採用しました。

ホワイトボードから設計する

カレンダーアプリの画面は、最初にホワイトボードへざっくり書き出しました。

ホワイトボードに書いた画面設計

左側にイベント一覧や今日の運勢を置き、中央にカレンダーを表示する構成です。カレンダー上のイベントをクリックすると詳細を見られるようにし、そこから参加や割り勘の操作につなげる想定でした。

最初に手を動かす前に画面の流れを書いたことで、必要なデータも見えやすくなりました。

Redisのデータ設計を行う

今回のアプリでは、Redisを使ってデータを管理しました。

Redisを選んだ理由は、研修中にまずアプリとして動くものを作り切ることを優先したかったからです。

Redisであれば、キーと値を決めればすぐにデータを保存できます。イベント、ユーザー、割り勘、日付ごとの一覧などを、それぞれキーとして分けて持てるため、シンプルに扱えると考えました。

最終的には、次のような構成になりました。

Redis
  ├── users
  │   └── {name}, {name}, ...              例: "taro.yamada"
  │
  ├── user:{name}
  │   ├── name        : string
  │   └── createdAt   : ISO8601
  │
  ├── event:{id}
  │   ├── id          : string              UUID
  │   ├── type        : "drinking" | "lunch" | "circle" | "play" |
  │   │                 "dinner" | "sports" | "morning" | "study" |
  │   │                 "travel" | "other"
  │   ├── date        : "YYYY-MM-DD"        開始日
  │   ├── endDate?    : "YYYY-MM-DD"        任意、連日のとき
  │   ├── title       : string
  │   ├── time        : "HH:mm"
  │   ├── location    : string
  │   ├── capacity?   : string(数値)        任意
  │   ├── emoji?      : string              任意、カスタム絵文字
  │   ├── createdBy   : string              user name
  │   └── createdAt   : ISO8601
  │
  ├── event:{id}:participants
  │   └── {name}, ...                      行きたい/主催者を含む
  │
  ├── event:{id}:warikans
  │   └── {warikanId}, ...                 このイベントに紐づく割り勘ID
  │
  ├── date:{YYYY-MM-DD}:events
  │   └── {eventId}, ...                   日付に紐づくイベントIDの一覧
  │
  ├── events:index
  │   └── member: eventId, score: createdAt(ms)  作成順
  │
  ├── warikan:{id}
  │   ├── id           : string
  │   ├── eventId      : string             紐づくイベントID
  │   ├── createdBy    : string             user name
  │   ├── totalAmount  : string(数値)
  │   ├── createdAt    : ISO8601
  │   └── entries      : JSON              [{name, amount, paid}, ...]
  │
  ├── warikans:index
  │   └── member: warikanId, score: createdAt(ms)
  │
  └── fortune:{YYYY-MM-DD}
      └── JSON: ["name1", "name2", ...]

イベント本体、参加者、日付ごとの索引、割り勘を分けて持つ形です。

ここで難しかったのは、削除や更新の影響範囲でした。

たとえばイベントを削除すると、そのイベントに紐づく参加者情報なども消す必要があります。一方で、アカウント削除時に割り勘の履歴まで消してよいのかは別問題です。ユーザー情報としては消したいが、支払いの履歴としては残すべきものがあります。

実装してから気づいたのは、データ削除は単に該当データを消すだけではなく、それに紐づくデータも考慮する必要があることでした。

自分以外のPCからアクセスできずに詰まった

次に、別端末から確認したときに画面が真っ白になる問題が起きました。

最初はポートフォワーディングやネットワーク設定を疑いましたが、原因はNext.jsの開発サーバーが別オリジンからのアクセスを制限していたことでした。自分のPCでは localhost として見えていても、他のPCから自分のPCのIPアドレスでアクセスすると、ブラウザ上では別オリジンとして扱われます。

開発用途では、許可するオリジンを設定することで確認できるようになりました。

// next.config.ts

const nextConfig = {
allowedDevOrigins: ["<自分のPCのIPアドレス>"],
};

export default nextConfig;

ウェブサイトにアクセスできるのに、画面が一切表示されないという経験はしたことがなかったので、今後トラブルシューティングをする際に活用できる知識だと感じました。

フィードバックを受けながらUIを直す

UIは一度作って終わりではなく、何度も修正しました。

最初の実装では、フォントの色が薄くて見づらい、吹き出しの表示が邪魔になる、イベントが背景と同化して押せるのか分かりづらい、といった問題がありました。

メンバーからもらった主なフィードバックは次のようなことでした。

これを受けて、今日ボタンを目立たせたり、イベントをカード形式で表示したりしました。

特に印象に残っているのは、「自分では押せると思っていたものが、他の人には押せるように見えていなかった」ことです。

ボタンを少し大きくするだけでも使いやすさに直結するため、デザインとは単なる装飾ではなく、機能を成立させるための重要な設計の一部だと感じました。

実際のアプリ画面

ログイン画面

ログイン画面

ホーム画面
ホーム画面

アカウント削除
アカウント削除画面

イベント詳細

イベント詳細画面

割り勘設定画面
割り勘設定画面

研修全体を通して学んだこと

研修用アプリを通じて、バックエンドと連携することでできることの幅が広がると実感しました。

アプリ開発では、チームとして何を作るかを決め、設計し、フィードバックを受けて改善する流れを経験しました。

研修を通して感じたことは次のことです。

これから実務に入っていく中でも、今回学んだことを土台にして開発をしていきたいです。

最後に

ラクーンホールディングスでは、新しい仲間を募集しています!

少しでも興味を持った方は、ぜひ採用情報をご覧ください!

一緒にラクーンのサービスを作りませんか? 採用情報を詳しく見る

関連記事

運営会社:株式会社ラクーンホールディングス(c)2000 RACCOON HOLDINGS, Inc