https://cookpad.connpass.com/event/249346/ にて発表。
© 2022 Cookpad Inc.クックパッドマートの失敗したデータ設計Before / After 大放出 Cookpad Tech Kitchen #27〜Rails/Next.js/IoTによる食品流通〜 / 2022年6月30日(木)
View Slide
© 2022 Cookpad Inc. 2バックエンドエンジニア Who? @mokuzon Motoi Okuzono 職種経歴SNS趣味2016/08 クックパッド入社 社内情報共有ツール開発 2017/05 クックパッド料理教室 2019/07 クックパッドマート 販売者 2019/12 クックパッドマート 流通 2022/07 クックパッドマート EC @mokuzon オーケストラでホルンを吹く 飲酒 最近はモンハン はやくサンブレイクやりたい
クックパッドマートで生鮮食品流通を実現するには 物理的・論理的を問わず様々な要素があります その中からいくつかを失敗談を交えてご紹介していきます © 2022 Cookpad Inc. 3
© 2022 Cookpad Inc. 4● 商品や、商品をいれるコンテナに貼る ● ユーザーやドライバーが商品や配送指示を認識するための重要なインターフェース ● 種類がいろいろあって、補助的なものも含めると 10 種類ぐらいある ラベル
© 2022 Cookpad Inc. 5ラベル ● ラベルの種類ごとにテーブルがあり ● 1 枚ごとに 1 レコード ● その日の出荷する注文が締め切られたタイミングで一斉にレコード書き込み ● そのレコードを元にラベルプリンターで印刷 ● 印刷のためのデータとログとしてのデータが共通 Before● 配送データが書き換わると印刷前にラベルデータも作り直し ● 販売者の欠品処理とデータ作成タイミングが同じでエラーが多発 Problem
© 2022 Cookpad Inc. 6ラベル ● 印刷データは配送データから動的に生成 ● その印刷データをログとして印刷時にレコード書き込み ● クックパッドマートにおける宣言的ラベル生成 https://techlife.cookpad.com/entry/2021/08/18/100000 After詳しい人イベント参加者限定コンテンツイベント参加者限定コンテンツ
© 2022 Cookpad Inc. 7営業日 ● 定休日と臨時休業日をそれぞれ別テーブルに記録 Before● 定休日に臨時営業したくなったらもう一つテーブルを追加...? ● 営業有無を算出するロジックが複雑化し扱いづらい ● 臨時休業と臨時営業を同時に設定できないようにしたりも必要 Problem● 販売者や受け取り場所にはお休みの日があるところもある ● お盆やお正月など不規則なスケジュールもある
© 2022 Cookpad Inc. 8営業日 ● 営業の有無をベタに保存するテーブルを作り、それを参照 ● 上記テーブルのデータを作るための規則を保存するテーブルも用意 ● 営業日などの規則性と例外を扱うための設計 https://blog.osa.in.net/schedule-and-scheduling-policies-pattern/ After詳しい人イベント参加者限定コンテンツイベント参加者限定コンテンツ
© 2022 Cookpad Inc. 9留まることの表現 ● 商品やそれが入ったコンテナはいくつかの拠点に留まり 配送や受け取りを待つ ● 同じ場所を同じ時間で取り合わないように管理が必要 受け取り場所 / ステーション 配送拠点 / ハブ ココに決めた!ココに決めた!
© 2022 Cookpad Inc. 10留まることの表現 ● 「この便に乗っているものは何時から何時」というドメイン知識から 「これとこれは被る」というのをすべて網羅して判定 ● 今日出荷された商品は昨日出荷された商品が最初に到達するハブでは時間帯が被らない ● 今日出荷された商品は昨日出荷された商品が最後に到達するハブでは時間帯が被る ● etc… ● というような条件を愚直に十数件判定Before● 競合するパターンをすべて洗い出すのは難しい ○ 実際に考慮漏れをして競合させてしまい損失が出たことも 😭 ○ 肌感では複数サイクル (マートでは日) を跨いだ影響が出るようになると 考慮漏れが発生しだす Problemココに入れたい被ってるコンテナある?
© 2022 Cookpad Inc. 11留まることの表現 ● 素朴に留まることを表現するテーブルを用意 ● クックパッドマート最難解ロジック!?「採番」 https://techlife.cookpad.com/entry/cookpad-mart-assignments-2022 After詳しい人イベント参加者限定コンテンツイベント参加者限定コンテンツイベント参加者限定コンテンツ
買えることの表現 クックパッドマートでは購入時に以下 2 つを選択する 受け取り場所 受け取り日 この組み合わせを Delivery と呼んで概念化している とある商品 ( Product ) がとある Delivery で買えるかは状況によって変わる ● 販売者の営業日 ● 配送経路の関係 (現在はこれによって差がステーション間に出来ることはほぼない) 買えないにも 2 種類ある ● 同じ受け取り場所で異なる受取日なら買える ○ これを明確に表示したい ● 同じ受け取り場所ならどうやっても買えない これを表現する手段が必要
© 2022 Cookpad Inc. 13買えることの表現 ● 買える ○ DeliveryProduct という中間モデルで表現 ● 同じ受け取り場所で異なる受取日なら買える ○ DeliveryUnavailableProduct という中間モデルで表現 ● それぞれデータは同名のテーブルに永続化 Before● 商品一覧を作るのに毎回 DP と DUP をクエリーして足し合わせる必要がある ● 商品を購入可能 ⇔ 不可能の状態が管理しにくい ○ 都度レコードの生成・削除が必要 Problem
© 2022 Cookpad Inc. 14買えることの表現 ● すべて DP に一本化、DUP の状態は DP に status enum を生やし表現 ● 700 受け取り場所 x 13,000 商品 x 7 日 = 63,700,000 レコードで依然課題ではある After詳しい人イベント参加者限定コンテンツイベント参加者限定コンテンツ
© 2022 Cookpad Inc. 15● toB があるサービスと PDF 生成は切っても切り離せない ○ 特に初期は web が整っていないこともあり紙のコミュニケーションが多い ○ 現場において、小さな端末の画面を見る必要がなく コピーも可能な物理的な媒体の需要は依然大きい PDF
© 2022 Cookpad Inc. 16PDF 1. Excel でテンプレートを作る 2. rubyXL gem を使って Rails のデータを書き込む 3. LibraOffice で PDF に変換する 4. qpdf でテンプレートで用意された余分なページを削除 Before● PDF の種類が増えるたびに Excel のテンプレートが増え、Docker の image size が肥大化 ● 実行時間が長い ● テンプレートで想定していない量の注文が入るたびに、テンプレートの行数を増やす ぬくもりのあるオペレーション 😇 Problem
© 2022 Cookpad Inc. 17PDF ● prawn gem で宣言的に生成 After詳しい人イベント参加者限定コンテンツイベント参加者限定コンテンツ
© 2022 Cookpad Inc. 18まだまだありますが今日はこの辺で...
● クックパッドマートは作り直しにとっても寛容 ○ 最初の要件に対しては元の作り方で十分だったが、要件が増えて辛くなることはザラ ○ 最初から未来の要件をすべて見通すのは不可能 ○ とにかく最初はシュッと作るが、辛くなったらすぐ作り直しを検討していくことで 新規事業にとって重要な初速 と長期運用に必要な品質 のバランスを取っている ● クックパッドマートではいろんなことができます ○ 登場人物の種類が多い ■ ユーザー、販売者、ドライバー、受け取り場所設置者、マートスタッフ etc. ○ それぞれに対して物理的に必要なもの、必要なロジックが沢山ある ○ 何かしら刺さっていたら幸いです 伝えたかったこと © 2022 Cookpad Inc. 19
© 2022 Cookpad Inc. 20