クックパッドマートの生鮮食品を SORACOM の IoT デバイスで遠隔温度監視している話

クックパッドマートでサーバーサイドなどのソフトウェアエンジニアをしている石川です。

この記事では、クックパッドマートの物流の一部で SORACOM のサービスを活用して生鮮食品の遠隔温度監視を行っている話について、主にサーバーサイドの取り組みを紹介します。

クックパッドマートの物流

クックパッドマートの物流は、非常に大雑把に言うと以下のような手順になっています。

  1. 販売者さんが集荷場所に置いてあるコンテナへ商品を届ける。
  2. ドライバーさんが集荷場所からコンテナを集めて回る。
  3. 集めたコンテナを、商品の受け取り場所の冷蔵庫に届ける。
  4. 冷蔵庫に届いた商品をユーザーさんが受け取る。

まとめると、(販売者さん)→集荷場所→(ドライバーさん)→ステーション→(ユーザーさん)、という図式になっています。

ここでコンテナと言っているのは物理的な容器の方のコンテナです。以下のようなコンテナに食品を入れて運んでいます。

緑色の折り畳めるコンテナの写真です。
コンテナ

今回注目するのは、ドライバーさんが集荷場所から受け取り場所に届けるまでの間です。集荷場所から受け取り場所の間ではドライバーさんが車両でコンテナを移動させています。お肉やお魚などの生鮮食品を扱っているため移動の間も温度を低く保ちたいのですが、コンテナをそのまま運んでしまうと温度を低く保つのが難しいため、蓄冷剤の入った保冷用のボックスにコンテナを入れて運んでいます。

保冷用のボックスというのは次の写真のような、銀色の箱です。コンテナがいくつか入る程度の大きさになっています。

外側が銀色になっている、直方体の箱です。
保冷用ボックス

この保冷用ボックスの温度を遠隔監視しよう、というのがこの記事のテーマです。

GPS マルチユニット SORACOM Edition

2021 年 4 月現在、私たちはこの保冷ボックスの温度を「GPS マルチユニット SORACOM Edition」を使って計測しています。このセンサーは京セラさんのセンサー「GPS マルチユニット」をベースに SORACOM プラットフォームで利用しやすくするためのカスタムがなされているセンサーです。温度の他、湿度、加速度、位置情報を計測できます。

GPS マルチユニット SORACOM Edition の見た目は下のような感じです。後ろでコンテナの中に入っているものは食品サンプルです。

白くて薄い直方体の形をしたセンサーです。背景には保冷用ボックスが写り込んでいます。
GPS マルチユニット SORACOM Edition

GPS マルチユニット SORACOM Edition は、実装当初候補に挙がっていた他のセンサーと比較しても実装工数が少なく済みそうなことや、今回のユースケースに充分な測定精度があること、充分な数を入手できそうなことなどを理由に採用しました。

SORACOM プラットフォーム上でこの GPS マルチユニットを使う場合、SORACOM Lagoon を使ってダッシュボードを作れる他、SORACOM FunnelSORACOM Funk を使って他のクラウドサービスへデータを送ることができます。今回は SORACOM Funnel を使って AWS へデータを送っています。

温度データの利用

具体的な構成の説明に入る前に、私たちが温度データを使ってどのような機能を作ったかを説明します。

保冷用バッグの中には生鮮食品が入っているため、GPS マルチユニットの示す温度は低く保たれている必要があります。もし GPS マルチユニットの温度が高くなり始めた場合、その GPS マルチユニットの入った保冷用ボックスを運んでいるドライバーさんにご確認いただこうということになりました。

しかし GPS マルチユニット自体には温度を表示する液晶画面の類や異常を知らせるブザーなどはついていないため、何かしら別の方法でドライバーさんに異常を伝えなければいけません。そこで GPS マルチユニットの温度データを元にドライバーさんへ通知をする機能を作りました。

元々ドライバーさんには、当日の配送ルートの表示や集めるコンテナの指示などを行う目的でモバイルアプリを使っていただいていました。これはドライバーさん専用アプリで、販売者さんの商品を販売するアプリとは別のものです。社内では通称「ドライバーアプリ」と呼ばれています。

もし GPS マルチユニットの温度が高くなり始めた場合、このドライバーアプリ越しにプッシュ通知してお知らせするようにしています。以下のような感じです。

プッシュ通知のスクリーンショットです。内容には「シッパー内の温度が高くなっていませんか?」「タップして続ける」と書かれています。
プッシュ通知

※「シッパー」と書かれているのが保冷用ボックスのことです。

また、先述のように GPS マルチユニット自体を目で見ても温度は分からないため、ドライバーアプリから現在の温度が確認できるようにもしています。

ところでこの機能を実装するためには、それぞれの GPS マルチユニットをどのドライバーさんが持っているのか知らなければいけません。この紐付け登録もドライバーアプリを使って行っています。具体的には、それぞれの GPS マルチユニットに二次元コードを貼り付け、ドライバーさんにモバイルアプリで読み取ってもらうことで登録しています。

更にドライバーさん向けだけでなく、弊社の社内オペレーター向けにも温度データが見えるようにもしています。具体的には、Grafana を使ったダッシュボードで温度の時系列変化が確認できるようにしたり、GPS マルチユニットの温度が高い状態を維持した場合に Slack へ通知が来るようにしたりもしています。

構成

以上のような機能を作るため、サーバーサイドでは以下のような構成を採用しました。

各々のサービスを示すアイコンが矢印で結ばれています。まず GPS マルチユニット SORACOM Edition から SORACOM Funnel に矢印が伸びており、SORACOM Funnel から Amazon Kinesis Data Firehose に伸びています。そこから AWS Lambda に伸びており、AWS Lambda からは 2 本の矢印がそれぞれ Amazon CloudWatch と Amazon DynamoDB に伸びています。
構成図

まず、GPS マルチユニットから SORACOM へ送られてきたデータを SORACOM FunnelAmazon Kinesis Data Firehose に転送します。続いてそのデータを AWS Lambda を使って整形しつつ Amazon CloudWatchAmazon DynamoDB に流します。図からは省略していますがモバイルアプリからは API アプリを介して DynamoDB にある温度データにアクセスできるようになっています。なお、データの行き先が CloudWatch と DynamoDB の 2 つになっているのは開発事情の都合です。

構成自体はシンプルで、全体の実装にもそこまで長い時間はかかりませんでした。たとえば AWS Lambda の部分は AWS CDK を使って 1 日かからずに作れています。

なお、自分が不慣れだったこともあり、上記の構成に落ち着くまでには少し時間がかかりました。たとえば論点をひとつ取り上げると、SORACOM Funnel と SORACOM Funk のどちらを使うかというものがありました。

SORACOM Funnel と SORACOM Funk はどちらもクラウド間を結ぶ「アダプタ」であるという意味で似たサービスです。結果的に Lambda を実行するのであれば、SORACOM から別のクラウドへデータを運ぶ仕組みである SORACOM Funnel ではなく、SORACOM から別のクラウドの関数を実行する仕組みである SORACOM Funk を利用する選択肢もありました。しかし今回は SORACOM Funnel を採用しています。

これは、SORACOM Funnel の方がそれぞれの温度データのタイムスタンプをより正確に得られそうであったためです。GPS マルチユニット SORACOM Edition はデータ取得時の時刻を送らないため何かしらの時刻を使ってタイムスタンプを計算する必要があるのですが、SORACOM Funk を使った場合タイムスタンプの誤差が大きくなりうるという問題がありました。

というのも、今回の実装時点の SORACOM Funk は、GPS マルチユニットからのデータを受信した瞬間のタイムスタンプを保持していませんでした。このため SORACOM Funk を使った場合に温度データのタイムスタンプを得るには「SORACOM Funk 経由で実行された Lambda の内部で現在時刻を取得して温度データのタイムスタンプとする」ような実装が必要でした。しかし Lambda の実行が失敗してリトライされる可能性があることを考えると誤差が許容できないと判断しました。SORACOM Funnel ではデータを受信した瞬間のタイムスタンプが保持されており、この問題が起こりませんでした。

ただし SORACOM Funnel にも、GPS マルチユニットがデータを取得するタイミングと Funnel がデータを受信するタイミングにズレがあるという別の問題はあります。

この問題については、今回は温度について秒単位でのリアルタイム性は要求されておらず、またデータ取得時刻とデータ受信時刻のズレは充分小さいらしいことが分かったため、許容することにしています。実際私たちが気にしているのは「温度の低い状態が維持されているか」であり、特定時刻の温度を正確に知りたい訳ではないため、これで充分と判断しました。

このようにいくつかの論点を考えた上で今回の構成に至りました。そして実際今のところサービスが成長しドライバーさんが増えていく中でもこの構成のまま運用を進められており、ベターな選択であったと考えています。

最後に

以上のように、この記事では、GPS マルチユニット SORACOM Edition を使って生鮮食品の温度を遠隔監視している話を紹介しました。

ところで、実際にこの仕組みを使って温度を計測してみると、たとえば車がトンネルに入ると少しのあいだ温度が上手く取得できないことがあるなどの問題が分かっています。現状は安全側に倒してデータ取得失敗時も通知を行い、人力で判断している状態です。このような状況をどうしていくか、ハードウェアとソフトウェアの両面から改善を進めています。

このようにクックパッドマートでは実世界にまつわる様々な課題にハードからもソフトからも切り込み、スピード感のある開発を続けています。弊社ではただいま絶賛エンジニア募集中ですので、ぜひ採用情報をご覧くださいませ。

cookpad.careers

※SORACOM は、株式会社ソラコムの登録商標または商標です。

JSON Schema をクックパッドマートの商品登録画面に導入した話

主にバックエンドのエンジニアとしてクックパッドマートの開発に携わっている塩出( @solt9029 )です。

美味しい食材をユーザにお届けするサービスであるクックパッドマートでは、日々街の販売店や地域の生産者が商品の登録を行っています。
商品を登録する際、販売者は消費期限をはじめとする様々な品質保証の情報を正確に入力する必要があります。
しかし、商品の種類や状態に応じて記載するべき品質保証の情報は異なるため、全項目が羅列されるフォームでは正確な入力が困難であり、販売者および商品の審査を行う社内の運用メンバに対して大きな負担をかけていました。 そこで、 JSON Schema を利用して複雑なフォームの出し分けを自動で制御し、またバックエンド側でのバリデーションも行うことが出来る仕組みを導入しました。
その結果、商品の種類や状態を選択するだけで、適切な品質保証の情報が自動的に入力され、必要な項目のフォームのみが表示されるようになり、販売者および商品の審査を行う社内の運用メンバの負担を大きく減らすことが出来ました。

JSON Schema を導入した商品登録画面

JSON Schema による商品の種類ごとのフォームの比較

背景・目的

クックパッドマートは、弊社が力を入れて取り組んでいる新規事業の1つです。生鮮食品を中心として扱っているECプラットフォームで、街の販売店や地域の生産者が、販売者としてクックパッドマートに参加しています。コンビニエンスストア・ドラッグストア・駅・マンションなどの様々な場所に、ユーザの受け取り場所として専用の冷蔵庫が設置されています。ユーザはアプリから注文を行い、冷蔵庫から生鮮食品を受け取ることができます。

クックパッドマートでは、販売者が商品の登録や日々の出荷作業などを行うための機能を提供する販売者向け管理画面を開発しています。
販売者向け管理画面を通じて商品登録をする際に、商品名や写真、価格だけでなく、消費期限や解凍品かどうかなどの、品質保証や食品表示に関わる情報も入力する必要があります。
一方で、それらの情報は商品の種類や状態に応じて入力するべきものが異なり、全項目が羅列されるフォームでは正しい項目を入力することが難しい状態でした。

例えば、じゃがいもをそのまま販売する場合、消費期限を入力する必要はなく、「お早めにお召し上がりください」といった文言を特記事項として記載する必要があります。
また、製品として販売されているドレッシングのように、商品自体に消費期限や賞味期限が元から記載されている場合、消費期限ではなく保証消費期限として、出荷日から最低限品質が保証される日数を入力する必要があります。この場合、販売者は保証消費期限よりも長い日数の消費期限や賞味期限が記載された商品を出荷する必要があります。
その他には、鮮魚や魚介加工品などの商品を販売するときには、生食用なのか・養殖なのか・解凍品なのか、といった項目を明示する必要があります。
このように、商品登録をする際には、商品の種類や状態に応じてそれぞれ異なった種類のデータを入力する必要がありますが、全項目が羅列されるフォームから人手でどの情報を入力するべきかを都度判断するのはとても困難です。そのため、商品の種類や状態に応じて、適切なフォームが出し分けされる仕組みが求められていました。

また、フロントエンド側でフォームの出し分け制御がされるだけでは、不正なデータの登録を完全に防ぐことはできません。社内の運用メンバが商品の販売開始前に商品審査を行っているものの、商品審査の負担やミスを避けるために、バックエンド側でバリデーションされた上で商品が登録されている状態が望ましいです。

複雑なフォームの出し分けのみであれば、 JavaScript でオレオレ実装をすることも考えましたが、バックエンド側のバリデーションまで考慮すると、共通した Schema が存在している状態が望ましいと考えました。そこで、複雑なフォームの出し分けおよびバリデーションをすることが可能な仕組みとして、 JSON Schema を導入することにしました。

実装

JSON Schema とは

JSON Schema とは、その名の通り JSON の構造を定義したものです。 OpenAPI で利用されている記述方法として知っている方も多いかもしれません。百聞は一見にしかずということで、JSON Schema とそれに対応する JSON の簡単なサンプルをご紹介します。

{
  title: "お料理レシピ",
  type: "object",
  properties: {
    id: { title: "ID", type: "integer" },
    title: { title: "タイトル", type: "string" },
    content: { title: "作り方", type: "string" },
    public: { title: "公開中", type: "boolean" }
  },
  required: ["id", "title", "content", "public"]
}
{
  id: 100,
  title: "カルボナーラの作り方",
  content: "ベーコンと玉ねぎを食べやすい大きさに切ります。〜(以下略)",
  public: true
}

このように型や必須項目など、 JSON の構造を定義することができます。他にも、本記事で扱う dependencies や oneOf などといった、複雑な構造を定義するときに便利な方法が豊富に用意されています。より詳細な仕様については、 Understanding JSON Schema をご参照ください。

JSON Schema の定義

商品登録時の JSON Schema を定義するにあたって、商品の種類ごとに必要なフォームの出し分けができるような構造を考える必要がありました。詳細な説明は省きますが、代表的な商品の種類を一部抜粋してご紹介します。

  • 根菜類(玉ねぎ、人参、じゃがいも)
    • 品質保証の種類:品質保証に関する特記事項 → テキストを入力するフォームが必要(デフォルトでは「お早めにお召し上がりください。」と入力される)
  • 鶏肉
    • 品質保証の種類:消費期限 → 日数を入力するフォームが必要
    • 解凍表示を入力するフォームが必要
  • 魚介加工品
    • 生食表示(生食用 / 加熱用)を入力するフォームが必要
    • 養殖表示(養殖 / 天然)を入力するフォームが必要
    • 解凍表示を入力するフォームが必要
    • 解凍品を選択した場合
      • 品質保証の種類:消費期限 → 日数を入力するフォームが必要
    • 非解凍品を選択した場合
      • 品質保証の種類:保証消費期限(配送日から最低限品質が保証される期間) → 日数を入力するフォームが必要

特に魚介加工品が一番複雑に見えると思います。このように、ある特定の値に応じてフォームの出し分けをする必要がある場合には、 JSON Schema の definitions・dependencies・oneOf などを利用します。魚介加工品の要件を JSON Schema として表現したときに、最終的には下記のようになりました。それなりに複雑な JSON にはなりますが、自前で出し分けを自動で制御するロジックやバリデーションをゼロから実装するよりも、遥かに簡単に記述することができました。

{
  required: ["raw", "thawed", "farmed"],
  properties: {
    category_id: { const: "魚介加工品カテゴリのID" },
    thawed: { "$ref" => "#/definitions/thawed" },
    farmed: { "$ref" => "#/definitions/farmed" },
    raw: { "$ref" => "#/definitions/raw" },
  },
  dependencies: {
    thawed: {
      oneOf: [
        {
          properties: {
            thawed: { const: true }, # 解凍品だった場合、消費期限
            quality_guarantee: { "$ref" => "#/definitions/quality_guarantee/definitions/expiration" },
          },
        },
        {
          properties: {
            thawed: { const: false }, # 非解凍品だった場合、保証消費期限
            quality_guarantee: { "$ref" => "#/definitions/quality_guarantee/definitions/guarantee_expiration" },
          },
        },
      ],
    },
  },
}

ライブラリ選定

クックパッドマートの販売者向け管理画面について、フロントエンドは Rails の View の仕組みを用いて HTML が返される仕組みとなっています。また、動的な処理などを追加する際には TypeScript / React を用いている状態です。そのため、 React で JSON Schema に基づいたフォームの出し分けを自動で制御するライブラリとして、 react-jsonschema-form を利用することとしました。
また、バックエンドについては Rails で開発が行われているため、 Ruby 製で JSON Schema に基づくバリデーションをすることができるライブラリが必要でした。そのため、 json_schemer を選定することにしました。

json_schemer

json_schemer はとても簡単に導入することができました。下記のように検証したい JSON を渡してあげることでバリデーションをすることができます。

JSONSchemer.schema(json_schema).valid?(json_to_be_validated)

react-jsonschema-form

react-jsonschema-form が JSON Schema の定義に沿ってフォームの出し分けを自動で制御してくれるため、自分で実装する必要のある箇所は主に見た目に関する部分でした。具体的には uiSchema と、 Widget や FieldTemplate と呼ばれる React Component です。

FieldTemplate や Widget は JSON Schema のそれぞれの入力フォームを描画する際に利用される Component です。JSON Schema および後述する uiSchema で渡される値を Props として受け取り、その情報を元に描画を行います。実装例は下記の通りです。

export const FieldTemplate = (props: FieldTemplateProps) => {
  const { label, required, children, rawDescription, rawHelp } = props;

  return (
    <Card>
      <Card.Header>
        <div>
          {required ? (
              <Badge variant="primary">必須</Badge>
          ) : (
              <Badge variant="secondary">任意</Badge>
          )}
          {label}
        </div>
      </Card.Header>
      <Card.Body>
        {rawDescription && <Card.Text>{rawDescription}</Card.Text>}
        {children} {/* この部分で Widget の描画が行われる */}
        {rawHelp && <small>{rawHelp}</small>}
      </Card.Body>
    </Card>
  );
};
export const RadioWidget = (props) => (
  <div className="field-radio-group">
    {props.options.enumOptions.map((option, i) => {
      return (
        <div key={i}>
          <label>
            <input
              disabled={props.disabled}
              type="radio"
              name={props.options.name}
              value={option.value}
              onChange={() => {
                props.onChange(option.value);
              }}
            />
            <span>{option.label}</span>
          </label>
        </div>
      );
    })}
  </div>
);

uiSchema について、下記は養殖か天然かを入力するフォームの定義例です。その入力フォームを描画するときに使用したい Widget の指定や、説明文の付与などの指定を行うことができます。uiSchema で指定された値は Widget の Props として渡されます。

{
  farmed: {
    'ui:disabled': isDisabled,
    'ui:name': 'item[farmed]',
    'ui:widget': RadioWidget,
    'ui:help': '養殖か天然を必ず選択してください。',
  },
  // ...
}

JSON Schema を導入した結果

これまでは新規登録された商品の内、約10%の割合で品質保証の項目の入力不備がありましたが、JSON Schema を導入したことによって、商品の種類や状態を選ぶだけで品質保証の種類が自動的に選択されるようになったため、品質保証の項目に関する入力不備はゼロになりました。商品登録時の正確性や体験を改善し、商品審査の運用負担を大きく減らすことができました。
Schema に基づいた実装を行っているため、今後新しく要件が増えたとしても JSON Schema の定義を更新するのみで解決し、フロントエンド側のフォームの出し分け制御ロジック・バックエンド側のバリデーションを容易に追加・更新することが可能な状態になりました。

最後に

クックパッドマートでは事業成長のためにスピードを高めて開発に取り組んでおり、様々な技術に触れる機会も多くとても楽しい環境です。弊社では絶賛エンジニア募集中なので、興味を持って頂けた方はぜひ採用情報をご覧ください。

cookpad.careers

Cookpad Online Spring Internship 2021 と Hackarade を合同開催しました

ユーザー・決済基盤部の三吉(@sankichi92)です。 昨年よりエンジニアの立場から新卒採用を担当しています。

2月の記事で告知したスプリングインターンシップを 3/22〜26 の日程で開催しました。 また、同時に社内でも Hackrade Remote #2 を開催し、社員もインターン生と同じ課題に取り組みました。 この記事はその開催レポートです。

合同開催について

今回のインターンシップのコンセプトは「クックパッドの社内ハッカソン "Hackarade" を体験してみよう!」というものでした。 Hackarade は Hack + Parade を組み合わせた社内の造語で、ハッカソンではあるものの「競技」より「祭り」の側面が強い社内イベントです。 アイデアや成果を競い合うのではなく、社内エンジニアの技術力向上を目的としています。 過去の Hackarade については、"Hackarade" でブログ内を検索してみてください。

そして、せっかく Hackarade をやるのならインターン生だけではもったいない、ということで社内 Hackarade の合同開催が決まりました。 具体的には、インターンシップと同じ期間に社内でも Hackarade を開催し、成果発表をインターン生と合同で行うことにしました。 以下は、合同開催が決定した時のツイートです。

クックパッドでは昨年の春よりオンラインでインターンシップを開催していますが、オンラインでは社内の雰囲気が伝わりづらいという課題がありました。 合同開催には、実際の社内イベントと重ねて関わる社員を増やすことで、会社の様子を少しでもイメージしやすくする狙いもあります。 実際、インターン生がシングルチャンネルゲストとして参加する Slack チャンネルは、これまでのインターンシップと比べても非常に活発でした。 スクリーンショットのように、インターン生21人を含む83人から5日間で3,000件を超えるメッセージが投稿されました1f:id:sankichi92:20210401000058p:plain

講義動画について

Hackarade には毎回テーマがあり、社内の第一人者による講義を受けたのち開発に取り組む形式が基本です。 今回のインターンシップ & Hackarade のテーマは「Web フロントエンド」で、講師を外村(@hokaccha)が務めました。 また、オンラインのメリットを活かす取り組みとして、講義動画を事前に撮影し、参加者各自の好きなタイミングで視聴してもらう形を取りました。 わからなかったところは何度も見返したり、知っている内容は倍速で飛ばしたりできると、インターン生・社員ともに好評でした。

ここで、実際に使用した講義動画を公開します。

講義動画はトピックごとに以下の4つからなります。

  1. JavaScript
  2. TypeScript
  3. React
  4. Next.js

モダン Web フロントエンドに入門したい方や、上に挙げたようなトピックをおさらいしたい方など、ぜひご覧になってください。

インターンシップについて

インターンシップは、初日に講義動画の共有や課題の発表を行い、最終日5日目に成果発表してもらう、というスケジュールでした。 その間、質問は Slack で受け付け、講師・TA の誰か回答できる人が回答します。 テキストだけで難しい場合は、Zoom を使用することもありました。

課題は、Next.js と TypeScript を使ってレシピサイトを作る、というものでした。 基本課題と発展課題に分かれており、基本課題は講義動画を見ればだいたいできる内容です。 一方、発展課題は Web フロントエンドに慣れている人でも5日間やることがなくならないよう、かなりのボリュームになっています。 詳細は https://gist.github.com/hokaccha/7003c700f7d2ad276bfb458edd862abe をご覧ください。 データについて、今回はインターンシップ用に Web API を用意しました。

講師の想定を超えて、基本課題を2日目の朝6時に終える猛者や、すべての発展課題に取り組む猛者がいました。 同じ課題に取り組んでいても、成果発表では参加者ごとの個性がよく出ていて感心しました。

今回のインターンシップでの大きなチャレンジは、従来のような対面型でのインターンを単にオンラインにするのではなく、オンラインならではの効果が得られるような実施方法を模索することでした。 先ほど触れた講義動画はそのひとつです。 会場という制約がないので、必ず全員が参加しなければならない場面も減らすことができます。 5日間を通して、時間を合わせて集まるのは初日と最終日のみの計5時間ほどでした。 2〜4日目は、毎日1時間オフィスアワーとして講師・TAが Zoom に待機する時間を設けていましたが、そちらよりむしろテキストのコミュニケーション方が活発でした。 3日目には、Tech MTG という隔週で開催しているエンジニア全員参加のミーティングを見学する機会も設けましたが、これも任意参加です。 事前に2〜4日目の時間の使い方は自由とアナウンスしていたので、インターンシップ期間中に研究したり、卒業式に出席したり、引越ししたりする参加者がいました。 インターンシップの様子は、Twitter ハッシュタグ #cookpad_spring_intern から覗くことができます。

Hackarade について

社内の Hackarade は、前回のリモート開催時同様、開催期間のうち「8時間まで開発に使ってよい」というルールにしました。 また、インターンシップと異なり、以下の2部門があります。

  • 規定部門: インターン生向け課題のレギューレーションに従って開発する
  • 自由部門: 講義内容の技術を使って自由に開発する

規定部門はインターン生が5日間かけて取り組むボリュームということもあり、自由部門のエントリーが多くなりました。 ここからはいくつか作品をピックアップして紹介します。

Ruby コミッターの @mametter からは「ブラウザの上で Ruby を動かす」という発表がありました。 Web フロントエンドがテーマのはずなのに、irb が(ブラウザで)動き始めるという、予想の斜め上をいく作品でした。

また、おまけとして1時間(!)で書いた Next.js を使った Quine の紹介もありました。 遠藤さんの Quine は社内で有名ですが、インターン生にはどう見えたのか気になるところです。

買物プロダクト開発部の @solt9029 からは「ズルできるババ抜き」の発表がありました。 発表中は「これを作ろうと思った思考プロセスが気になる」といったコメントが寄せられました。

他にも、分析 SQL のシェアができるアプリや、GHE・Slack などから社内情報をまとめて検索できるアプリなど、社員待望の便利ツールや、業務での利用を視野に入れた QR コード読み取り機能のプロトタイプ、趣味でやっているポッドキャストの Web ページなどなど、多彩な作品が集まりました。

また、規定部門の発表では、講師・TA から Auth0 を使った認証やインクリメンタルサーチ、Storybook を使ったコンポーネント開発、Recoil を使った状態管理など、課題では扱われなかった少し発展的な技術の紹介がありました。


以上が、Cookpad Online Spring Internship 2021 & Hackarade Remote #2 の開催報告です。 ご参加いただいた皆さま、本当にありがとうございました!

スプリングインターンシップは終わってしまいましたが、クックパッドでは就業型インターンシップを通年で募集しています。

また、サマーインターンシップも例年どおり開催予定です。 興味のある方はぜひご応募ください!


  1. アプリやインテグレーションによる投稿はなく、すべて人間による投稿です。Tech MTG や成果発表では多くの社員を巻き込んで盛り上がりました。