この記事は Calendar for Akerun | Advent Calendar 2022 - Qiita の 16 日目の記事です。
どうも、 daikw - Qiita です。
たまに社内勉強会を思いついたように企画していまして、企画したフォーマットの一つが少し気に入っています。それを紹介したいと思います。
前提・課題意識・活動
Photosynth 社では、 Akerun 実機の開発で利用する物理的なツールを一般に「治具」と呼んでいます。治具の中でも、シングルボードコンピュータ (Raspi) とディスプレイが搭載されたものが最も多く使われています。Raspi 治具と呼びます。
Raspi 治具は、施工対象と利用者に対するインターフェースをそれぞれ備えた、普通の Linux サーバと考えることができます。最近のゲームやコンテンツ系サービスのようにアクセスが多いわけでもないので、一見普通の web サーバより簡単そうに見えますね。
ただ、メンテナンスにはかなり横断的な知識を要求されます。実機との通信のための比較的低レイヤの仕込みや、web バックエンド・フロントエンドの知識が必要です。特に Web アプリケーションフレームワークの Next.js を採用したことで、FW 開発グループで扱うには少々ハードルが高い状態でした。
そこで、それなりにちゃんとした勉強会を企画し、属人化の回避とチーム全体のスキル向上を狙いました。
シープディップトレーニングと勉強会の工夫
学びとは、「人に対して」行われることではない。「人が」行うことである
羊の毛についた寄生虫を落とす目的で、滅菌用の薬品に漬けることをシープディッピングと呼ぶそうです *2。
このシープディッピングに似たような、情報を浴びせるようなトレーニングをシープディップトレーニングと言います。一般には詰め込み教育とか言ったりするでしょうか。
この言葉は英語でも日本語でもあまり流行っていないようなのですが、「学び」の本質を突いているように思います。例えば、もくもく会はシープディップトレーニングとは対局にあって、参加者全員が自主的です。「学ばせる」のは間違いで、自ずから「学ぶ」のが正しいわけです。
僕はシープディップな「勉強会」や「授業」を憎んでおり、全てなくなれば良いと思っていまして、今回開催した勉強会も僕のアレルギーが出ない内容にするために工夫をいくつか入れました。
- 参加者のモチベーションに合わせた複数のコースを用意し、完了目安時間を設ける
- 全てのコースに「座学」と「ハンズオン」を用意する
- LT の時間を作り、その日に完全に理解したことを発表してもらう
参考実装
web アプリケーションを要件から作ってみるトレーニングの一環として、実際に利用されている治具のソースコード 以外の 参考実装を一つ作りました。
https://github.com/daikw/file-uploader-nextjs
参考実装を使った「学び」の方法を、後述のフォーマットに含まれる内容から抜粋して示します。Progate などのように手順通りに作っていくタイプの勉強サイトだとフィードバックを得にくいようなタイプの「学び」だと思ったので目玉コンテンツのつもりでしたが、ほとんど誰もここまで辿り着けませんでした。 もし次回があれば、ボリュームに気を使おうと思います。
## Next.js を使ってアプリを作ってみる: OPTIONAL
- 正直どんなアプリでも良いが、何か目標があるとわかりやすい。
- 簡単なファイルアップローダーを作ってみる過程で、web 開発の一部を体感する
- セキュリティは一旦気にしないが、[セキュア・バイ・デザイン輪読会で勉強](https://akerun.hateblo.jp/entry/2022/12/06/000506)しましょう
### 取り組み方
1. まず後述の要件通りに作ろうとしてみる
1. 参考実装 (https://github.com/daikw/file-uploader-nextjs) を読んでみる
1. 参考実装か、自分で作ったものに対して改善を加えてみる
### 要件
- 機能要求
- 3 つのページ・2 つの HTTP-API からなる web アプリケーション
- ページ数・API 数は守らなくても良い
- ファイルを保管し、ファイル名か何かをキーとしてダウンロードできる
- 保管方法は任意・適当でいい・メモリ上でも最悪構わない
- 実装要件
- フロントエンド
- index ページ(静的なページ)
- 他のページへのリンクを含む
- 動的なページ 1
- input 要素を 1 つ持つ(1 つはファイル入力・1 つはファイル名)
- 入力をバックエンドに POST できる
- 動的なページ 2
- input 要素を 1 つ持つ(ファイル名)
- GET で ファイルがダウンロードできる
- バックエンド
- `POST api/files`
- 受け取ったファイルを保存する
- `GET api/files`
- パラメータにあるファイル名に合致するファイルを返す、なければ 404 を返す
### 本来あるべきアーキテクチャを構想する: CHALLENGING
このアプリを作る前に、いろんな部分に ? がつく
- ファイルはどうやって保管されるべきか?
- ファイル名はキーとして妥当か?
- そもそもこんなもん作らなくても Google Drive あるやん??
- etc ...
何か特に気になる課題を見つけて、それがビジネス設計上・アーキテクチャ設計上どのように改善されるのか議論してみる
実施風景
参加者
3 つのコースを用意し、参加者に選んでもらいました。 🎋 ばっかりになるかと思いましたが意外とばらけました。
- 🌸 :cherry_blossom: 初級コース: 3 人
- 🎋 :tanabata_tree: 中級コース: 1 人
- 🎍 :bamboo: 上級コース: 2 人

実施中
毎日夕方に LT の時間があり、全員が「完全に理解した」と言っている和やかな時間が流れました。

結果
チームの実績解除を言語化し、情報共有・コラボレーションのベースラインを作りました。

勉強会のフォーマット
以下、社内固有の情報を除去し、再利用可能なフォーマットにしてみました。
毎年 4 月になると、非常に質の高いエンジニア新卒研修スライドが大量に公開されてすごいなと思います *3。
とてもいいなと思いますが、僕はスライドよりマークダウン派です。僕は文章のスタイリングを編集しやすい文字列以外のメタ情報に含めるな過激派、アンチ WYSIWYG 代表取締役(仮)なので、社内で共有するコンテンツもほとんどマークダウン形式のテキストです。よって勉強会フォーマットもマークダウン形式です。アトラシアンは早くマークダウン対応してください *4。
# 概要
## 契機
- 最近の治具アプリケーション では、Next.js を採用して実装しているため、メンテナには必須の知識である
- Next.js に限らず、 FW 開発者は web アプリケーションフレームワークに馴染みがない
## 目的
- 属人化回避
- 治具メンテナに属人化している知識を敷衍する
- スキル向上
- web アプリケーション開発に入門することで、web グループとのコミュニケーションを円滑にする
- 治具アプリケーションのメンテナンスができるようになる
## なぜ Next.js か?
チケットへのコメントより、
> 治具には、最低限のフロントエンドとバックエンドの共存、zero-config 性が(他のフロントエンドフレームワークよりも)ややイケてるので、 Next.js を使っています
面倒なビルドツール周りの問題に煩わされることなく、ほぼ全部入りの web アプリケーション開発をサクッと始められるところが良い by @daikw
参考: [Next.js を使うべき 5 つの理由 + 実装 Tips - Qiita](https://qiita.com/Yuki_Oshima/items/5c0dfd8f7af8fb76af8f)
# 勉強会のフォーマット
## 基本
- 常時オンラインであることを要求せず、 [もくもく会](https://web-camp.io/magazine/archives/89540) のような雰囲気
- カリキュラムは、オーガナイザーが提供する後述の自習コンテンツから選択する
- オーガナイザー( @daikw ) にいつでも質問して良いし、周りの人に質問するのも OK
## ざっくりカリキュラム
### 梅コース :cherry_blossom:
- Next.js の チュートリアルをゆっくりこなす
- 治具を手元で動かしてみる
- どれかの治具に変更を追加してみる
### 竹コース :tanabata_tree:
- Next.js の チュートリアルを爆速でこなす
- 治具を手元で動かしてみる
- お題のアプリを作る
- オプション課題( OPTIONAL と表記のあるもの)をこなす
### 松コース :bamboo:
- Next.js の チュートリアルを事前に終わらせてくる
- お題のアプリは作らない
- 自分が作りたい要件を持ち込む & 実装 & 発表
# 自習コンテンツ
## Next.js のチュートリアル
### 目安時間
- :cherry_blossom: : 6 ~ 8 時間程度
- :tanabata_tree: : 4 ~ 6 時間程度
- :bamboo: : 事前に完了済 / 3 時間程度
### やること
- [Introduction | Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) から開始して、順番に章をこなしていく。
- クリアすると、ポイントが貯まって楽しい
実施する必要のない章もある。 :cherry_blossom: の人は `REQUIRED` を、 それ以上の人は `OPTIONAL` まで含めてやると良い。 `SHOULD NOT` は、FW グループで勉強する意味はあまりない。
| chapter | title | level |
| -------------------------- | ------------------------------- | ---------- |
| FOUNDATIONS | \* | REQUIRED |
| CREATE YOUR FIRST APP | Create a Next.js App | REQUIRED |
| CREATE YOUR FIRST APP | Navigate Between Pages | OPTIONAL |
| CREATE YOUR FIRST APP | Assets, Metadata, and CSS | OPTIONAL |
| CREATE YOUR FIRST APP | Pre-rendering and Data Fetching | OPTIONAL |
| CREATE YOUR FIRST APP | Dynamic Routes | OPTIONAL |
| CREATE YOUR FIRST APP | API Routes | REQUIRED |
| CREATE YOUR FIRST APP | Deploying Your Next.js App | OPTIONAL |
| SEARCH ENGINE OPTIMIZATION | \* | SHOULD NOT |
| EXCEL | TypeScript | OPTIONAL |
## 治具を手元で動かしてみる
### 目安時間
- :cherry_blossom: : 6 ~ 8 時間程度
- :tanabata_tree: : 4 ~ 6 時間程度
- :bamboo: : 4 時間程度
### ドキュメント等
`dfu-jig` を動かす前に、以下ざっと目を通すと好ましい。特に `docs/techstack-explain.md#治具開発コマンド` はよく使うスニペットが書いてある。
- `README.md`
- `docs/techstack-explain.md`
### `dfu-jig` を Mac 上で動かす: REQUIRED
#### やること
- クローンしたレポジトリで `yarn install`, `yarn dev` を実行する
- 画面を表示する
- `http://localhost:3000` にアクセスする
- [DevTools を開いてみる](https://developer.chrome.com/docs/devtools/open/)
- API Routes を叩いてみる
- `curl http://localhost:3000/api/echo`: hello と返ってくるだけ
- `curl http://localhost:3000/api/test/mqtt`: mqtt メッセージが送信される。メッセージを別の方法でキャプチャしてみるとか
### `dfu-jig` を Raspi 上で動かす: OPTIONAL
#### 必要なもの
ポートフォワードでアプリケーションを手元に引き寄せるので、ディスプレイや周辺機器はなくても良い
- Raspi x1
- 16GB microSD x1
- 施工対象 x1
#### やること
- `dfu-jig/README.md#Recipe` にある内容を Raspi 実機に対して操作する
- Raspi のホスト名を変更しておく(他の人と衝突するため。必須ではない)
- `ssh pi@$target -L 8080:localhost:8080 -L 80:localhost:80 -L 3000:localhost:3000` でログインし、ポートフォワードしておく
- 手元の PC 上で治具アプリケーションにアクセスする
- 小細工なし -> `http://localhost`
- dev サーバ(`yarn dev` で起動)を実行中 -> `http://localhost:3000`
- ログを流してみる
- `journalctl -u dfu-jig.service -f`
- 起動した `dfu-jig` を使って、手近な製品の一つをアップデートしてみる
- 色々触ってみましょう
- API Route を叩く
- `curl htpp://localhost/api/dfu?device_id=A12XXXXX`: 治具バックエンドに、 `A12XXXXX` のアップデートを指示する
- `mosquitto_sub` を実行してみる(治具の `history` を見るとあるかも)
### どれかの治具に変更を加えてみる: REQUIRED
Mac 上で実行した治具アプリケーションに対して変更を加える。
dev サーバは `yarn dev` で起動できる。
起動中の治具に変更を加えて、動作を変える。
見た目をちょっと変えてみたり、レスポンスの内容を変えてみたりして動作を確認する。
変更推奨のファイル:
- フロントエンド: `dfu-jig/src/pages/index.tsx`
- バックエンド: `dfu-jig/src/pages/api/echo.ts`
## Next.js を使ってアプリを作ってみる: OPTIONAL
- 正直どんなアプリでも良いが、何か目標があるとわかりやすい。
- 簡単なファイルアップローダーを作ってみる過程で、web 開発の一部を体感する
- セキュリティは一旦気にしないが、[セキュア・バイ・デザイン輪読会で勉強](https://akerun.hateblo.jp/entry/2022/12/06/000506)しましょう
### 取り組み方
1. まず後述の要件通りに作ろうとしてみる
1. 参考実装 (https://github.com/daikw/file-uploader-nextjs) を読んでみる
1. 参考実装か、自分で作ったものに対して改善を加えてみる
### 要件
- 機能要求
- 3 つのページ・2 つの HTTP-API からなる web アプリケーション
- ページ数・API 数は守らなくても良い
- ファイルを保管し、ファイル名か何かをキーとしてダウンロードできる
- 保管方法は任意・適当でいい・メモリ上でも最悪構わない
- 実装要件
- フロントエンド
- index ページ(静的なページ)
- 他のページへのリンクを含む
- 動的なページ 1
- input 要素を 1 つ持つ(1 つはファイル入力・1 つはファイル名)
- 入力をバックエンドに POST できる
- 動的なページ 2
- input 要素を 1 つ持つ(ファイル名)
- GET で ファイルがダウンロードできる
- バックエンド
- `POST api/files`
- 受け取ったファイルを保存する
- `GET api/files`
- パラメータにあるファイル名に合致するファイルを返す、なければ 404 を返す
### 本来あるべきアーキテクチャを構想する: CHALLENGING
このアプリを作る前に、いろんな部分に ? がつく
- ファイルはどうやって保管されるべきか?
- ファイル名はキーとして妥当か?
- そもそもこんなもん作らなくても Google Drive あるやん??
- etc ...
何か特に気になる課題を見つけて、それがビジネス設計上・アーキテクチャ設計上どのように改善されるのか議論してみる
## 自分が作りたい要件を持ち込む & 実装 & 発表: CHALLENGING
比較的自由になんでもやっていいが、なるべく以下は守って実施する。
- 事前に、`Next.js のチュートリアル` を終わらせてくる
- 事前に、何か作りたいもののトピックを温めてくる
- アプリが動作しなくても、やりたかったことと解決法が発表ができる状態を目指す
- @daikw と相談するしないは自由
なお、発表に関するレギュレーションは当日相談して決める。想定は以下の通り。
- 10 min 発表, 10 min 質疑応答。発表にデモが含まれる
- スライド 10 枚以内
- 発表内容には制約なし
参考記事
株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co
Akerun Pro の購入はこちらから akerun.com
*1:https://scrapbox.io/kidaaam-92022284/%E3%82%B7%E3%83%BC%E3%83%97%E3%83%87%E3%82%A3%E3%83%83%E3%83%97%E3%83%BB%E3%83%88%E3%83%AC%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0
*2:https://www.oreilly.co.jp/books/9784873114033/ より、今でも羊飼いがやっているのかはわからない
*3:まとめられたりしている: https://gist.github.com/gcchaan/02f4746a323acac4095c30e0783a3912
*4:[JRACLOUD-72631] Provide users with a plain text markdown editor - Create and track feature requests for Atlassian products.