2020年8月1日をもって、PaykeからCBcloudに転職しました

2020年8月1日をもって、約3年半ほど在籍していましたPaykeから、CBcloud(シービークラウド)に転職しました。

琉球インタラクティブ→Payke→CBcloudとキャリアとしてはこれで3社目になります。

CBcloudとはどういう会社?

東京に本社を持つ、物流業界の課題解決を目指したスタートアップです。

サービスは、荷物を運んでほしい人と運んでくれる運送ドライバーをマッチングするプラットフォームである「PickGo」、宅配業者の業務を効率化するシステム「SmaRyu Post」、運送業者向けの業務支援システム「SmaRyu Truck」、運送ドライバーさんにアプリで買い物代行を依頼できる「PickGo 買い物代行」など様々なサービスを提供しています。

cb-cloud.com

なぜCBcloudに転職したの?

転職を決めた理由はいくつかありますが、大きな点は以下の3つになります。

  • CBcloudが沖縄支社を立ち上げた
  • 物流というニーズが大きくかつ課題も深い産業
  • 強そうな人たちがいっぱいいる

CBcloudが沖縄支社を立ち上げた

2020年4月1日に沖縄支社を設立しました。

https://cb-cloud.com/news/Xo3I-hUAAIP3C3gb

僕も妻も沖縄で生まれ育ち両親も沖縄もいるため、生活の拠点として子育てする上で一番沖縄がいいと考えています。 しかし僕はソフトウェアエンジニアとして「つよつよになりたい!」ですし、より変化と成長が早い環境が好きだと思っています。 なので、キャリアの選択として常に「沖縄がソフトウェアエンジニアにとって、そして変化や成長の早い環境が好きな人にとって最高の場所になることに貢献できるか?」を考えています。

CBcloudを通して物流というすべての人のためのインフラの大きな課題解決に貢献し、沖縄支社をその課題解決のための重要な拠点として成長させることに貢献できれば、結果的に「沖縄でソフトウェアエンジニアにとって、そして変化や成長の早い環境が好きな人にとって最高の場所」の一つを作れることができると考えました。

CBcloudは社長が沖縄出身であり、かつプログラミングもできるエンジニアでもあるので、面談の時にも「沖縄にいる優秀なエンジニアが東京に行かなくてもやりがいがある仕事ができるようにしたい」という話をしてくれて、沖縄に対する想いは同じようなモノを持っていると感じました。

物流というニーズが大きくかつ課題も深い産業

日本の物流というのは、社会のインフラであり、これからも非常に早いペースでニーズが増えているにも関わらず、深刻なドライバー不足という大きな課題を抱えています。

ドライバー不足の原因は、収入の不安定さや労働環境の過酷さなど多数あります。

CBcloudは「ドライバーファースト」の理念を掲げ、ドライバーと荷主をマッチングするプラットフォームによる「仕事の選びやすさ」や「仕事の安定的な供給」を提供、SmaRyu PostやSmaRyu Truckなどでドライバーの複雑な仕事を誰でも簡単に行えるようにするシステムを提供することで「効率化」や「ドライバー業務の参加しやすさ」を作り出し、ドライバーという仕事をより価値の高いものにしようとしていて、非常にやりがいのある仕事だと思いました。

また、最近の僕のエンジニアとしての理想像として「特定の業界への深い理解 x ソフトウェアエンジニアリングの高い技術力」というものをイメージしています。 業界への知識が浅くてよく、技術力だけ解決可能な課題というのはGAFAMが最終的には持っていける市場だと考えていますが、業界に深い知識を持ちかつ深く入り込んで地道にネットワーク作ることによってやっと解決できるような課題はGAFAMでもなかなか取れません。

その点CBcloudはANA Cargoが提供する空港間配送との連携をPickGoに取り入れることによって、ドライバーさんとのマッチングだけでは達成できなかった長距離配送の低価格と配送スピードを実現しており、見ていて「すごいかっこいいな!」と思いました。

僕自身もまずはソフトウェアエンジニアとしての価値を出しつつも、ゆくゆくは物流という業界への深い理解とネットワークを作って、技術だけでは解決できないような課題さえ解決できるようになりたいと考えたのも理由の一つです。

強そうな人がいっぱいいる

面談を通して出会った方々、そしてCBcloudに関わってそうな人をSNSなどで探して観察してみても、エンジニアもそうでない人も非常に優秀そうな方々ばかりでした。

自分の成長というのは周りにどんな人がいるか決まると思っているので、自分よりもはるかに優秀な人がいる、そしてそんな人たちが集まってくるような環境に常に身を置きたいと考えていて、その環境がCBcloudには確実にあると感じたのも決め手の一つです。

CBcloudでなにをやるの?

今の所、まずはサーバーサイドの開発とクラウドインフラの設計・改善・運用あたりをしていくことになるだろうと思っています。 PaykeではPHP + Azureでしたが、CBcloudではメインがRuby + AWSになりそうです。 Azureは好きなのでいま開発している個人プロダクトはAzureを使ってキャッチアップはそれを通して続けつつ、もしAzureの方が最適なユースケースがあればCBcloudでも採用できるようにしておきたいなーと個人的には思っています。

また沖縄支社の最初のエンジニアということもありますので、エンジニア組織を作るための採用活動なども積極的に行って行きたいと思います。 興味のある方がいらっしゃいましたらお気軽にお声がけください!

個人的な野望として、沖縄から日本、そして世界に使われるようなCBcloudの新たなプロダクトを生み出し育てたいとも思っているので、そのチャンスは常に探って行きたいと思っています。

さいごに

2020/08/06(木)に、CBcloudのオンラインミートアップがあります!

沖縄支社ではカスタマーサポートとエンジニアの採用を行っていますので、もし少しでも興味のある方は以下のWantedlyの記事からお気軽にご参加くださーい!

エンジニア向けはこちら

www.wantedly.com

カスタマーサポート向けはこちら

www.wantedly.com

Clojure/leiningenでユニットテストを実行する

leiningenを使っているプロジェクトで、ユニットテストを実行する方法について整理します。

ユニットテストを実行する

$ lein test

特定のnamespaceのユニットテストだけ実行する

$ lein test sample-app.core-test

テストをメタキーワードでグルーピングして、そのグループのテストだけを実行する

project.cljにtest-selectorsを追加する

 .
 .
 :test-selectors {:api :api
                  :model :model
                  :core :core)}
 .

テストコードにキーワードを指定する

 (ns ^:core sample-app.core-test
    (require [clojure.test :refer :all]
        [sample-app.core :refer :all]))
 
 (deftest ^:api a-test
    (testing "TEST A" 
        (is (= 1 (+ 1 1)))))
        
  (deftest ^:model b-test
    (testing "TEST B" 
        (is (= 1 (- 2 1)))))

キーワードを指定して lein testを実行する

# :modelメタキーワードが設定されたb-testだけ実行
$ lein test :model 
 
# :apiメタキーワードが設定されたa-testだけ実行
$ lein test :api
 
# :coreメタキーワードが設定されたsample-app.core-testに含まれるa-testとb-testが実行される
$ lein test :core

特定の関数だけテストする

$ lein test :only sample-app.core-test/a-test

フロントエンド開発における課題を問い直す〜2020年6月版〜

2020年6月21日(日)「チャリティカンファレンス沖縄2020 Vol.1 Frontend編」というイベントで、「フロントエンド開発における課題を問い直す」というタイトルで登壇させていただきました。

re-build.connpass.com

f:id:arakaji-yuu:20200625152514p:plain
フロントエンド開発における課題を問い直す

今回発表資料の準備をするにあたって、まず話したいことをテキストでひたすら書いていき、全て書ききったらそれをもとにパワポのスライドに情報を圧縮するというアプローチで作っていたのですが、せっかく書いたテキストをそのまま捨てるのはもったいないので多少加筆修正した上でこちらのブログにて公開することにしました。

このイベントに参加出来なかった人にも登壇内容が届いて、なにかの参考になれば幸いです。


フロントエンド開発における課題を問い直す〜2020年6月版〜

speakerdeck.com

なぜこのテーマを選んだか?

登壇すること自体は1ヶ月以上前から決まっていたのですが、登壇テーマがなかなか決まらずグズグズしていると当日のスケジュールが発表されました。 それを見てみると自分がトップバッターの一人になっていて、かつKey noteという立て付けになっているので、これはやばいぞと思いました笑

せっかくKey noteという立場をいただけたので、僕の方では特定の技術トピックについてお話するのではなく、現在のフロントエンド開発の全体像が見えるようなお話をして、それから他のセッションを聞いて深堀りをできるような形にしていきたいと思います。

では全体像をどういう視点で見ていくかという話なんですが、現在のフロントエンド開発は様々な技術が出てきており、それらはすべて開発における課題を解決するために生まれています。

僕もエンジニアとして技術を学ぶときに「この技術がおもしろそう!!→この技術はこの課題を解決するために生まれたのか〜」というテクノロジーファーストなきっかけで学ぶ事が多いのですが、本質的にはまず課題があり、その課題に対して技術でどう解決するかという、イシューファーストなアプローチを取るべきです。

そのため本セッションでは、まずフロントエンド開発における課題を改めて問い直して整理し、その課題に対していまどういう技術が解として存在するのかという話をしていきたいと思います。

課題の定義

ではフロントエンド開発における課題はこれです!という話をする前に、まず課題というのがどこから生まれるのかという話をさらっとしておきたいです。

国語辞典で「課題」と調べると以下のようにでます。

1 与える、または、与えられる題目や主題。
2 解決しなければならない問題。果たすべき仕事。

「解決しなければならない問題」というのはわかりやすい定義ですね。じゃあフロントエンド開発における解決しなければならない問題っていうのはなぜ解決しないといけないのか?

これを僕は、 「進みたい方向に進みたい速度で進みたいが、それが出来ない障害があるので、解決しないといけない」と考えています。

そう考えるとまず課題を知るにはそもそもの進みたい方向というのを知る必要があることがわかります。

フロントエンド開発の目的はユーザーにより良いUXを届けること

進みたい方向というのは、フロントエンド開発における目的になります。 フロントエンドというのは、システムとユーザーが接する部分のUIであり、その目的は良いUXを提供することになります。 じゃあ良いUXってなにか?という話になるんですが、UXの品質評価方法のひとつとして、UXハニカムという手法があります。

blog.btrax.com

これはプロダクトやサービスが提供するUXの評価軸を、useful、desirable、accessible、credible、findable、usableの6つの項目に分け、それぞれの項目を5段階評価をし、その総合点でUXを評価するという手法です。

各項目は以下の様に定義されています。

1. Useful – 役に立つ 提供されるプロダクトやサービスがユーザーの役に立っているか。彼らのニーズを満たしているか。もしそれがユーザーの目的を達成していなければ、ユーザー体験としてはレベルが低い。

2. Desirable – 好ましい プロダクトの見た目や雰囲気がユーザーにとって好ましいかどうか。ここに評価軸においては”デザイン要素”はなるべく少ない方が優れているとされる。

3. Accessible – アクセスしやすい 体の不自由な方や、異なる制限のあるユーザーにとっても使いやすい体験がデザインされているかどうか。色盲の方でも認識しやすいサインなどもその例の一つ。

4. Credible – 信頼できる 企業やプロダクトが信頼できるものであるかどうか。例えば無名な企業よりも、著名なブランドの製品であれば、最初からユーザーの心理的ハードルが下がり、自ずと利用体験がよくなりがち。

5. Findable – 探しやすい 情報やコンテンツが見つけやすい。短期間でユーザーが求める情報にたどり着ければ、利用している際のストレスが下がる。サイトであればページの構造、駅や公共の建物であれば、目的の場所に辿り着きやすいなど。

6. Usable – 使いやすい そしてユーザビリティの高さ。利用していて必要以上に複雑で使いにくい場合はユーザー体験の価値が下がってしまう。例えば家電製品であれば、説明書を読まなければ使い方がわからない時点で減点対象になるであろう。

つまり、UXを最大化させることがUI/フロントエンド開発における目的であるならば、これら6つを高めようとすると発生する課題がフロントエンド開発における課題となります。

では、やっと本題です。フロントエンド開発をすると発生する課題とはなんでしょうか?

正解がわからない

最も大きな課題の一つはUXの6つの指標を高めるためにどうすれば良いという正解が誰にもわからないことです。自分たちがリリースしたプロダクトが本当にユーザーの役に立つのか、使いやすいのか、ユーザーに好んでもらえるのかということは、実際にリリースして反応を見てみるまでわかりません。

マルチデバイスへの対応

ソフトウェアのUIは、10数年前まではPCでの利用のみを対象にしていればよかったのですが、現代ではPCだけでなく、スマートフォンタブレットの利用まで対象にしないといけません。そしてそれぞれのデバイスのOSの違いや、スペックの違い、利用シーンでのネットワーク環境の違いなど様々な状況を考慮に入れた開発をしていく必要があります。

ユーザーの期待値の増加

スマートフォンの普及によって、一般の人もアプリという形でソフトウェアを日常で使うことが普通なことになってきました。そしてみんなが使っているものといえば、instagramTiktokNetflixなど世界No1を取ったものばかりです。その世界トップレベルに洗練されたプロダクトを日常で使い目が肥えたユーザーに、それよりも劣るUXを提供してしまってはなかなか使ってもらう、使い続けてもらうに至るのは難しいでしょう。 つまりUXにおいては、資本力においてはるかに劣っていながらも、必然的に世界トップレベルのサービスの基準と戦うことが宿命付けられています。 またスマホアプリと接する時間が増えることで、スマホでWebアプリを使う時に関してもスマホアプリと同等のUXが求められるようになってきました。

正解がわからないという課題に立ち向かう手段

正解がわからないという課題に対して立ち向かうには基本的には「早く小さくリリースして、フィードバックを得て、そのフィードバックをもとにまた早く小さくリリースする」を繰り返すしかありません。これがいま良く言われているアジャイル開発で行われていることでもあります。 では、みんながアジャイル開発をしている時代においてチーム力、開発力として差がでるところは以下の点になります。

  • 単位時間あたりの試行回数を増やせるか?
  • データドリブンな意思決定を行う

単位時間あたりの試行回数を増やす

  • 限られた人数での開発効率を上げる
  • コード量が増えても開発効率を落とさないようにする
  • 人数が増えても開発効率を落とさないようにする

データドリブンな意思決定を行う

  • ユーザーの利用動向に関するデータ収集
  • データの可視化

では、上記を行うためにいまどのような技術がソリューションとして存在するのか?

Firebaseはフロントエンドエンジニアの必修項目のひとつ

「単位時間あたりの試行回数を増やす」、「データドリブンな意思決定を行う」のための手段を総合的に、かつ非常に低価格、そして簡単な方法で提供しているサービスは僕の知る限りFirebaseにおいてありません。

Firebaseのすべての機能を必ず使う必要はありませんが、Firebaseで何が出来て何ができないのかを把握して戦略を持って利用することができれば大きな武器になる、というよりもむしろ戦略を持って利用できないために不要なコストを書けて開発しなくてもよいものに開発リソースをかけてしまい競合に遅れを取るということにことになりかねません。

単位時間あたりの試行回数を増やすことにどう貢献するのか?

「単位時間あたりの試行回数を増やす」ために、限られた人数での開発効率をあげる、コード量が増えても開発効率を落とさない、人数が増えても開発効率を落とさない、という3つの点が重要です。

この3つの課題を同時に解消するための手段は、「自分たちで作らない部分を増やすこと」です。

Firebase AuthenticationというFirebaseが提供する認証サービスを例に考えてみましょう。

firebase.google.com

ユーザー認証の部分を自分たちでスクラッチで作らずにFirebase Authenticationを使うという戦略を取れば、その開発コストが大幅に減少し、その分他のアプリ固有の価値を生む機能や改善に開発リソースを使うことができ、それによって開発効率が向上します。

認証機能を自分たちで全て書くよりもFirebase Authenticationを使う方がコード量ははるかに小さくなるため、開発効率を落とさないで済むことができます。

人数が増えると仕様のキャッチアップをするためのコミュケーションコスト増加によって開発効率が落ちていくのですが、自前で作らずFirebase Authenticationを使う選択をしたことで仕様のキャッチアップはFirebase自体のドキュメントを読むだけで完了します。

もちろん外部サービスを利用する場合はそのサービスで出来ないことは出来ないこと、そしてそのサービスの提供が終了してしまうリスクなども考慮した上で利用を検討するべきですが、自前で作らずに既存のサービスを利用することで作らないモノを増やすことは開発効率を上げるための強力な手段になります。

Firebase Authenticationは認証というアプリ必要な単機能を提供してくれるものですが、もっと大胆に「作らない部分を増やす」ことに貢献するFirebaseのサービスがCloud Firestoreです。

Cloud Firestoreはクラウド上でホスティングされたNoSQLデータベースですが、iOSアプリ、Androidアプリ、WebのフロントエンドなどのクライアントからSDK経由で直接アクセスできるという特徴があります。

さらにリアルタイムアップデートという機能によって各デバイスから更新されたデータがリアルタイムで各デバイスに共有される機能、オフラインサポート、スケーラビリティの高さという特徴もかねそ兼ね備えています。

コレをうまく活用すれば、いままで単純なデータの読み書きだけのために行っていたサーバーサイドのAPI開発やデータ同期のためのプログラム、そしてスケーラビリティ確保のためのインフラ運用などの大部分を省く事が可能になります。

こちらも利用することによるトレードオフを見越した上で戦略を立てるべきですので、開発効率を上げるための自分の手札として何が出来て何ができないのかをしっかりとキャッチアップしておくべきでしょう。

データドリブンな意思決定を行うことにいかに貢献するのか?

開発効率をどれだけ高める事ができても、提供した機能がユーザーの体験価値をちゃんと高めたのか、またいま提供しているプロダクトのどこがユーザーの体験価値を毀損しているのかを把握することが出来なければ、正しい方向にプロダクトを改善していくことができません。

正しい方向にプロダクトを改善していくには、「ユーザーの利用動向をデータとして取得する」「取得したデータを可視化する」という2つが非常に重要です。

この点においてもFirebaseはGoogle Analyticsという強力なツールを提供しています。

firebase.google.com

Google AnalyticsSDKを入れるだけで、自分たちのアプリをどれくらいのユーザーが利用しているのか、どこで利用しているのか、どれくらいの時間利用しているのかなどがわかります。

より詳細なことが知りたい、たとえばどの画面を開いたのか、どのボタンを押したかなどを知りたければイベントを発火するコードを書くだけでクラウド上に記録されていきます。

そしてそれらのデータがGoogle Anaticsのダッシュボード上で可視化されるので、そのダッシュボード上で自分たちのアプリが正しく改善されているのかを客観的な事実であるデータで知る事ができます。

同じ事ができるツールは他にもありますがそれらは有償であることや、Firebaseの場合他にもパフォーマンス監視やクラッシュレポートに関する機能なども提供されかつ無料であることを考えても、デフォルトで取る選択肢としてFirebaseのGoogle Analyticsを利用することが多いでしょう。

「単位時間あたりの試行回数を増やす」、「データドリブンな意思決定をする」をするための強力な技術の一つとしてFirebaseがあるのは間違いないため、これからフロントエンド開発に関わる上でほぼ必須科目に近いぐらい身に付けないといけないモノだと考えています。

マルチデバイスへの対応という課題に立ち向かう手段

マルチデバイスへの対応というのはまず2つに分類することができます。

  • Webのフロントエンドをマルチデバイス対応をどうするのか
  • 各デバイスのネイティブアプリを提供をどうするのか

今回は「Webのフロントエンドをマルチデバイス対応すること」は、僕の理解だとどこもそこまで大きなインパクトのある差異はなくて「レスポンシブ対応していこうな」というところだと思っています。

各デバイスのネイティブアプリを提供するかどうかという点は、今回はわかりやすくするため以下の3つのプラットフォーム上に、それぞれ用のフロントエンド(モバイルの場合はネイティブアプリ)の提供をどのようにするのか?という風に考えます。

これは「それぞれのプラットフォーム上のアプリ同士でどのくらいコードを共有するのか?」を考えることです。

単純に考えると、すべてのデバイスにそれぞれのプラットフォーム用のプログラミング言語(AndroidJavaiOSをSwift、WebをJS)でフロントエンドを書くことにした場合、すべてのプラットフォーム用に共通コードを使うよりも開発リソースが必要になります。

しかし、コードをすべて共通化した場合には各プラットフォーム固有の処理を書かなければならない場合にはコードを分離して書かなければならないためコードの複雑性は高くなる傾向があります。またプラットフォーム間のコード共通化を支援しているフレームワークが、各プラットフォームのアップデートにどれだけついていけるのか?という課題もあります。

これらのトレードオフを見極めた上で技術選択をしていく必要がありますが、ではこの課題に向き合うための技術はなにがあるでしょうか?

Flutter、iOSAndroidのコード共通化の解のひとつ

FlutterはGoogleが提供しているiOSAndroidアプリをDartという言語で、共通のプログラムで書く事ができる技術の一つです。

flutter.dev

ただし共通化できるのはあくまでUIとビジネスロジックなどプラットフォームに依存しないコードの部分であり、カメラなどの機能はプラットフォーム固有のコードをプラグインという形で書く必要があります。ただ良く使う機能のほとんどはOSSプラグインが提供されているので凝ったことをしないのであればそれをインストールして使うことで解決するでしょう。

今回のカンファレンスでは登壇者がいませんが、iOSAndroidでコードを共通化するというアプローチを取っている技術はFlutter以外にもあります。

・Xamarin ・React Native ・ionic(cordova)

Xamarin

XamarinはMicrosoftが提供するフレームワークで、C#という言語を使ってiOSAndroidアプリを開発することができます。先日公開されたCOVID-19の接触確認アプリも、実はXamarinで作られています。もしインストールしていない方がいればぜひインストールしてみてください。

docs.microsoft.com

XamarinとFlutterの違いとして特徴的なのが、Flutterは「UIとロジックの共通化が目的」なのに対して、Xamarinは「ロジックの共通化が目的、だけどUIも共通化をしたければできる」という違いです。

Xamarinは、AnroidやiOSの各プラットフォーム固有のAPIC#APIで1対1のマッピングを行っているので、C#から直接プラットフォーム固有の機能を使うことができます。 Xamarin.Formというライブラリを使うとiOSAndroidで共通コードを使ってUIを作ることもできますが、全く別々のコードを使いつつロジックだけ共通化するというアプローチも取れます。

React Native

こちらはReact.jsというWeb用のViewライブラリをiOSAndroidでも同じ思想で使えるようにしたものです。こちらはJSを使ってiOSAndroidのUIとロジックを共通化して作ることができます。

reactnative.dev

JSでUIを書くにも関わらず実際に実行されているのはネイティブのUIコンポーネントなので、ネイティブアプリ水準のパフォーマンスが期待できます。

FlutterやXamarinとの違いは、すでにウェブのフロントエンドを作るのと同じReact.jsとJavaScriptをネイティブアプリの開発利用できるようにすることで、Webのフロントエンド開発者を、学習コストを減らした形でモバイルのネイティブアプリの開発者として転用可能にしている点です。

ionic(cordova)

ionicはFlutter、Xamarin、React Nativeと違い、JS/HTML/CSSというWebのフロントエンド技術を使ってアプリを作り、それをモバイルアプリのWebView上で動かすというアプローチを取っています。

ionicframework.com

これはiOSAndroidでコードを共通化するのはもちろんのこと、Webフロントエンドともコードを共通化することが技術的には可能になります。(Webと共通化する場合ネイティブの機能を提供するPluginをどううまく扱うか、またWebとモバイルアプリで製品のライフサイクルが違うなどの課題はある)

そのトレードオフとして、パフォーマンスやUXの面でネイティブアプリ同等のものを提供する難易度が高い、プラットフォーム固有の機能を使う場合はpluginという形で別でコードを書かなければならないなどの課題も出てきます。

このようにAndroidiOSのコードを共通化してマルチデバイス対応を開発効率を上げながら行うための技術はいくつかあります。 各ツールのメリットデメリットを理解しつつ、共通化するのか別々に作るのか、また共通化するならどの部分を共通化するためにどのツールを使うのかを考えて選択していく必要があります。

ネイティブアプリを使わずにWebアプリをモバイルアプリのように提供する方法としてのPWA

FlutterやXamarinなどはあくまでAndroidiOSでコードを共有してモバイルアプリを開発・提供するための技術ですが、あくまでウェブアプリとは別のコードを書く必要があります。

そこに対して「ウェブアプリ自体をモバイルアプリのように動かせるようにしたらいいじゃないか」というアプローチを取っているのがPWA(Progressive Web App)の技術になります。

developer.mozilla.org

PWAとはReactやFlutterのような特定のフレームワーク、ライブラリのことではなく、ブラウザに搭載されている機能の組み合わせによってモバイルアプリと同等の機能を実現するためのデザインパターンのようなものです。

ここでいう「モバイルアプリ同等の機能」とは、以下になります。

  • インストール可能(ホーム画面にアイコン設置、そのアイコンをタップして起動できる)
  • ネットワーク非依存(ネットがなくてもローカルにデータ保存して動かすことができる)
  • 再エンゲージ可能(プッシュ通知など)

モバイルデバイスに大きく依存した機能(カメラやGPS、ARなど)が必要なアプリについてはPWAのアプローチは取れないですが、Webで提供している機能をモバイルでも提供したいだけの場合、PWAのアプローチを取ることでモバイルアプリの開発リソースを全く使わずに上記3つの要件を実現することが可能になります。

ユーザーの期待値の増加に立ち向かう手段として生まれたSPA

スマホネイティブアプリと同等のUXをWebのフロントエンドでも実現するために考え出されたのがSPA(Single Page Application)です。

皆さんご存知だと思いますが、SPAは1ページのHTMLをJSで動的に書きながら画面描画をする技術のことです。

いままでは画面遷移やユーザーのアクションのたびに画面を全部リロードしないといけなかったものを、必要なデータだけをサーバーと通信し画面描画はリロードせずに行えるようにすることでスマホアプリのようなUXを実現可能にしました。

SPAによってネイティブアプリとUXで戦える土台を手に入れましたが、それによってまた新たな多くの課題を生み出しました。それが以下になります。

  • JSでより多くを担当することによるプログラムの複雑性が増加
  • 初回表示パフォーマンス悪化とGoogleインデックスが遅い問題

プログラムの複雑性の増加

画面描画処理の複雑性とパフォーマンス改善

SPA以前は入力フォームのバリデーションや少しのAJaxやHTMLの動的変更程度だったJavaScriptの役割が、SPAによって非常に多くのことを担当せざる得なくなり、それによってコード量の増加、複雑性の増加が激しくなりました。

そのうち最も大きな比重を占めるのが、アプリケーションの現在の状態をもとに画面を正しく描画する、DOMを変更するというプログラムを書くことです。

この処理を、メンテナンスしやすく、簡単に、かつパフォーマンス高く解決しようと生まれたのがReact.jsであり、Vue.jsであり、Angular(js)になります。

不具合発生率を言語レベルで減らすための策としてのTypeScript

SPAにすることで画面描画処理の他にも非常に多くのロジックがプログラムに入ってきてコード量がふえてきます。コード量が増えてくると適切に設計されていなければ依存がどんどん増えていき、一つの変更によって想定外の場所に影響が及びバグが発生してしまう可能性も高くなります。

バグをリリース前に見つけるにはテストが必要ですが、手動テストでは時間が非常にかかってしまう上に漏れの可能性もあります。そのため本来的には自動テストを書くべきではあるのですが、UIに関するテストはテストプログラムを書く難易度が高い上にUIの変更頻度も多いため書いたプログラムが無駄になることも多々あります。

このトレードオフに関するリーズナブルな解としてTypeScriptが利用されるケースが増えています。

TypeScriptはJavaScriptにトランスパイルすることができる言語ですが、JavaScriptに型という言語仕様をつけているのが一番の特徴です。

関数や変数で受け取れる値の型を明示することで、間違った型の値が入った場合にはコンパイル時にエラーを検出してくれます。

これにより、値の形式(型)違いによるバグの発生を事前に防ぐ事ができる上に、不要になったコードの削除や簡単なプログラムの変更などをコンパイルが通ればある程度は動くという安心感を得られるようになりました。

もちろんテストを置き換えるものではありませんが、コードや開発に関わる人が増えていったときにも開発効率を下げないための手段としてTypeScriptはJavaScriptをそのまま使うよりは支持されているように思えます。

初回表示パフォーマンス悪化とGoogleインデックスが遅い問題

SPAによって、Webアプリを利用中のUX/パフォーマンスは以前と比べて大きく改善可能になりましたが、逆に初回表示時のサーバーからレスポンスを受け取ってから画面が描画されアプリを利用できるようになるまでのパフォーマンスの悪化が問題視されるようになりました。

SPA以前の場合はサーバー側でHTMLを描画しているため、そのレスポンスをブラウザが受け取って描画するまでの時間は微微たるものでした。

しかしSPAになるとサーバーからのレスポンスは早くても、そのレスポンスをブラウザが受け取って画面を描画するためにはまずJavaScriptをすべて読みこんで解釈し、それを実行し、それからAjaxで画面描画のためのデータを取得とし、最終的に画面が描画されるため初回表示時の待ち時間が明らかに悪化していました。

また、Newsなどのメディアサイトの場合Google検索からの流入が非常に多いため、Googleに正しくそして早くインデックスされることがビジネス上非常に重要なファクターになるのですが、GoogleクローラーはJSの解釈は行うためSPAで作ったサイトでもインデックス自体はされるものの、JSの解釈をしてインデックスをされるまでの時間が通常のサイトよりも遅くなる傾向があるため、この問題も解決する必要がありました。

初回表示パフォーマンス悪化とGoogleインデックス遅い問題を両方解決するためのアプローチとして生まれたのがSSR(サーバーサイドレンダリング)という技術です。

SSRとは、SPAの場合はクライアントサイドで描画していたHTMLを、初回表示の場合のみサーバー側で描画しつつ、クライアントでJSが実行された際には現在の状態をHTMLから読み取れるようにデータを埋め込んでおく手法です。

これにより初回表示の場合はJSの実行またずに画面描画されつつ次のユーザーのアクションからはSPAとしてJSで画面描画を行うことを可能にしました。 初回表示をサーバーサイドでHTML描画できるようにしたことで、GoogleクローラもJSの実行なしにコンテンツを読み取れ、早くインデックスされることを可能にしました。

しかしこのSSR、フロントエンド用に書いてあるJSをサーバーサイドのnodejsで実行できるようにしつつ状態の受け渡しをスムーズに行う必要があるため、0からコレを作るのは非常に手間のかかるものでした。

それをSPAでよく使われるViewライブラリ毎にフレームワークとして解決したのが、Vue.jsのNuxt.jsであり、React.jsのNext.jsです。ちなみにAngularの方もAngular UniveralというAngularに同梱されているライブラリでSSRの導入をできるようにしています。

さいごに

この7〜8年のフロントエンドに関わる技術の発展は凄まじく、いろんな技術が生まれては消えていきます。しかし、それらの技術はいずれも特定の課題に対する解決策として生まれています。

ただいま流行っている技術を追うだけでなく、そもそもいまフロントエンド開発に起こっているトップレベルの課題からブレイクダウンして課題を具体化し、それらの解決策としていま注目されている技術はどのようにマッピングされているのかを見ていくと、自分たちのプロダクトや組織にとって必要な技術がなんなのかが見えてくると思います。

この発表で、いまのフロントエンド開発のなんとなく全体像が見えてくる、かつ、課題から考えるということの重要性を理解することが出来たら良いなと思っています。

長々とお付き合いいただきありがとうございました。

D2Cの本質を考える

D2Cの本質を理解する

いま「D2C」というのがバズワード化しているが、それが意味するのはECサイトでメーカーが直接顧客に商品を売るというだけものではない。このドキュメントでは、D2Cとして表現されている企業が伝統的なメーカーよりも非常に早い成長を遂げた重要な成長ドライバーはなんなのか?そして既存のメーカーがD2Cから得られる知見を生かしどのような戦略を実施するべきなのかを考えてみる。

D2Cとは

まずD2Cという言葉の定義を揃えておく必要がある。D2Cとは、メーカーが消費者へ直接商品を販売することだけを意味する言葉ではない。

D2C 「世界観」と「テクノロジー」で勝つブランド戦略」によると、D2Cの辞書的な定義は以下になる。

新しい消費の価値観を持つミレニアル世代以下のターゲットに対し、ユニークな世界観を下敷きにしたプロダクトとカスタマーエクスペリエンス、SNSや店舗を通じた顧客とのダイレクトな対話、垂直統合したサプライチェーンを武器に、VCから資金調達を行い、短期間に急成長を目指すデジタル&データドリブンなライフスタイルブランド

つまりD2Cブランドは以下のような特徴を持っていることを意味する。

  • 顧客ターゲットがミレニアル世代
  • チャネルが直接販売、
  • コミュニケーションチャネルがSNSなどのデジタルを使った顧客との直接コミュニケーション
  • 成長速度が指数関数的な急成長
  • デジタル技術を駆使したデータドリブンな意思決定とオペレーションの改善
  • 商品の機能ではなく、世界観(ブランド)を通した総合的な体験価値を提供する

なぜいまD2Cが注目されているのか

Casperという2014年に登場したマットレスを販売するスタートアップが、急速に成長し伝統的なマットレスメーカーのシェアを奪っていく。創業初月に1億円、最初の12ヶ月で100億円、2年目には200億円に到達。2019年はじめには北米地域だけで200もの店舗を出すことに成功している。

Casper以外にもメガネ業界ではWarby Parker、スーツケースブランドのAwayなどが登場し、それらがインターネット企業のスタートアップのような急成長を行うことに成功し、ユニコーン企業(評価額が1000億円を超えるベンチャー企業)になったことから、これらの企業に共通する特徴をD2Cというワードにまとめて注目されることとなった。

なぜミレニアム世代をターゲットとするのか

ミレニアム世代とは

ミレニアム世代とは、アメリカにおいて1980年代から1990年代後半までに生まれ、2000年代に成人または社会人になる世代のことを言います。この世代の特徴として、デジタル・ネイティブ、物心ついたときからPCやスマホ、インターネットなどが身近にある環境で育っているという点が挙げられている。

人口割合の巨大さ

アメリカ国内のミレニアル世代の人口は約9000万人にのぼり、ベビーブーマー世代を抜いて米国最大の年齢層になっただけでなく労働力人口に占める割合も最大となっている。

ミレニアル世代の労働力にしめる比率は2019年時点で35%だが、2030年までに75%に達すると予想されいる。それだけでなく、ミレニアル世代は推定30兆ドルの資産をベビーブーマー世代の親から相続すると予想されている。 また教育水準が最も高い世代とされており、学士号以上の比率は同じ年齢でみるとみれミレニアル世代が40%前後に対してX世代が29%、ベビーブーマー世代は25%となっている。

つまり、人口規模や若さ、高い教育水準、さらに巨額な相続資産により今後長年米国経済を牽引する消費者層と考えられており、D2Cの急成長は伝統的な企業がいままで提供できていなかったミレニアル世代に対する価値提供をうまく実現することが大きな成長ドライバーとなるため、ミレニアル世代をターゲットとしている理由の一つになると考えられる。

EC経由での購買ハードルの低さ

D2CはECでの直接販売がメインの販売チャネルであるため、 その成長速度は対象となるユーザーがEC経由でその商品を購入することのハードルが低いことに大きく依存する。

ミレニアル世代はデジタルネイティブと呼ばれ、物心ついたころからPC、インターネット、スマホなどに触れながら育ってきた世代のため、それよりも上の世代よりもECでの購買ハードルが低い傾向にある。

このEC経由での購買ハードルの低さもミレニアル世代をターゲットしている理由の一つといえるだろう。

なぜ直接販売をするのか

  • 卸や小売店に取られる中間マージンをなくすことでき、その分より低価格で販売することができる。
  • デジタル経由で顧客に直接販売することで、様々なデータを取ることができ、そのデータによってプロダクト自体や各種オペレーションを最適に、かつ素早く改善していくことができる。

なぜSNSなど通じた顧客との直接コミュニケーションを重視するのか

  • 直接コミュニケーションすることにより、エンゲージメントを高める手段を得ることができる
  • エンゲージメントを高めることで、ユーザー自身がブランドや商品を拡散するという現象を起こすことができ、それにより伝統的なメーカーよりも低コストでユーザーを獲得することができる(仮設)

なぜ指数関数的な急成長を実現できるのか

  • アメリカの場合はミレニアル世代が相当な人口ボリュームがあるのでターゲットとして成功した場合大きくスケールする
  • 各種データを取りながら改善を回す事が可能なため、最適化もしやすい。成功した場合の将来の成長性も計算しやすいためVCからの投資を集めやすい。

なぜデータドリブンな意思決定とオペレーションの改善が実現できるのか

  • ユーザーとの接点がソフトウェア上になっているため、各種データを取りやすい
  • またデータを元にしたオペレーション改善もソフトウェアで対応しやすい

なぜ機能ではなく世界観を通じた体験価値の提供を重視するのか

  • ミレニアル世代の特徴として、モノではなくコトの方を大事にする価値観をもっているため

D2Cの本質

本質的に重要なのは、価値あるデータをあつめ、それを分析し、データドリブンで高速にオペレーションを改善すること。そしてデータや顧客との直接的な対話から、顧客の持つより本質的な課題を見つけ、それを解決するプロダクトを正しく提供する、プロダクト自身も改善していくこと。そしてそのサイクルを高速に回すことである。

より価値あるデータを集める、顧客の本質的な課題を見つけるために、ソフトウェア(SNS、EC)を通して直接顧客との接点を持つ。

ミレニアル世代をターゲットとするのは、あくまでデジタル経由のコミュニケーションや購買行動のハードルが低い、かつアメリカにおいては非常に大きな人口割合を占めているからである。

機能ではなく世界観を通じた体験価値を提供しているのは、ミレニアル世代をターゲットするために必要だからである。

D2Cから学んで既存メーカーが取り組むべき戦略はなにか

D2Cでの成功例をみて、いきなりSNSをやる、ECをやるというのは違う。

重要なのは価値あるデータを集めること、データドリブンで意思決定し、高速にオペレーションや商品開発を改善していくことにある。

つまり既存メーカーがまず取り組むべきは、いま持っているまたは得られるデータを集め、分析し、それをもとに意思決定し、改善するというサイクルを回すこと。そのための土台を整えることである。

その土台をもとに既存事業のオペレーションや商品改善サイクルを回していき、成功体験を作ること。

その後、ミレニアル世代を中心とした顧客層と直接つながるための販売チャネル、コミュニケーションチャネルを確立し、そこで得たデータや顧客の課題をもとに新たな商品を作っていくという順番が正しいだろう。

参考

2019/11/17(日) JAZUG沖縄のミートアップを開催いたしました!

2019/11/17(日) JAZUG沖縄のミートアップを開催いたしました!

jazug-okinawa.connpass.com

自分はPaykeに転職してからずっとAzureを使っていて来ていて、大体1年1回ほどはAzureに関連する勉強回を開催していたのですが、継続的に沖縄でAzureのユーザーが集まれる回を作っていきたいと思い、この度JAZUG( Japan AZure User Group) 沖縄としてミートアップを開催することとなりました。

今回JAUG沖縄のミートアップを開催するということで、非常に多くの方に応援のコメントもいただいたり、一緒にコミュニティを運営していきたいという方が出てきてくれたり、実際にMicrosoftの横井さんにリモートでセッションをしていただいたりと、様々な方にご協力頂きました。

圧倒的感謝!!でございます。

今回イベント内容について

最初のセッションとして、横井さんに「AI 使って、何しよう? ~ あなたの挑戦が、未来を実現する: Microsoft の AI の世界 ~ 」というテーマでMicrosoftが提供しているAI系サービスの特徴やそれを利用していくための勘所などを紹介して頂きました。

1,2年前ほどに勉強回でAzureのAI系サービスについて話を聞いたことがあったのですが、そこから精度が向上していたり、サービスのラインナップ自体も増えていたりと、この分野は継続的にキャッチアップしてプロダクトにどのように活かしせるか常に考えておくと非常に面白いなと思いました。(個人的にはTranslate系をもっとキャッチアップしておきたい。。。)

次に僕が「Azure Web Appはいいぞ!」というタイトルでAzure Web AppというAzureのPaaSの良さを発表させて頂きました。

EBILABという飲食店をデータ駆動で経営改善を支援するBIツールを提供する会社の開発チームから、3人が登壇して頂きました。

@r_nakamineさんが「様々なデータの統合を支えるETL基盤をAzure Serverless コンポーネントで構築」、@puremoru0315さんが「Azure ServerlessでWeb Application開発」、@saboyutakaさんが「10x Serverless Product Development for a Startup with Microsoft Azure」というタイトルでそれぞれ発表していただき、EBILABさんの開発の中の構成がすべて見えてくるとても充実した内容でした。

EBILABさんの技術選定やアーキテクチャ構成などは一貫して「分業可能にすることで生産性を上げる」というコンセプトが通っていて、その分業可能なアーキテクチャを作る上でAzureの様々なマネージドサービスやServerlessテクノロジーを駆使することで本来大規模開発になるところを少人数でも開発可能にしているようでした。

アーキテクチャ選定の思想や紹介してもらった様々なサービス群についてすぐにでも使える情報が多かったので、非常に勉強になりました。

皆さんの登壇が終わったあとは、Microsoft Learnを使って実際にAzure Functionsを触ってみようということで@saboyutakaさんにリードしてもらってMicrosoft Learnを体験してみました。

docs.microsoft.com

今後について

JAZUG沖縄はできるだけ継続的にミートアップを開催して、みんなでMicrosoft Learnを使ったもくもく会を開催したり、県外からのゲストを招いて様々な事例やAzureの最新動向をキャッチアップできる会を作ったりしていきたいと思いますので、今後ともよろしくお願いします。

やっていくぞ!!!

PHPカンファレンス沖縄2019に、個人としては運営スタッフ&登壇者、Paykeはスポンサーとして参加しました!

PHPカンファレンス沖縄2019に運営スタッフ & 登壇者、僕が所属する会社であるPaykeはスポンサーとして参加しました!

phpcon.okinawa.jp

総勢140名近くの方が参加していただく規模のカンファレンスになり、沖縄だとハッカーズチャンプルーに次ぐ規模のカンファレンスになりました。

ハッカーズチャンプルーは沖縄の各エンジニアコミュニティが協力して開催しているコミュニティですが、一つのPHPというコミュニティだけでこの規模のカンファレンスができ、しかも多くの県外から参加者も来ていただけたのはすごく良い事例になったと思いますし、参加者としても非常に楽しめたカンファレンスになったと思います!

スポンサーとして

今回始めての沖縄で開催させるPHPカンファレンスということで、少しばかりの応援としてPaykeもスポンサーさせていただきました。

f:id:arakaji-yuu:20191014145119j:plain

f:id:arakaji-yuu:20191014145146j:plain

このようなカンファレンスで僕らのロゴが掲載されて、全国から来ていただいたPHPerの方々に少しでも認知していただけたなら嬉しい限りです。

弊社CTOの花城はゲストスピーカーとして、「スタートアップにおけるプロダクト開発とエンジニア組織の変遷」と言う内容で登壇しました。 沖縄でPaykeぐらいのスピード感で成長するスタートアップ企業はこれまでなかったので、その成長を遂げたエンジニア組織がどのように変化してきたのかという話は多くの方に興味を持っていただけたようで身内として非常に嬉しい限りです。

あと弊社CTOの登壇に関する反響として一番多かったのは「CTOイケメンですね!」でした笑(うらやましい。。。

登壇者として

今回ボクは「技術基盤/SREの視点で取り組む、サービスの成長を継続し、加速させるためのPHPアプリケーション改善」というタイトルで登壇させていただきました。

Paykeの開発組織の中で技術基盤という組織を作り、解決してきた課題の事例を通じてサービスの成長を継続させ、そして成長させていくためにどのようなことを考えながら意思決定しているかを伝えたいと思って今回の登壇内容を作りました。

30分枠頂いてたのですが時間オーバーしてしまい、最後のほうは一部省いてしまったのですが、一番伝えたかったのは以下のページに書いた「事業目標を理解し、ボトルネックを解消する」ということです。

技術基盤だからといってビジネスのことを考えなくて良いわけでは決してなく、むしろビジネスと事業の成長戦略、そして目標を理解し、その道の先にある技術的ボトルネックを見抜き予めかじめ取り除く、またはその戦略執行をより効率的・効果的に行えるような技術的な武器を整えておく、のようなことがPaykeの技術基盤には求められていて、これまでもそれを意識して意思決定を行ってきました。

この登壇を通して「ビジネスを理解して、それを支えかつ強化する技術的な意思決定をすることが重要」ということをうまく伝えたかったのですが、うまくいったのかはあんまり自信がない。。。

いろんな方に「新垣さんの発表が一番楽しみです!」と言って下さったので、期待に答えられただろうか・・・

人前で話す事自体には最近だいぶなれてきたんですが、うまく伝えられるようになったかというそうでもない気がするので、次からは「伝えたいことを正しく伝える」ということをもっと意識して登壇に望みたいと思います。

参加者として

今回は運営スタッフとしての役割上、ずっとtrack_aの会場にいました。 すべての登壇内容が面白く、かつ勉強になるものばかりで非常に楽しかったのですが、個人的なベストセッションを挙げさせていただくとランチセッションの「小さな機能、大きな仕事」が最高でした。

自分もリファクタリングするときやもしくは自分が新規開発するときの基本的な考え方として「小さくシンプルな役割をもったプログラムをまず作り、それを組み合わせることで大きな役割をするプログラムを作る」というのを意識して行っています。

それは「UNIXという考え方」という本で学んだことや、Clojureのような関数型言語でプログラムを作るときの作法から影響をうけてそうなっていたのですが、頭の中にぼんやりとあるだけでうまく言語化はできていませんでした。

今回のこのセッションでは実際にもう作られて負債化しているシステムの要因分析やそれに対する改善方法のアプローチとして僕が暗黙知的に意識していた「小さなプログラムを組み合わせて大きなプログラムを作る」ということがうまく言語化されていて、登壇中も「あー、そうそう!そういうことなんですよね!!!」とこころの中で首がもげるかというほど頷いてました。

フィーチャーとケイパビリティという言葉で「フィーチャー=ユーザーからみた機能(大きな仕事)」と「ケイパビリティ=フィーチャーを実現するための構成要素として必要な能力(小さな機能)」を明確に分けて話されていたのが印象的で、僕の辞書にはその言葉がこれまでなかったので非常に勉強になりました。

「登壇内容めっちゃ良かった!」と伝えるのと「ajito.fmのファンでめっちゃ聞いてます!」ということを直接伝えられなかったのが個人的には心残り。。。

スタッフとして

今回PHPカンファレンス沖縄は最初はスタッフとして関わる予定ではなかったのですが、実行委員長のカンボさんに直接誘っていただいたのがきっかけでコアスタッフとして途中参加させていただきました。

僕がやったことは以下のような感じです。

  • Paykeにスポンサーとして参加してもらう。
  • キーノートスピーカーとの調整
  • 当日のビデオ撮影(スタッフ用)
  • 後片付け

今回のイベントは他のコアメンバーがすごく頑張っていて「途中から参加したのにあんまり貢献できていないな~」とちょっと罪悪感的なことも頭の中には浮かんでいたのですが、こういうカンファレンスは小さなことでも自分ができることをやってくれる人達の集合で成り立っているので、ここは罪悪感を忘れて「自分も運営に貢献したぞ!」と自信を持って言いたいと思います。

おれも自分のできる範囲で運営がんばったぞー!!!

スペシャルサンクス

今回のイベントが無事開催できたのは、会場提供してくださった株式会社プロトソリューションさんの全面協力のおかげでした。

会場提供だけではなく、会場準備や後片付けにもスタッフを参加させてもらって協力してくれるだけでなく、当日の備品で足りないものが見つかったときに会社にある備品を貸し出してくださったりと非常に多くのサポートをしてくださったことで今回のカンファレンスを無事やり遂げる事ができたと思います。

株式会社プロトソリューションさん、本当にありがとうございました!!

会議終了後に必ず作成してもらうアクションサマリー(または議事録)

会議は意思決定のためにするもので、かつその意思決定を正しく素早く伝達するために、自分は会議終了後には基本的には必ずアクションサマリーを書いて共有するようにしている。

アクションサマリーとは、会議で話して決まった以下の内容を簡単にまとめたものです。

  • 何を目的に議論したのか
  • 結果どうなったのか
  • アクションリスト(誰が、いつまでに、なにをやるのか)

自分は必ずやるようにしているが、それを組織全体に適応するためにはどうすればいいかな〜と考えているときに 「マーケティングとは「組織革命」である。」という本を呼んでいたら、会議後に提供するアクションサマリーについて書いていた。

この本によると、アクションサマリーは以下の内容を描く必要があるそうです。

  1. その会議の目的がなんだったのか?
  2. そして結論はどうだったのか?
  3. 結論に至る議論された主な内容はなんだったのか?
  4. 結論に基づき、関係者が次に取るべきアクションの明示(誰が、なにを、いつまでにするのか? )

そしてこの内容を会議から24時間以内に全体に公開することが義務付けられれているそうです。

これにより、まず会議の関係者に正しい素早くアクションしてもらうためのシステムとして機能するとともに、情報や意思決定の透明性を上げることを組織に浸透させていくという2つの効果があるそうです。

これをもとに、僕の組織でも使えるように以下のようなアクションサマリーのテンプレートを作成しました。 情報共有ツールとしてesaというサービスを利用しているので、テンプレートもMarkdownで書いています

- 日時: 
- 参加者: 

# 会議の目的

# 結論

# 結論に至る議論された主な内容

# アクション(誰が、なにを、いつまにするのか?)

これでうまく回るか試してみます。