サークルの管理サイトを作った話
自分のバンドサークル向けのアプリを作りました。自己満足ですが、その変遷について話します。
バンド数集計アプリ
バンドサークルでは定期的に内輪のライブがあり、サークルメンバーは参加するバンド数によってライブの出演費が変わります。バンドはGoogle Formを用いて応募し、幹部が集計結果からサークル員の出演バンド数を集計するという運用を行なっていて、毎回めんどくさいという声がありました。そこで、Google App Script(GAS)を使って自動で集計できるアプリを作りました。
こだわりの箇所はアルゴリズムです。バンドにはギターボーカルが存在し、フォームではギターとボーカル両方にカウントされてしまいます。そのため、フォームの中の出現回数を調べるだけでは本人の出演バンド数と異なってしまうので、アルゴリズムを組んで重複がないようにしました。
for(var i=0;i<members_arr.length;i++){
members = members_arr[i];
counted_members = [];
for(var j=0;j<members.length;j++){
member = members[j];
if(counted_members.includes(member)){
}else{
counted_members.push(member);
var hasMember = member_and_count_list.some(value => (value.name === member));
if(hasMember){
member_index = member_and_count_list.findIndex(({name}) => name === member);
member_and_count_list[member_index]['count'] = member_and_count_list[member_index]['count']+1;
}else{
member_and_count_list.push({name:member,count:1});
}
}
}
}
しかし大きな問題点があります。Google Formで名前を記入する際に漢字ミスが多く、うまく集計ができないということがあります。一方バンドサークルのメンバーは50人を超えており、選択肢機能を使うとフォームがとても使いづらくなるという問題がありました。そのため、フォームから自作しようと、以下の管理サイトを作ることにしました。
管理サイト
技術スタック:Laravel mix, Vue.js, AWS EC2, RDS
バックエンドはLaravel, フロントエンドはVue.jsを使いました。このvue-selectというのがとても便利で、セレクトボックスなのですが検索をして選択肢を見つけることができます。このコンポーネントを使い、上記のフォームの問題を解決しました。
https://github.com/sagalbot/vue-select
そのほかにも、サークル員のみが作成可能な会員でログイン機能をつけ、サークル員のみ過去の動画や、プロフィール、ライブのセットリストなどを見れるようにしました。
これらのコンテンツはプロフィール編集や管理画面から内容を簡単に変更することが可能です。
サークルの非公式企画として自分が立ち上げたライブがあったのですが、自分の事業ということにしてしまい、stripeを用いてクレカ決済も導入しました。
このアプリで初めてAWSを触りました。元々研究室でラズパイとかで遊んでいたのですが、この機会に初めてクラウドに触りました。ここからインフラの世界にのめり込み今に至ります。この本を参考にしました!
管理サイト(サーバーレス編)
技術スタック:AWS lambda, lambda@edge, cloudfront, S3, DynamoDB, API gateway, Python, Node.js, pupeteer, Golang
自分も卒業の年になり、このアプリの運用のことを考えないといけなくなりました。まず、コスト面についてです。AWSのEC2とRDSはそこそこ高いです。EC2にmysqlも入れたとしても月1500円くらいかかります。
また、フレームワークはサポートしてくれるバージョンの入れ替わりが激しく、定期的にメンテナンスする必要があります。そこで、このサービスをサーバーレスにすることにしました。
データベースにDynamoDB、サーバーサイドにlambdaを使い、SPAをS3でホスティングすれば、100人規模のサークルのアクセスだとほぼ0円で運用することが可能です。
そこで、今までEC2上でLaravel mixで開発していたものを、lambda上のpythonとVue.jsで作り直しました。
アーキテクチャは以下のようになりました。
Basic認証
動画など個人の顔が含まれますので、今回のアプリも前回同様にサークル員のみがアクセスできるように認証機能を作る必要があります。しかし、クレカ機能などを作らない場合個人の認証は必要なく、サークル員であることが担保されればいいのでBasic認証のみ実装することにしました。S3hostingでbasic認証するのは少し難しく、cloudfrontを使う必要があります。
PDF作成
合宿などでは同意書を書くのですが、PDFをスキャンしたり、
編集するのは色々面倒です。そこで名前と住所を画面上で入力すれば、自動でPDFが生成され、管理者側とユーザー双方にPDFを保存できるシステムを作りました。サーバーレスでPDFの作成アプリを作るのは結構面倒でした。PHPのベアメタル環境であれば、wkhtmltopdfとかでできるのですが、コンテナ化するのはもちろん、lambda上で動かすのは至難でしょう。特に日本語で作るとなるとフォントに気を使わないといけません。そこで、Lambda layerの機能を使って、puppeteerというNodejsで制御できるchromeをlambda上で動かしPDFを生成しました。
この記事が気に入ったらサポートをしてみませんか?