初Reactでも能力Amplifyしてスマートな(?)チーム分けアプリを作ってみる
突然ですが現withコロナ時代においてチーム分け時が必要な時はないでしょうか。
例えば最近増えましたリモート会議ですと一人しか同時に話せないのでzoomのブレイクアウトルーム使うなどチームを分割することは良くあるのかなと思ってます
(ちなみに自分の所属するチームでは毎朝、朝会でランダムに2、3人のチームを組んで開発しております。Be Full Stackです。)
普通のチームわけであればrandomに割り振ればいいかと思いますが、下記のような状況で困ることがありました
- なるべく均等に分けたいグループがある(たとえば下記)
- 研究室MTGで各学年が均等に分かれて欲しい
- 飲み会で1つのチームに各世代の人がいて欲しい
- マルチファンクショナルなスクラムチームを結成する時に各分野(インフラ、バックエンド、フロントエンド、デザイナー、QA)の人がそれぞれれのチームに入って欲しい)
- ランダムだと前回と同じ人と同じチームになってなかなか同じチームになれない人がいる
このようなことが何回かあって毎回手動で調整するのが面倒だなと思い、楽するために苦労するエンジニア精神でこの2つの問題を解消するwebアプリ作ってみました。
↓作ったもの
https://www.memo-team-gen.com/
↓クソースコード (拙いですが公開しました。aws-exports.js
などセキュリティ的にまずそうなのは除いております。)
https://github.com/LittleWat/memorizing-team-generator-public
普段の業務はモバイルアプリなのでiOSやAndroid,バックエンドをいじることはあってもフロントをいじることはほとんどなく、フロントエンドは 状態だったのですがこれを良い機会にということでググり力 で開発しました。
時代はjsよりtsということで、初めて typescript
を使ったので設定周りでつまづきまくりました。が、何とかバックもフロントも開発できバックもフロントもイケるts(js)の旨味を享受しました。typescript
初めてではありましたが、null安全で型推論が多少ありmapはじめコレクションの処理がサポートされていたりしてswift
, kotlin
と似ており個人的に書きやすかったです。
いろいろググると、React
, Vue
, Angular
がフロントエンド の三大レームワークとしてあり、Angular
は後方互換性を消しまくってて開発辛いみたいな記事を散見したので選択肢から外し、React
と Vue
で迷い 世界的にメジャーなのは React
ということで React
の学習から入りました。(のちのち Vue
のチュートリアルも行ったのですが、今回のようにRedux使わなくても良さそうな小さいアプリだったらVue
のほうが楽かもと感じました。)
では開発の流れや内容についてご紹介したいと思います。
開発の流れ
Reactの学習
適当にググって出るチュートリアルをやっているとReactは書き方がclass
のものとfunction
(Hooks
使うもの)のものの大きく二種類があるのを知り、Hooks
がナウいことをしったので何かまとまっている良さげな記事ないかなと調べておりますと下記の良記事に遭遇できました。
こちらで紹介されていた本(pdf)を買って勉強しました。
こちらの本、体系的にまとまっててお世話になりました
Boothのpdfの本ですが、紙の本は時代の流れについていけてない(hooks以前のものが多い)ので流行りすたり(競争)の激しいDeepLearing研究時代を彷彿とさせるものを感じました。
またUIのライブラリはbootstrapか何か使おうか迷っていましたが、material-ui がぱっと見充実しており、GoTのキャラが使われていたためmaterial-uiを使うことにしました。話それますが、GoTのキャラはDeepLearning研究でもこちらなどちらほら題材として使われていましたね。
開発
ナウい(お財布に優しい)構成で行きたいなと思い、firebaseは以前iOSアプリで一通り触ってみたので、今回は別のものがいいなということでawsのamplifyでサーバレスにいくことにしました。
フロントエンド
amplify hosting
で行いました。masterにpushするとデプロイされる仕組みも簡単に構築でき、ドメイン名の取得も簡単に行えました。amplify楽で良いですね。
バックエンド
amplify api
は GraphQL
と RestfulAPI
の二種類選べます。
ナウさを求める私はGraphQLで行おうと思い、下記のAWS公式のチュートリアルを行いました。
このチュートリアル、実装物も具体的で図解もあり、分かりやすく勉強になりました(おすすめです!!)
AppSync使えば簡単にElastic Seachと連携できるというのも知りました。強いですね。
がしかし、実際のチームわけのモデルをしたところ、お金のかかる(CapacityUnitの料金が倍になる)DynamoDBのGlobasSecondaryIndexが自動で貼られてしまったり、思ったように動かなかったので断念しました。(さらなるGraphQLの勉強の必要性を感じました。。)
仕方がないので、ここで方向転換して普通の RestfulAPI
でいくことにしました。
こちらもいろいろ選べたのですが、express
で開発することにしました。
フロントは create-react-app
でtypescirptが選べたのですが、express
はデフォルトが js
でバックエンドもどうせなら統一して ts
でいきたいなと思ったのですが、割と設定でハマったので後述してます。結論として何とかjsに変換してデプロイはできました。
(amplify、デフォルトを js
か ts
か選べるようになることを期待してます。(自分でコミットせぇという話かもですが汗))
DynamoDBのテーブル設計
Dynamo(NoSQL)なのでRDSではアンチパターンとされる配列を格納しても良いかと思い、配列を格納する設計にしました。
設計にはNoSQL Workbench という下記のようなツールを用いました。
このツール、dynamoのlocalやawsに簡単に設計したものを反映でき、テーブル定義のjsonも保存できて使いやすかったです^^
チームわけのアルゴリズム
random
か smart
か選べるようにしました。
スマートな
と言ってますが、実は100回ランダムにチーム生成してその中から スコア(frequency)が低いものを選ぶというシンプルな方法です。
スコア(frequency, freq.
)の計算ですが、これまでのチームわけの履歴を見て最近チームになった人がいればいるほど高いみたいな計算してます。
簡単に数式で示しますと
w_{ij} =
\begin{eqnarray}
\left\{
\begin{array}{l}
1 (member_i とmember_j が同じチームの時) \\
0 (member_i とmember_j が異なるチームの時)
\end{array}
\right.
\end{eqnarray} \\
N: 過去の何回分まで見るか(max10回分見るようにしてます) \\
M: メンバーの総数
と置くと下記のような計算をしてます。
freq. = \sum_{k=1}^N \sum_{i=1}^M \sum_{j=1}^M \frac{1}{k}w_{ij} \\
具体例で説明しますと下記のように均等に分けたいグループがあるときに
単純に直近10回で何回一緒のチームになったかが下記の隣接行列で、5回一緒になった人が数組ありますが、
下記の重み付けされた隣接行列で100(最大値を100にスケールしました)の組みは[麻生太郎、松本さん]ペアなので
次回は[麻生太郎、松本さん]が同じチームには絶対ならないだろうということでgenerationすると下記のようになり
たしかに[麻生太郎、松本さん]は同じチームにならず、いい感じでチーム分けできていることが伝わるかと思います。
ぜひ使っていただいて何かフィードバックいただけると幸いです。
Analytics
amplify add analytics
で一瞬でAmazon Pinpointが使えるようになります。簡単ですね。。
GoogleAnalyticsやFirebaseAnalyticsの置き換えになりそうでしょうか。
まとめ
- Amplifyは現在進行形で発展中(awsのUIもupdateされてますね。)
- 個人開発は全部自分でやらないといけないので良い勉強になる(慣れない技術を使うと苦労も多いですが発見が多く楽しい)
- 隣接行列の可視化のライブラリ探してて偶然見つけた
apexcharts
楽しい
将来的にやりたいこと
- ランダム生成はログイン不要にしたい
- 生成結果をslack通知
などありますがやるかは不明です。。
ハマったこと
いろいろあるのですが、誰かの参考になればと思い念のため残しておきます。
backendのfunctionを勝手にいじってうまくdeployできない
同じく困った人がいた模様
下記、私がミスしていたファイル構成(src
に ts
ファイルを置いた。)
➜ memoteamgenec8c5c26 git:(add-lambda-team-gen-api) ✗ tree . -L 2
.
├── amplify.state
├── dist
│ ├── app.js
│ ├── app.js.map
│ ├── config
│ ├── index.js
│ ├── index.js.map
│ ├── latest-build
│ ├── latest-build.zip
│ ├── models
│ ├── repository
│ ├── service
│ └── util
├── function-parameters.json
├── memoteamgenec8c5c26-cloudformation-template.json
├── package-lock.json
├── package.json
├── parameters.json
├── src
│ ├── app.ts
│ ├── config
│ ├── event.json
│ ├── index.ts
│ ├── models
│ ├── repository
│ ├── service
│ ├── swagger.yml
│ └── util
└── tsconfig.json
あるべき姿(デフォルトの姿): (src
に js
ファイル, package.json
を置く。)
➜ memorizing-team-generator git:(add-lambda-team-gen-api) ✗ tree amplify/backend/function/tmp
amplify/backend/function/tmp
├── amplify.state
├── function-parameters.json
├── parameters.json
├── src
│ ├── app.js
│ ├── event.json
│ ├── index.js
│ └── package.json
└── tmp-cloudformation-template.json
結局 src
の下に ts
ディレクトリを切って下記のようにtsconfig.jsonを編集すると動いたが、ディレクトリ構造が気持ち悪いことになりました...
何か良い方法ないのですかね
{
"compilerOptions": {
"outDir": ".",
"sourceMap": true,
"module": "commonjs",
"target": "es6",
"lib": ["es2017", "dom"],
"moduleResolution": "node",
"removeComments": true,
"allowJs": true,
"checkJs": true,
"allowSyntheticDefaultImports": true,
"baseUrl": "./ts",
"paths": {
"*": ["node_modules/*", "ts/types/*"]
}
},
"include": [
"ts/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
responsive designにできない
こちらは今もハマってます。ただのフロントエンドスキル不足故の問題です。。cssの勉強などします。。
Author And Source
この問題について(初Reactでも能力Amplifyしてスマートな(?)チーム分けアプリを作ってみる), 我々は、より多くの情報をここで見つけました https://qiita.com/LittleWat/items/e78800eb40bdd8a6475f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .