UUUO Tech Blog

水産流通のDXや業務効率化を実現するアプリケーション「UUUO」「atohama」を開発・展開している株式会社ウーオのテックブログです。プロダクトにまつわる様々な情報発信を行います。

2021年〜2024年前半の担当施策振り返り

こんにちは! ウーオのソフトウェアエンジニアの井草です。 私事で恐縮ですが、産休でしばらくお休みをいただくことになりました。今回のブログでは、入社した2021年後半から現在まで私が関わった施策をメインとした振り返りをしていきます。

タイムライン

2021年

アプリ「Maehama Cloud」リリース

現在まで続く魚を仕入れるためアプリ「UUUO」の他、全国の水揚げ情報を配信するアプリ「Maehama Cloud」の開発を開始し、2021年7月にリリースしました。 水揚げについてはリリース以前もLINE公式アカウント上で案内していましたが、取引先産地が増えるにつれテキストでの配信に限界があり、アプリでの情報発信へと切り替えました。

アプリでは魚種ごと・産地ごとで水揚げが見れる他、過去その魚がどのくらい獲れていたかも見れるようになっていました(※現在は水揚げ情報の配信を停止しています)。

漁獲情報は各産地のLINEグループからの情報やHPから取得しているのですが、配信のためのオペレーション改善については↓で記事化されています。

note.com

kg売り出品

UUUOアプリではそれまでケース売りでのみ出品可能でしたが、kg売り出品に対応しました。その対応により、出荷する段階まで合計kg数が分からず金額が確定しない商品についても出品することが出来るようになりました。

出荷タブ

出品者向けアプリ「UUUO Sellers」にて、受注したものを表示する購入一覧タブに加えて出荷タブを追加しました。 出荷便ごとの表示に対応し、商品を何時の出荷便で出荷するのか分かりやすくなりました。

2022年

アプリ統合

前年にMaehama Cloudをリリースし、発注用のアプリUUUO(+出品者向けアプリUUUO Sellers)と並行して開発を進めてきましたが、検証を重ねた結果水揚げ情報機能をUUUOアプリに体験を統合する流れとなりました。

アプリの統合の経緯について👇

note.com

リクエスト出品

水揚げ日前日に事前注文を取りたいという要望に応えて、リクエスト出品機能を追加しました。 「セリ前商品」という名前に変わって現在も活用されています。

鮮魚BOX内訳表示

鮮魚BOXの取り扱いが増えるにつれ中に入っている魚種が多様になったため、魚種の内訳を入力しやすくし、アプリ上の表示も分かりやすく改善して出荷ミスが起きにくいように対応しました。

販売時間ごとの出荷便の締切時間改善

それまでは各出品に紐づく販売時間で登録されている締切時間によって各ユーザーが購入できる期間を一律で管理していましたが、出荷便の締切時刻に合わせたり、その日によって締切の時刻を変えられるようにして柔軟に締切時間を設定出来るようになりました。

この頃開催したイベントで登壇する機会があり、この施策について触れています👇

speakerdeck.com

荷口番号対応

2022年12月1日、違法に採捕されたアワビ・ナマコの流通を防止するために施行された水産流通適正化法により、荷口番号(漁獲番号)という取引の際に発行された番号の伝達・管理が義務付けられました。アプリ上でも施行に合わせて荷口番号を管理できるように対応しています。

2023年

️タイムライン

出品以外の形で情報発信を行うことで売上の向上につなげるため、タイムライン機能を追加しました。 現在はオススメタブの中で出品者からの投稿を確認する事が出来ます。

️クレカ決済 / ヤマトクール便対応

新規顧客層の飲食店の利用シーンに合わせ、クレジット決済機能・ヤマト便で受け取れる機能をリリースしました。 それまでは支払いは銀行振込、発送は市場便(産地と市場間を輸送する専用の便)のみでしたが、飲食店ユーザーでも購入ができるようにインフラ整備を進めました。

tech-uuuo.hatenablog.jp

出品コピー

以前出した魚種と同じような商品を出品する際、一から作成する必要があり出品作業に時間がかかる問題がありました。 過去の出品をコピー出来るようにする事によって出品時間が減り作業効率が上がりました。

加工対応

加工オプションの設定を追加し、出品者が対応できる場合は内蔵処理等の加工をした状態で商品を提供出来るようになりました。 商品によって加工賃の設定を変更出来るため、対応の手間の違いから適切な価格で販売出来るようになっています。

Algoliaによる検索機能の改善

UUUOアプリの検索機能は2021年時点でありましたが、魚種名での検索しかできませんでした。「産地や漁法、食べ方などで検索し、意図した商品を見つけたい」という要望に応えるべく、検索機能改善を行っています。

tech-uuuo.hatenablog.jp

出品アプリのWeb対応

商品の発注はUUUOアプリを使用してのみ行う事が出来ていましたが、アプリをインストールしなくても発注が出来るようにWeb版の立ち上げを行いました。 Next.jsを採用しています。

tech-uuuo.hatenablog.jp

リリースしたWeb版はこちら👇

https://app.uuuo.jp/commerces

2024年

産直表示

UUUOアプリでは産直品の取り扱いがメインでしたが、市場入荷品(入荷量が多く供給が安定しているため安価な商品)が増えた事で一見して商品の区別がつきにくい課題がありました。アプリ上の表示を改善し、産直品/市場入荷品が分かりやすいように変更を加えました。

おわりに

今回は、私が関わってきた施策についてまとめました。
入社してから3年弱も経っていることに驚きですが、振り返ると色々なことをやってきたなと感慨深い気持ちになりました笑
今年に入って約3割が経ちましたが、その間に私が関わった施策以外にもおすすめ商品の提案等、大きめの機能がリリースしていて勢いを感じます。 この勢いに乗り遅れないよう、復帰した際には今まで以上に頑張ります💪

ウーオでは水産流通を革新するため、プロダクトを通じてあらゆるアプローチをしています。ウーオの事業やプロダクト開発にご興味がある方は、以下をぜひご覧ください 👇

uuuo.co.jp

◆カジュアル面談はこちらから◆ / 株式会社ウーオ

各ポジションの募集要項はこちら

<業務委託スタート可>ソフトウェアエンジニア(Mobile Application/Flutter) / 株式会社ウーオ

<業務委託スタート可>ソフトウェアエンジニア(Frontend/Flutter on the Web) / 株式会社ウーオ

<業務委託スタート可>ソフトウェアエンジニア(Backend/Ruby on Rails) / 株式会社ウーオ

鮮魚バイヤー向けおすすめ提案のアプリデザイン

このブログは、2024年2月29日に note に投稿した記事を転載したものです。 note では技術記事以外にも多くの記事があるので、是非ご覧ください!

note.com


こんにちは!株式会社ウーオでUI/UXデザイナーをしている久保坂(@misaaa09)です。

先日水産流通マーケットプレイス「UUUO」でユーザーに合った商品提案を行う「オススメ提案機能」をリリースしました。

オススメ提案機能の画面イメージ

約6ヶ月で構想からリリースまでを行い、その中で様々のメンバーを巻き込みながら進めたプロジェクトでした。 今日は具体的な開発フローの紹介とともに、周囲を巻き込みながらデザインしていくうえで工夫しているポイントをお伝えしたいと思います。

構想〜リリースまでの半年間のタイムライン

続きを読む

OCR/AI を用いた FAX の読み取りによる商品掲載自動化の仕組みづくり

こんにちは! ウーオのソフトウェアエンジニアの髙橋(@yt_hizi)です 👋 今回は OCR/AI のプロダクトへの適用事例について紹介します。

tl; dr

  • 入荷案内の PDF は毎日複数社から届き、これを入力するのに大変な時間がかかる
  • Azure の Document Intelligence を用いて入荷案内情報を OCR で解析し効率化した
  • OCR をプロダクトに組み込む際は、業務に沿った形でデータを変換することがプロダクトの価値になる

ウーオは日々の入荷案内を全国に届ける

市場では日々、さまざまな魚が取引されています。日によって市場にある魚の種類が違えば量も違います。 そういった情報を、市場の事業者は「入荷案内」という形で1つのドキュメントにまとめて、取引先に入荷情報を伝えます。 取引先は、入荷情報を見てどの魚をどれだけ買おうか、というのを日々判断して購入し、これが最終的に私たちの食卓に届くわけです。

そんな入荷案内は、市場の事業者の取引先であるウーオにも日々届きます。 ウーオは各社から届く入荷案内に載っている情報を、市場の事業者の代わりに水産マーケットプレイスである「UUUO」に掲載し、全国のお客様が買えるようにしています。

これだけでも全国のお客様にとっては大きな価値となりうるのですが、日々入荷案内は複数社から届き、各社の入荷案内には約50商品ほどが掲載されています。

これら全てをアプリに掲載するために人力で入力すると、毎日数時間をこのために使うことになってしまいます。これでは効率が良くないので、なんとかしようというのが今回のプロジェクトです。

続きを読む

Algolia (with Ruby on Rails) を使って検索機能を改善してみました。

はじめに

こんにちは! 冬に美味しい鰆が準絶滅危惧種に指定されたということに驚きを隠せない t3qyo です。
特選京サワラはUUUOでも購入できます。飲食店様、仲卸様、スーパー発注担当者様、UUUOをどうぞ鮮魚仕入れにご活用ください!

app.uuuo.jp

先日のウオ会でセールスチームが握ったサワラ鮨

前置きはさておき、 最近、UUUOアプリで検索の改善を行ったので共有します。

改善後の画面
改善後の画面


続きを読む

Ruby biz 2023 大賞受賞に寄せて、水産流通における Ruby や Ruby on Rails の活用についての話

こんばんは、土谷(@taihaku0415)です!

ウーオは、11月8日に行われたRuby biz Grand prix 表彰式でありがたいことに大賞をいただきました。 個人的には、プログラミングを始めた一番最初の言語がRubyだったのもあり、非常に感慨深かったです。

Matz-product-uuuo
まつもとさんとプロダクトチームで写真

せっかくいただいた大賞をきっかけに、ウーオの開発のことを知っていただければなと思い、ブログを書きました(11月最終日になってしまいました)。

ウーオは、

の2つのサービスを開発しています。

まず、UUUOとatohamaの使用技術を非常に簡単にご紹介すると、ユーザ側のクライアントサイドのアプリから叩かれるAPIサーバーは全てRuby on Railsを採用しています。APIサーバーはWebとWorkerからなり、非同期関連のジョブはSidekiqで構築しております。

また、基本的にインフラはPaaSのHerokuを使っており、データベースを始めエラー検知、データ解析、モニタリング等を目的としたツール等もHerokuのAdd onで実現しています。

社内で利用している管理画面(sashimori)はRailsのView(Haml)を利用してフロントを構築しています。

このブログでは、2019年に入社してから今まで、ウーオの開発でRuby+周辺技術*1を利用していますが、そこの背景や意図について書きたいと思います。

1. プロダクト作りに集中したかった

採用資料より

この構成(主にRails + Heroku)にしたのには、水産業におけるプロダクト開発(≒価値の具体化)に集中し、標準的に備えたい仕組みや機能とともにサービスを素早く立ち上げて価値検証に時間を使いたかったから*2、です。

水産業は専門性が高く、開発者も身近に感じづらい領域で、ユーザの課題1つとっても理解するために乗り越えるべきハードルが高い業界だと思います。

それは、具体的には

  • 関わるプレイヤーが多く多岐に渡る
  • 電話やFAX等の通信手段で売買が行われる
  • 特有の商習慣があり参入しづらい

等、サービス開発するにおいて私自身も、どこから手をつけたらいいかわからないことだらけでした。

ウーオでは、頻繁にエンジニア、プロダクトマネージャーが現場に行って観察を行います。 開発の比較的多くの時間を現場に入り込んで業界・ユーザ理解に比重が多く置かれる場面もあります。 詳しくは パソコン捨てて、市場に行こう港でパフォーマンスチューニング 等をご覧ください。

2. 入社後のキャッチアップのしやすさ

採用や組織づくりという観点で言うと、ウーオでは、強弱はあれど実は Ruby に拘らず、一定のバックエンド・サーバーサイドの開発経験があれば、ウーオの事業やプロダクト開発に共感してくれるメンバーを積極的に採用してきました。なので、採用候補者の方へのアプローチ時もあまりRubyという枠では絞っていなくて、プロダクトづくり、ユーザに価値を届けること、課題解決が好き、と言ったメンバーが集まっています。

水産未経験は当然ですが、RubyRailsも未経験だったというメンバーが多くいます。

土谷太皓氏は「Rubyのおかげで会社が成長できている。特にプログラミング未経験の人でも、Rubyを使うことで楽しみながら開発できていると感じる」とコメント - https://news.yahoo.co.jp/articles/7eb969867bdcda6b7dded6ae96ed05c30ea0afcb より引用

(プログラミング初心者ではなく、Rubyが未経験という意味で表彰式のスピーチでは話をしたつもりでしたが...笑) 上の記事にも書いていただいているように、実際今いるメンバーの内7割のエンジニアはウーオに入ってからRubyを書き始めました。

キャッチアップのしやすさの1つに、コミュニティやエコシステムが成熟しており、一定のレベルまでのキャッチアップまではすぐできるように支援してくれるドキュメントも豊富ですし、

何か実現したい解決策がある時も豊富な Gems からパッと探して取り入れることもできると思います。

もちろん、Ruby未経験だったメンバーにとっての難しいところもありますし(ex. 自由(?)に書け過ぎる)、チームとしては社内の開発ガイドラインを設けてみんな一定のルールのもと実装ができるようにしていたりもします。

3. 複雑なドメインロジックとうまく付き合っていきたい

同じカレイでも、サイズの定義は港ごとに違う

冒頭にも書いた通り、水産業は多くの複雑なドメインが混在しています。

例えば、UUUOのRailsアプリのコードを見ても

  • 魚種にまつわるモデル(呼び名、魚種ごとの規格)
  • 物流のモデル
  • 購入や決済のモデル
  • 色々なプレイヤーがいることによる組織のモデル

等がパッと思い浮かびます。

(あまり詳細には踏み込みませんが) 少し具体的な話をすると、上記の例の物流のモデルにも関係する、ユーザごとの出荷方法を決定するだけでも、

  • 通常のBtoBの市場間物流を使う
  • ラストワンマイルを配送してくれるヤマト配送を使う
  • その両方を使う

のか、購入するユーザの種類と、商品(発送地)の組み合わせで色々な分岐があります。 ※複雑なドメインを実装に落とし込む話については水産業ドメイン可視化と実装のコツ〜釣って捌いて食べてみる〜 - Speaker Deck が面白いのでぜひご覧ください!

speakerdeck.com

こういった複雑性を内包するロジックはなるべくカプセル化し外から扱いやすくする工夫を随時していっています。 これはどの言語を扱っても当然行うべきことだと思いますが、プロダクトや事業のフェーズに合わせて、エンジニアが柔軟にロジックの形をアップデートしていきやすい言語だなと思っていて、個人的に好きなとてもポイントです。

Rubyの外観はシンプルです。けれど、内側はとても複雑なのです。 それはちょうど私たちの身体と同じようなものです - https://www.ruby-lang.org/ja/about/ より

実際、上で挙げた例の出荷方法の決定方法についても、最初は1つの方法しかなく特に意識せず、それが複数になってきたタイミングで課題が出てきて、モジュールとして切り出そうという流れで開発されました。その裏側にあるビジネスロジックを詳しく知らないエンジニアでも扱いやすくなるようなっていて、こういう動きは現在進行形で随所で行われています。

最後に

今回は、Ruby biz 2023の受賞に寄せて、ウーオでのRuby+周辺技術の活用について簡単にご紹介しました。引き続き、ウーオでは水産業の新しいインフラをつくっていくべく、どんどん価値あるサービスを開発していきます。

RubyRails を使ってサービス開発したい方はもちろん、Ruby 未経験でも水産業の課題解決に興味があるエンジニアの方もぜひご応募、ご連絡お待ちしております!

*1:今回、上述したRails等を含むフレームワークやHeroku等を総称して周辺技術としています

*2:当然初期のフェーズでインフラエンジニアを採用していく余裕もなかったのもあります

Next.js13 x AppRouter でFlutterアプリのWeb版を1週間で立ち上げした話

はじめに

こんにちはウーオでエンジニア兼PdMをしているt3qyoです。
7月に、モバイルアプリ(Flutter)でしか公開されていなかったUUUOのWeb版を約1週間の開発合宿を経て立ち上げしました!

合宿中に食べたお好み焼

以下のページのリンク先になります。 app.uuuo.jp

今まではモバイルアプリだけの公開でしたが、より広いお客様に産直鮮魚アプリのUUUOの商品を知ってもらいたく、Web版を公開することになりました。

なぜNext.jsを採用したのか

モバイルアプリでも採用しているFlutterで利用可能なFlutter Webと比較して考えました。
すでに、出品者側のアプリはFluttter Webで実装しており、Flutter Webもかなり有力な候補でした。
Flutter Webの立ち上げについては以前の記事で紹介しております。

tech-uuuo.hatenablog.jp

この記事にもある通り現状のFlutter Webでは、コードが流用できるという工数面でのメリットはかなり大きいのですが、 デフォルトでブラウザ検索がサポートされていない、レンダリングが重い等の問題を感じていました。

また、Flutter Webは基本SPA(Single Page Application)であるため、SSR(Server Side Rendering)でHTMLを構成するよりはそこまでSEOが期待できないと考えました。
今回は、より多くの購入者の方に使ってもらうために、SEOと性能面を強化したいと思い、
Web特化のフレームワークで、SSRにも力をいれているNext.jsを採用しました。

比較対象として、Vue.js&Nuxt.jsについても検討してみましたが、
社内ではReactの経験者が多いということと、ChatGPTにも聞きながら、(あとは直感と趣味嗜好で)
Next.jsで行こうとなりました。

ちなみに社内にWebフロントエンドエンジニアはいなかったので、Flutter Webを採用するよりはかなりリスクが高く、
なかなか挑戦的な決断だったなあと思います(遠い目)
この決断にも社内のエンジニアメンバーは嫌な顔ひとつせず賛同してくれました。(涙)

インフラ

インフラはGCPのCloudRunを採用しました。(Terraformで構築して、GitHub Actionsでデプロイ)
これについてもまた記事を書ければと思います。

Next.js13 x AppRouter の壁

Next.jsでの開発を決め、インフラも整い、さぁ開発だ!とチュートリアルなどを読み漁り、簡単なデモページなどを作っていったのですが、
Next.js13から採用されたAppRouterを採用するのかどうか、というところで大きな壁が待ち受けていました。

5月ぐらいに参考実装した段階ではまだAppRouterもNext.js13も使っておらず、従来のPageRouterでの参考実装となっていたのですが、

nextjs.org

nextjs.org

7月に開発を始めようとなった段階ではAppRouterは安定版となっており、
参考情報もちらほら出始めていました。
create-next-appでも recommended と表示されるのもあり、 これは、後で変更するのもなかなか大変そうなので今の段階でAppRouterを採用するのが良いのでは?
ということで、Next.js13 x AppRouterの構成で行くことに決めました。

npx create-next-appでApp Routerがデフォルトに

nextjs.org

AppRouterを採用して詰まったところと回避策

AppRouterを採用し、PageRouterからの参考実装の移し替えを始めましたが、多々問題があることに気づきました。

(当然ですが) AppRouterに対応していないライブラリが多かった

2023/10時点では、MUIがAppRouterに対応し、対処方法が公開されていましたのでこちらを参照ください。

mui.com

大体の問題はこれにつきるかなと思います。 UIフレームワークとしてMUIを採用しましたが、

github.com

MUIはCSR(Client Side Rendering)のページでしか使うことができず、 SSRしたいページでは以下のエラーが出てそのままでは使うことができませんでした。

TypeError: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component

そのため、SSRが必要なページでは、以下のように、use client を記載したコンポーネントを独自で用意して、そこを経由して読み込む というような回避策をとりました。

components/common/Material.tsx

"use client";

export {
  Box,
  Button,
  ButtonBase,
  Divider,
  Grid,
  ...
} from "@mui/material";

export {Mail, TextsmsOutlined, ArrowForwardIos} from "@mui/icons-material";

getServerSidePropsが使えない

AppRouterでは getServerSideProps は deprecatedとなっており、 特にそれを使わなくても SSRの場合は、async/awaitでのfetch処理をコンポーネント内にそのまま記述すれば良いとなっています。

PageRouterの場合は、特に意識せず、getServerSideProps を使えば SSRだろうがCSRだろうがNextのサーバーサイドと通信できて欲しい値がとれていた?と思うのですが、 AppRouterの場合は、「基本的にはSSRで、末端にCSRを使う」という思想のため、 認証方式や、APIをfetchする方式がSSRしたい画面と、CSRを使わざるを得ない画面で異なり、また、こちらもライブラリによってはCSRにしか対応していないものがあり、 getServerSideProps が使えたらなぁという箇所がいくつかありました。

これについては、特に初期表示にCSRさせる必要のない画面では、Server Componentsを利用してAPI fetchし、Client Components内では Tanstack Queryの useQuery を使う方式でいきました。

nextjs.org

SSRのローディングはどうする?

SSRではまず初めにAPI fetchを行うため、「CSRのように、部分的なレンダリングができず、fetchの間、画面が真っ白になってしまう」という問題が起きました。 ただこれについては単純に、「ServerComponentsの描画時のローディングには <Suspense> を使うと良い」というのが公式にも書いてあるので、 それを参考にすれば特に問題なく、実装できました。

nextjs.org

AppRouterを採用して良かったこと

苦戦したAppRouter採用でしたが、
基本的に画面の情報取得のAPIのfetchをする際にはSSRで実装していくのが、不要なjsのロードを少なくし画面をより軽量にできるのでパフォーマンス的にも良いのかなと思いました。 PageRouterでも意識すればできるのかもしれませんが、AppRouterでは、getServerSideProps が使えないなど、基本的にはServer Componentを使って、 Server SideでのAPI fetchを行うということが推奨されているので、 そのあたりでパフォーマンス + SEOの恩恵を受けられるのは良いと思っています。


Client Componentsには use client を使う方式になっていますが、その点もこのコード上でSSRCSRがわかりやすいのも 従来よりはいいのかなと思っています。

短期開発合宿というスタイルをしてみて

開発合宿の様子

弊社は東京 or 広島 or リモートの各拠点があり、普段開発メンバーはリモートで開発していますが、 今回は、広島に集まって同期コミュニケーションをとりながら開発しました。

他部署からの刺激 & 同期コミュニケーション

普段の落ち着いた環境の中でのリモート開発も良いですが
広島ではセールスメンバーやコーポレートメンバーの平常業務に囲まれており、
間近でフィードバックをもらえたり、魚の売買の臨場感も感じられるので、開発にも精が出る部分があります。

「合宿の振り返りでは普段よりコミュニケーションが取りやすく、スピード感があった」
という声も多く上がりました。
また、普段であれば合間にMTGなどが挟まってきますが、合宿期間中は、定例MTGなどは一切いれないよう調整したのも集中が途切れず、よかったです。

Figjamを使って振り返り

(👆にもありますが、フロントエンド経験のない私たちに最近話題のChatGptが大活躍でした)

差し入れが嬉しい!

リモートからでもスタバが贈れる時代、素敵です🎉

合宿は計画的に

1週間という期間制約を持たせるのは良いことですが、
1週間では、立ち上げまではできても、本番リリースまでは今考えるとどう考えても不可能でした。
どこまでの成果物を作り上げるのか、最初に決めるのは難しくても、もしくは期間中にでも見直してゴールを明確にしていくのが大切だと感じました。

終わりに、今後

今回は、全国の産直鮮魚仕入れプラットフォームであるUUUOアプリのWeb版を作りましたが、 より広い水産事業者に使っていただけるよう、 水産業内の受発注をより簡単に行える atohamaアプリのWeb版もUUUOのマルチテナントとして作っていく予定です!

atohama.uuuo.co.jp

ウーオでは水産流通を革新するため、プロダクトを通じてあらゆるアプローチをしています。ウーオの事業やプロダクト開発にご興味がある方は、以下をぜひご覧ください 👇

uuuo.co.jp

UUUOではモバイルアプリだけでなく、今後はWeb frontendも強化していきたいので、 今回のように開発合宿でしのぎを削りたい方はぜひともご応募お待ちしております!

👇👇👇👇👇 フロントエンドエンジニアの応募はこちら! 👇👇👇👇👇
<業務委託スタート可>ソフトウェアエンジニア(Frontend/Flutter on the Web) / 株式会社ウーオ

では。