先日初めてサポーターズが運営している技育博に参加しました。
プロダクトが本番でうまく動作しなかったり、悔しい思いをしたりしたのですが、その中で気づいたこととか学んだこととかがあったので、そのことについて時系列を追いながらダラダラ書いてみようと思います。
朝マックについては後ほど...
自己紹介
軽く自己紹介しようと思います。
私は立命館大学の情報理工学部に通う3回生です。
大体3回生の4月くらいから開発について学び始めて、大体半年過ぎたかなぁくらいの経歴です。
普段は、立命館コンピュータクラブという技術系サークルの会長として、後輩の育成しつつ、自己研鑽したりしています。また、 MR系の研究室に所属しているのでUnityとVR開発がある程度できます。
エンジニア関連で言うと、GoとTerraformを使ったサーバーサイドのインターンと大学の先輩のサービスのお手伝いでNext.jsでのフロントエンド、たまに趣味でGithubActionsのCI書いたり色々してます。
作った作品
今回作ったのはHubMeという作品です。
HubMeは、探すのが大変なサークル探しと勧誘をタグ機能やスカウト機能で解決することを目的として、大学生(ユーザー)とサークル(コミュニティ)向けのマッチングプラットフォームです。
ユーザーやコミュニティはタグを設定することができ、これを使って自分の興味のあるカテゴリやコミュニティの行っている活動を簡単に検索するようにしています。
ChatGPT等を活用して選択したタグから興味のありそうなタグを表示させることを行ったりしています。
一方でコミュニティはタグからユーザを検索して、相性が良さそうなユーザーを勧誘(スカウト)することができます。
ユーザーはスカウトをメールで通知を受け取ることができ、承諾することでDMも行うことができるように設計し、実装しました。
まぁ本番動かなくなったりしたんですけど...
JPHacks
このプロダクトを作るきっかけは、10月に行われたJPhacksでした。
5人メンバーで参加し、5人とも友人でかつ自分が運営しているサークルのメンバーでした。
加えて、自分以外は技育博での企業賞をもらった実績や技育展での決勝出場決定が決まっている優秀なメンバーしかいなかったので、自分としてはとても無力感を感じつつもキャリーしてもらうかくらいの気持ちを持つこともできたので、結果的には軽い気持ちで臨むことができました。
なにを作るか考える
5人メンバーの強みとしてあったのは
- 人と何かのインタラクションを考えたサービスを考えることが多い
- かなり領域を横断したプロダクトを作るのが得意
という点がありました。
実際に私以外のメンバーはバックエンドとVRを使ったアプリケーションを作成して、先述した実績を挙げていました。
私自身もインターン経験としてUnity、Next.jsを使ったフロントエンド、Goを使ったサーバーサイドを経験していたので、技術スタック的には話についていける領域でした。
ある程度賞も狙えたらなとは話し合っており、かつハッカソンはある程度アイデア勝負と他メンバーは今までの経験から強く言っていたので、VRとバックエンドを使ったら面白くかつ賞も狙えるプロダクトになるのではないかとみんなで考えていました。
しかし、JPHacksは評価される開発期間が2日しかなく、VRようなアプリケーションはかなり動作調整させるのが難しいため、VRアプリケーションを作るのは難しいだろうと考えていました。
そこで、僕らが感じている(感じていた)悩みを解決できそうな問題を解決できそうなアプリケーションを作ろうという話になりました。
そこでサークル勧誘難しかったよねという話が出ました。
私がサークルの会長になった今年の新学期初めの頃、アクティブメンバーは5人ほどしかおらず、下手したらサークル消滅するかもしれないという危機に陥っていたことがありました。
その際、サークルの立ち上げに動かせる動員としてサークルに勧誘したのが、実は今回の開発メンバー達でした。なんとかそのメンバーでアクティブメンバーを20人から30人程度に立ち直すことができました。
本当に感謝しています。助かりました...
ただ、そのメンバー達もどうして新入生の時にこのサークル見つけれなかったんだろうと嘆いていました。やはり新入生にとってサークル探しは困難であり、探すにしてもX等のSNSで情報収集をするという慣れていないと難しいアクションを取らないといけなかったり、大学公認団体でないと勧誘できないというルールがある大学もあるらしく、出会うのは大学生もサークルも難しいという問題があるなと感じたため、そのようなサークル探しと新入会員獲得がしやすくなるようなプロダクトを作ろうと考えました。
JPHacksまでの準備期間
JPHacksは当日2日間以外は評価されないため、コードは書かず当日は実装に専念できるように設計やドキュメント整備に充てました。
私はフロントエンド担当として、ただ本業としてはサーバーサイドではあるのでサーバーサイドを主に実装するメンバーと交渉しながら、ドキュメントやタスク作成と技術選定とディレクトリ設計を行いました。
ドキュメントやタスク作成
私たちはドキュメントやタスク作成等をNotionで行いました。
ドキュメントでは、ディレクトリ構成の説明やライブラリの基本的な使い方や命名規則等をまとめました。
バックエンドでは、APIの仕様やdbのテーブル定義も書きました。
タスク(チケット)は、タスクの切り方を番号で割り振り、先頭の数字で領域を区別していました。
これはメンバーが今までのハッカソン経験で行っていたタスク管理方法で、画像のように
- 番号
- タスク名
- 状態
- 未着手
- 進行中/PR未
- 進行中/PR済
- マージ済み
- 停止中
- 割り当てるメンバー
という形をとっていました。
実際にタスクはデザイン担当がFigmaで作ってくれたページ単位で作るようにして、バグ修正があったらその都度作るという形をとっていました。
今見るとページクソ多い
技術選定
フロントエンドの技術選定としては、
いじりやすく
かつ
触ったことのある技術多めに
という点で選びました。
その結果下のようになりました。
カテゴリ | 名前 |
---|---|
フレームワーク | Next.js(React) |
言語 | TypeScript |
パッケージマネ-ジャー | yarn |
UIライブラリ | shadcn |
デザイン | SCSS(SCSSmodules) |
状態管理 | jotai |
バリデーション | zod |
lint | biome |
shadcnやscssを採用している理由は先述したいじりやすくを重視して選びました。
Tailwindでなくscssを採用しているのは
- 自分含め書いてる経験が多い
- TailwindよりCSSの方が情報が多い
- カラーコードを変数化したかった
という理由でした。
ちなみに私が担当していないバックエンドは
カテゴリ | 名前 |
---|---|
言語 | Go |
フレームワーク | Gin |
ORM | gorm |
マイグレーション | golang-migration |
これに加えてAWSでインフラをマルチAZを意識して構築していました。
どう考えてもハッカソンで作るアーキテクチャじゃない、バックエンドメンバー頭がおかしい(褒め言葉)
ディレクトリ設計
ディレクトリ設計は今流行りのfeaturesデザインを参考にしながら作りました。
srcディレクトリ直下は下のように分けました。
全体的に使いまわしつつ、技術にかなり依存してるものをディレクトリ直下に置くような感じで作っています。
例えば、shadcn等のライブラリは技術としてfeaturesにはいれないようにして、どこのディレクトリに入っているかさがしやすくしようとcomponentsに入れたり、axiosでつくったapi叩く用のモジュールはかなり技術依存だと判断してlibに入れたりと、全体的に使い回すものをappとfeatures以外に配置しています。
.
├── app
├── components
├── features
├── lib
├── styles
└── utils
ディレクトリ | 役割 |
---|---|
app | approuterでページのコンポーネント |
components | shadcnなどのライブラリコンポーネント |
features | 機能(ページ)のコンポーネントを作成 |
lib | axios等でつくったモジュール |
styles | globals.scssやテーマカラーの変数を定義 |
utils | その他使い回すモジュール |
featuresの中は、機能やドメインごとに分けて作成していました。
.
├── account
├── chat
├── event
├── home
├── menubar
├── popup
├── profile
├── scout
├── signin
├── signup
└── tags
加えてそのディレクトリの中は下のように役割ごとに分けてみました。
.
├── api //apiを叩くモジュール
├── components //ページや機能を構成するためのコンポーネントファイル
├── funcs
├── hooks
├── stores.ts //jotaiで定義したatomはこれに
└── types //zodでの型定義
これである程度、責務ごとにディレクトリを分けて開発しやすいように意識して考えました。
本番当日
自分たちは大阪会場だったので関西大学にお邪魔して開発がスタートしました。
初日は、10時くらいから開発が始まり19時ごろまで
2日目は、10時から15時まで開発してコードフリーズという感じでした。
たださっきのFigmaや認証や検索タグだけでなく、スカウトやDM機能など多くの機能があるのに、それを2日間で開発できるのか?という問題がありました。
完全に無理でした。
メンバーのほとんどが完徹して30時間以上稼働しても動作(完成)させることができませんでした。
結局、完成せず発表もfigmaで誤魔化し、自分たちのチームだけ完成していないという恥ずかしい思いをしました。
バカです。
私自身初めてのハッカソンだったのですが、結局完成させることができず、実装能力が低いなととてつもなく無力さを感じました。
とは言ってもいくら作品的に2日で無理なのはみて薄々気づいていたところがあります。そこで妥協する経験値や決断がなかったのもかなり自分としてもチームとしても落ち度でかなり落ち込んでいました。
なぜか企業賞がもらえる
2日間しかなかったのにまぁまぁ大きなプロダクトを作ろうとして、完成せず絶望したハッカソンの結果はどうなったかというと、タイミーさんから企業賞をいただきました。
え? しか出てきませんでした
メンバー全員この言葉を発したので面白かったです
JPHACKSはコードをかなりみてくれるハッカソンで、尚且つタイミーの企業理念とのマッチングかつタイミーのエンジニアの方がかなりの技術好きであったため、企業賞をいただくことができました。
一応講評としては
- ドメイン駆動設計をベースとした設計
- 企業理念との合致
をいただきました。
確かに完成はしませんでしたが、ある程度リリースも視野に入れつつ設計していたのが、良い結果を招きました。
悔しさは残るものの一応企業賞獲得という実績を手に入れることができました。
企業賞の景品として、めっちゃ高いところでご飯をいただきました...恐れ多かったです。
ただタイミーのエンジニアの方と設計や言語選定等の話ができてとても楽しかったです。
反省点
反省点としては
- ハッカソンでアイデアを重視しつつも、期間を意識して機能数を制限して開発できなかったこと
- お互いの認識共有(報連相)ができなかったこと
一番目は先述した通りでハッカソンで大きなプロダクトを作ろうと頑張り過ぎたなという印象でした。
二番目に関しては、プロダクトが複雑すぎてお互いに考えていることが全然違うという現象が起きることが多く、話し合いに時間が取られたりして大変でした。
ドキュメントの整備でなんとか対応しようとしましたが、それでもメンバーがどこになんのドキュメントが書かれているかを把握しきることができず、苦労しました。
技育博
技育博までのブラッシュアップ
せっかくここまで頑張ったし、企業賞ももらえた、加えて動いていないのでここから継続開発してリリースまでできたらしようという話になりました。
そこでサポーターズさんの技育博に参加してFBを企業様からもらおうという話になりました。
よし! ここから技育博通るように頑張ろう!と思った矢先にある困難が待ち受けました。
開発に回せるメンバーが自分しかいない
技育博は審査制のイベントなのである程度動く状態にして、応募する必要がありました。
技育博の申し込み期限が11月半ばだったのですが、その直前に技育展の決勝があり、自分以外のメンバーはそこへの準備をする必要がありました。
というわけで大体2週間ほど一人である程度のところまで開発して、そのあとみんなで1週間ほど開発して。技育博に応募必要がありました。
責任重大です。
作るべき機能としては
- スカウト
- DM
- ユーザーやコミュニティ一覧の表示がありました。
それに加えて
- サインインやサインアップが動かない
- デザインが複数箇所崩れてる
- ドキュメントでのAPI定義と実装されたAPIがかなり違う
- 決めた命名規則と違う書き方をしているファイルがある
- 分けたコードが乱雑
という絶望的な状態でした。(てか忘れてるだけでおそらくもっとありました)
応募まで3週間ほどしかなく、素直に開発するのは無理だなと思いました。
メンバーが技育展終わるまで開発する
なので、私は1週間でみんなで効率よく開発できるようにドキュメント整備とバックエンドの修正とディレクトリ構成やファイルの中身をある程度のリファクタを行いながらやっていくという方針を取りました。
これをとった理由としては、自分がある程度メンバーの中でも実務経験があり
- 自分はAPI仕様書としてswaggerがかける
- Goもかける
- CIもGihubActionsで組める
という点がありました。
結局長期的に開発したいという考えはあったのである程度それを念頭に置いてこの方針を取りました。
バックエンドのコードを見直す
ドキュメントでのAPI定義と実装されたAPIがかなり違った原因としては、バックエンドメンバーがAPIの定義を書く場所を限定し、その共有認識ができていなかったのが問題でした。
なので同じAPIの定義があらゆる箇所に書いてあり、JSONのプロパティ名が小文字にしてあるべきところが大文字になっていたり、URIが違ったり、色々問題が起きてました。
そのためswaggerでプロジェクト内に置くことでここにAPIの仕様を書くという制限をつけてやろうと思いました。notionだとページを新しく作ってしまうことがありますが、swaggerはライブラリの結合機能を使って1ファイルに定義をまとめることができるので、書く場所を誘導させることができるのではないかと思いました。
その際に書いた記事です。
幸いにもGoでのサーバーサイドの方が得意だったので、ある程度フロント側が使いやすいようにバックエンドのコードを修正し、swaggerの執筆、redoclyで1ファイルにまとめることを行いました。
また、GihubActionsでもし変更がredoclyでまとめられていなければ、結合させてフォーマッタの結果をPRに出すようにしました。
それに関する記事です。
フロントエンドを見直す
フロントメンバーはこのような命名規則で行っていました。
ターゲット | ケース |
---|---|
ディレクトリ | キャメルケース |
コンポーネント | パスカルケース |
tsxファイル | パスカルケース |
変数 | キャメルケース |
関数 | キャメルケース |
しかし、tsファイルの命名規則が統一されていなかったり、一部メンバーがこれを忘れて進めてしまっていたりしました。
また、featuresの中もfeatureの中にあるファイルやディレクトリが本当に見づらくなっていたので、ファイル位置の見直しを直す必要のあるファイルから行ってきました。
また、scssのCSSmoduleを使ってデザインをしていたのですが、一つのファイルにまとめて書きすぎていたので、分割したりもしました。
結局全ファイルリファクタできませんでしたが、先述したディレクトリ構成に沿ったわかりやすいコードに近づきました。
フロントの他メンバーも見づらいとJPHACKS以降嘆いて言いましたが、合流した後見やすくなったと言ってくれたので一安心しました。
ユビキタス言語を見直す
今回のプロダクトのターゲットは大学生とコミュニティであったため、そこの差別化をする必要がありました。
ただそこをuser、communityとして分けており、一般的にはuserはプロダクトを使用するターゲットを示すのにそこが明示されていないということがありました。
なのでユビキタス言語を定義することにしました。
下のようにアカウントドメインに対して、ユーザードメインとコミュニティドメインを作成し、それに加えてログインをサインインとして扱うように、招待とは言わずにスカウトと言葉を統一するようにしました。
また、lintでbiomeを使っていたのですが、設定ができていないメンバーもいるだろうということで、GithubActionsで自動的にbiomeを走らせるようにしました。
用語 | 説明 |
---|---|
ユーザー | コミュニティ(団体)に参加したい人(参加者) |
コミュニティー | サークルやイベントなどの主催者を指す |
アカウント | ユーザーとコミュニティの総称 |
DM | ユーザーとコミュニティのチャット |
タグ | 属性属性 |
サインアップ | アカウント作成 |
サインイン | ログイン |
サインアウト | ログアウト |
uuid | ユーザーのid |
スカウト | 招待のことのこと |
とりあえず応募するまで頑張る
他メンバーが技育展が終わったので、みんなで一斉に開発を始めました。
ある程度、先述の作業しながらタスク整理もしていたので一斉にタスクを振って、フロントは主にデザイン崩れと作成できていない機能の実装、バックエンドは足りなかったAPIの追加を行いました。
まぁ先述した作業である程度作業はしやすくなったとはいえ、やはり作成したページ数や機能数の多さ、テストコードがなかったりして保守性が低く確認できていなかった修正がたくさん見つかることが多く、ユーザーとコミュニティ双方にアカウントを表示させる等はできましたが、DMやスカウト機能は完成させれず、タグの操作も上手く動作させることができませんでした。
とりあえずできることをやろうとPR動画を一人のメンバーに全振りし、なんとか応募しました。
本当に無理させました、すいません
なんか通ったので動かすまで頑張ろう
なぜかわかりませんが、技育博が通りました。
なんで通ったかわかりません。はい。
とりあえず通って一安心...とは言っても作品が動いていないので、当日に向けて頑張らなければなりません。
そのため、拍車をかけてタスクを一つずつ終わらせていきました。
加えて技育展に参加したメンバーの提案でchatGPTを使ってAIサジェスト機能を作ろうという話になりました。
この時未だに動いていませんでしたが、ある程度企業からFBをもらうにはちょうどよく、また使い方がわかってるメンバーがいたため、そのメンバーにその機能は任せて、他メンバーでフロントが動くように注力しました。
そのおかげで前日までに、ほとんどの機能自体は作成し終わり、あとはデザイン修正とデプロイや!となりました。
技育博当日
というわけで本番を迎えました。
夜行バスで6時に東京駅について、そこからデザインの修正作業をすることになりました。
みなさん、ここまで話が長かったと思うのですが、この記事のタイトルを覚えていますか?
そう 朝マック です
朝マック
友人たちが技育博や技育展の当日、大体開発が間に合っていないことが多く、朝に充電できるマックで作業するということが多かったそうです。
そこから開発が間に合っていないので朝にマックで作業することを 朝マック という用語が生まれました。
朝マックである程度の修正は終わり、デプロイして動いていたので、これなら見せられるやろ!という状況になりました。
技育博に到着
技育博の会場に到着して、話を聞きながらデプロイを行って見せるための最終調整を行いました。
ただ、ここで急にデプロイがうまくいかなくなったり、先ほどデプロイした時(朝マック)に動いていた物が動かなくなったりして非常に困りました。
特にChatGPTを使ったタグのサジェスト機能を前日までに調整してある程度ローカルでは動いていたのですが、それもデプロイした途端思い通りに動かなくなり、結局完成していない状態に逆戻りしてしまいました。
発表
技育博の特徴は企業や同じ学生エンジニアに作成したプロダクトをアピールしてFBをもらえる点です。
デプロイしたものが動いてなかったり、ローカルでも思い通りに動かなくなってしまったりもしましたが、それで諦めず実装した機能を企業に説明して、AI機能は内部処理を見せたり、設計等や継続開発に向けた取り組むを話したりして、色々FBをもらうことができました。
結果
結果としては、企業賞とかは流石にもらえませんでした。
他の学生さんとかでもブロックチェーンを使った作品や黒電話を使った作品など、面白い発想をしてかつ技術もすごいプロダクトをも多く、かなり刺激的かつ自分たちの作品は動かせなかったのが悔しいと思いました。
しかし、企業様からのFBとしてコンセプトの良さや設計や技術選定がかなりしっかりしていた点はすごく褒めていただきました。
加えて、リリースする際にAWSやChatgptのAPIを使ってかなりコストがかかりそうだったのでそこの削減をどうしたらいいかという相談に乗っていただきました。
本当にFBをもらってよかったなと思いました。
感想
とにかく完成させたものを見せられなかったのが悔しいです。
ただ、ある程度上流工程で行っているような設計や技術選定が行えていたのかなとは思いました。
強みとして
- コンセプト
- 設計
- 共同開発に対する考え方
がよかったと思いました。
自分たちの悩みかつそれを技育博でわかっていただける方も多かったので、コンセプトとしては問題解決につながる良い開発だったのかなと思いました。
設計はJPHACKSの時もそうでしたが長期運用に向けたものができるようになったと思います。将来的に就職してから長期運用するプロダクトを作ることになると思うので良い練習だと感じました。
共同開発に関する考え方としては、企業での開発ではどうしてドキュメントがどうしてあるのか、それを再認識して見やすさだったり開発を効率化するためにもドキュメントをちゃんと書こうという考えが身についたのかなと思いました。
あとは、タスクの振り方においてもフロントのデザインを作ってくれた子は、デザイン力はある一方でコードを書いた経験が少なく、それに対する意欲が強かったため、できるだけ書かせてあげたいと思いました。
そのため、その子の成長を考えかつデザインセンスを信じてデザイン等のリファクタを任せるという選択をとりました。このおかげで前日までにはある程度すぐ実装できるようになっていたので、良い選択だったかなと感じています。
共同開発はある程度適材適所かつ相手の能力も伸ばしていく必要があると思いました。
弱みとしては
- 計画性
- 長期運用に向けたビジネス的な考え
- APIを使い方における工夫
だと思いました。
計画性に関しては完成しなかったのがとても大きく、工数や期限設定も考えてやらないと今回の場合はダメだったかなと思いました。まぁハッカソンどころの規模じゃなく大きくしすぎたのが原因でした。AWSやCIでかなり時間を割いて今後の運用を意識してしまったのに加えて、技育博に向けてももう少しDMとか機能を減らしてもよかったのかなとは思ったりもして、タスクの優先度も考えないといけないと思いました。ここを解決するには経験だと思うので、これからも開発経験を積むことが大事だと思いました。
長期運用に向けたビジネス的な考えとしては、AWSやChagGPTのAPIにどうしてもお金がかかってしまい、それを抑えるためにもコミュニティからお金を取る、広告を出す等の工夫をしなければなりません。企業様にも言われたのが、もう少し機能の少ない小さなプロダクトからリリースして、お金のやりくりができるようになってからChatGPTやAWSのサービス選定したら?と言われました。本当に参考になりました。
既存のAPIを使う等の工夫に関しては、タグの表示はChatgptにこだわらなくてもGoogleSearchAPI等のAPIでも代用できるのではないかなと感じました。コストの高い技術選定を指定したと感じているので、もう少し工夫して安くできればと感じました。
というような感じで得たものが多かったです。
私自身開発を始めたのが半年前くらいで、始めた時に友人たちが技育博で企業賞をもらってるのを見て自分も追い付けたらなと思っていました。
友人たちも技育博や技育展に連れてってあげたいと思ってくれていたらしく、今回友人たちのおかげで良い経験を積めました。本当に感謝しています。
加えて、FBをいただいた企業様、機会をくださったサポーターズ様、なんならハッカソンに初めて出るきっかけになったJPHACKSの運営の方々本当にありがとうございました。
正直リリースに関しては怪しいです、お金がかかってしまうと言う点から学生で運営するのは難しいなと感じています。
ただ完成は一旦したいよねと言う話がメンバーの中で出ていて、自分もそう思ってるので一旦完成させたいなと思います。
これからも継続開発していこうと思います。