自分たちの役に立つものを開発せよ（初めてのチーム開発）

# はじめに
私は、内定直結型エンジニア学習プログラム「[アプレンティス](https://apprentice.jp/lp)」に6期生として参加しています。
その中でチーム開発に取り組んだので、学んだことや実際にどんなことをしたのかを書いていきます。
至らない点もあるかもしれませんが、優しい目で見守っていただけると幸いです。どうぞよろしくお願いいたします。

## 実際に作ったプロダクト
#### 時間管理アプリ(YALOOP)
- 学習時間の計測
- グラフによる学習時間の可視化(1日分、1ヶ月分)
- 1日の振り返りのための日報

 ![スクリーンショット 2024-09-10 16.38.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835540/d1a5fc06-2f7c-74ea-313c-d984080256da.png)


## チーム開発の概要

### テーマ　『自分たちの役に立つものを開発せよ』
#### チーム開発の要件

- ベースとなる技術は HTML/CSS/JavaScript/MySQL/Ruby or PHP をご使用ください。
- Rails, Laravel, React などのフレームワークは使わないでください。まだフレームワークを学習していない方もいて開発に付いていくのが困難になるのと、生の言語で書くことで DEV 1 の学びを深めたいというのが理由です。
- ローカル（手元のPC上）で動くようにしてください。
- 最終日に各チーム、制作物をプレゼンしてもらいます。プレゼン時間は5分となります。プレゼンは Zoom の画面共有で、スライドとデモを使用して行ってください。デモはローカル上で制作物を実際に動かして見せることです。基本はデモで動作するところを見せますが、どうしても難しい場合は動画やスクリーンショットを使ってください。

### メンバー構成
- 実務未経験の3人チーム
- 全員がチーム開発未経験
- プログラミングのレベル：rubyで簡単な実装をしたことがある

# チーム開発でやったこと
## 1. プロダクト決め
### 前提として
- 実装期間は1週間なので期間内で完成できるもの
- 自分たちの役に立つもの
### 背景
- アプレンティス生は毎日、日報の提出が義務になっている
- 日報には学習時間を掲載する必要がある
- 日々継続して、学習する必要がある

### 課題
- 1日における、学習内容ごとの学習時間を思い出すのが大変
- 学習を継続するのは難しい
- 学習の習慣化のきっかけが欲しい

### プロダクト決定
- 上記の背景、課題から以下の機能を持つプロダクトに決定しました
  - 学習内容ごとに時間を計測
  - 継続するためのモチベーションづくりとして、学習時間の可視化
  - 日々のルーティンとして、日報の記入
<br/>

#### インセプションデッキ
- 全体の方向性を共有するためにインセプションデッキも行いました
<details><summary>詳しくはこちら</summary>
  <p>問1. 私たちはなぜここにいるのか</p>
  <ul>
      <li>なぜこのプロジェクトに取り組むのか：自分たちの時間管理に対しての解決</li>
      <li>自分たちの仕事の核となる価値：日報の継続のハードルを下げる</li>
      <li>何をお客様に届けたいのか：リズムを作り出すのに、習慣化のきっかけ</li>
  </ul>
  <p>問2. エレベーターピッチ</p>
  <ul>
      <li>誰に向けているのか：目標に向けて学習している人</li>
      <li>要約すると何なのか：学習時間の可視化、継続のハードルを下げるモノ</li>
      <li>どんな価値が生み出せるのか：学習のリズム、習慣化のきっかけ、継続のハードルを下げる</li>
      <li>ライバルとの違いは何か：シンプルでわかりやすい、機能の量（少なく）</li>
  </ul>
  <p>問3. パッケージデザイン</p>
  <ul>
      <li>ひらけば説明なくても使える</li>
      <li>デザインが説明になってる</li>
  </ul>
  <p>問4. やらないことリスト</p>
  <p>やること</p>
  <ul>
      <li>時間の計測</li>
      <li>時間の可視化</li>
      <li>日報の記入</li>
  </ul>
  <p>やらないこと<p/>
    <ul>
      <li>他ユーザーはなし</li>
    </ul>
　<p>やりながら決めること<p/>
    <ul>
      <li>Xへの投稿</li>
      <li>discordへの投稿</li>
  　</ul>
  <p>問5. ご近所さんを探せ</p>
  <ul>
      <li>チームメンバー</li>
      <li>同期</li>
      <li>メンターさん</li>
  </ul>
  <p>問6. 技術的な解決策を描く</p>
  <ul>
      <li>言語：HTML/CSS/JavaScript/Ruby/MYSQL（フレームワークなし）</li>
      <li>ライブラリ：Chart.js/MySQL2/AJAX</li>
      <li>ツール：Docker/WEBrick/Git/VSCode</li>
  </ul>
  <p>問7. 夜も眠れない問題</p>
  <ul>
      <li>どうやってrubyで作るのか</li>
      <li>いざこざあったら</li>
  </ul>
  <p>問8. 期限を見極める</p>
  <ul>
      <li>スケジュール通り</li>
  </ul>
  <p>問9. トレードオフスライダー</p>
  <ul>
      <li>スコープ：問４のやることを全て備える</li>
      <li>予算：無料</li>
      <li>納期：9/5 22:00</li>
      <li>品質：バグを出さずに動くようにする</li>
  </ul>
  <p>問10. 何がどれだけ必要か</p>
  <ul>
      <li>スキル：「Ruby」「HTML」「CSS」「javascript」「docker」「webrick」「sqlite」</li>
      <li>期間：4日間</li>
      <li>コスト：０</li>
  </ul>
</details>

https://products.sint.co.jp/obpm/blog/inception-deck

## 2. 要件定義
要件定義に関しては、以下のサイトを参考にあーだこーだ話し合いながら、決めていきました。
> 3人とも知識が十分ではなかったので、技術や構成などに関しては、少し不安を持ちながら進めていました。笑
今思えば、しっかりと話し合いでの課題を明確にしてその都度、解決する必要があったと思います。

https://be-marke.jp/articles/knowhow-website-requirement-definition

<details><summary>1. 背景</summary>
  <p>現状の問題</p>
  <ul>
    <li>1日における、学習内容ごとの学習時間を思い出すのが大変</li>
    <li>学習を継続するのは難しい</li>
    <li>学習の習慣化のきっかけが欲しい</li>
  </ul>
</details>

<details><summary>2. プロジェクト概要</summary>
  <ul>
    <li>人員: 3人</li>
    <li>スケジュール: アプレンティスのチーム開発スケジュールを参照</li>
    <li>定例ミーティング: 週２回（火、土21:30~)</li>
  </ul>
</details>

<details><summary>3. サイト構成</summary>
  <ul>
    <li>サーバーOS: Ubuntu?</li>
    <li>クライアントOS: macOS</li>
    <li>デバイス: PC (余裕があればモバイル対応)</li>
    <li>サイトマップ: トップページのみ (日、月の切り替え機能あり)</li>
  </ul>
</details>

<details><summary>4. システム要件</summary>
  <h4>必須機能</h4>
  <ul>
    <li>タスク入力</li>
    <li>スタート/ストップ/休憩ボタン</li>
    <li>開始、終了の差分で合計時間の出力</li>
    <li>作成したタスクはタグ化して再度選択可能</li>
    <li>ストックタスクの編集、削除機能</li>
    <li>完了後に時間をグラフ化（縦棒グラフ、上限あり）</li>
    <li>1日単位と月単位のグラフ切り替え（ボタンで非同期処理）</li>
    <li>完了後に日報機能（タスクと時間の出力、デフォルトの記入項目）</li>
  </ul>

  <h4>追加開発</h4>
  <ul>
    <li>UIの色変更機能（時間、タスク進行中に反映）</li>
    <li>レスポンシブデザイン</li>
    <li>ユーザー登録機能</li>
  </ul>
</details>

<details><summary>5. 技術要件</summary>
  <ul>
    <li>HTML, CSS, Ruby, JavaScript/AJAX, SQL/MySQL, Git/GitHub, Docker, Ubuntu,webrick (暫定)</li>
    <li>フレームワークなし</li>
  </ul>
</details>

<details><summary>6. インフラ要件</summary>
  <ul>
    <li>ローカルのみ</li>
  </ul>
</details>

<details><summary>7. セキュリティ要件</summary>
  <ul>
    <li>現時点では考慮しない</li>
  </ul>
</details>

<details><summary>8. リリース要件</summary>
  <ul>
    <li>本番リリースなし</li>
  </ul>
</details>

<details><summary>9. 保守運用</summary>
  <ul>
    <li>なし</li>
  </ul>
</details>


## 3. 設計
- 業務フロー、画面遷移図、ワイヤーフレーム
    <details>
    <summary>フリーボード上で作成</summary>

    ![スクリーンショット 2024-09-10 20.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835540/4bf06795-af02-c5db-f960-900a7020a3fd.png)

    </details>


- テーブル定義書
    <details>
      <summary>テーブル設計</summary>
      <p>Tasks</p>
      <table>
        <thead>
          <tr>
            <th>カラム名</th>
            <th>データ型</th>
            <th>Null</th>
            <th>Key</th>
            <th>初期値</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>id</td>
            <td>int</td>
            <td>NO</td>
            <td>PRI</td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>title</td>
            <td>varchar</td>
            <td>NO</td>
            <td></td>
            <td>NULL</td>
          </tr>
        </tbody>
      </table>
      <p>Daily Tasks</p>
      <table>
        <thead>
          <tr>
            <th>カラム名</th>
            <th>データ型</th>
            <th>Null</th>
            <th>Key</th>
            <th>初期値</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>id</td>
            <td>int</td>
            <td>NO</td>
            <td>PRI</td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>tasks_id</td>
            <td>int</td>
            <td>NO</td>
            <td>FK</td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>daily_reports_id</td>
            <td>int</td>
            <td>NO</td>
            <td>FK</td>
            <td>NULL</td>
          </tr>
        </tbody>
      </table>
      <p>Daily Reports</p>
      <table>
        <thead>
          <tr>
            <th>カラム名</th>
            <th>データ型</th>
            <th>Null</th>
            <th>Key</th>
            <th>初期値</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>id</td>
            <td>int</td>
            <td>NO</td>
            <td>PRI</td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>description</td>
            <td>text</td>
            <td></td>
            <td></td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>user_id</td>
            <td>int</td>
            <td>NO</td>
            <td>FK</td>
            <td>NULL</td>
          </tr>
        </tbody>
      </table>
      <p>Users</p>
      <table>
        <thead>
          <tr>
            <th>カラム名</th>
            <th>データ型</th>
            <th>Null</th>
            <th>Key</th>
            <th>初期値</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>id</td>
            <td>int</td>
            <td>NO</td>
            <td>PRI</td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>name</td>
            <td>varchar</td>
            <td>NO</td>
            <td></td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>email</td>
            <td>varchar</td>
            <td>NO</td>
            <td></td>
            <td>NULL</td>
          </tr>
        </tbody>
      </table>
      <p>Times</p>
      <table>
        <thead>
          <tr>
            <th>カラム名</th>
            <th>データ型</th>
            <th>Null</th>
            <th>Key</th>
            <th>初期値</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>id</td>
            <td>int</td>
            <td>NO</td>
            <td>PRI</td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>start_time</td>
            <td>datetime</td>
            <td>NO</td>
            <td></td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>end_time</td>
            <td>datetime</td>
            <td></td>
            <td></td>
            <td>NULL</td>
          </tr>
          <tr>
            <td>tasks_id</td>
            <td>int</td>
            <td>NO</td>
            <td>FK</td>
            <td>NULL</td>
          </tr>
        </tbody>
      </table>
    </details>
- 技術アーキテクチャ
  - アーキテクチャーの重要性を考えず、設計しませんでした
  そのため、データフローがあやふやで開発の効率が悪かったです

>設計に関しては、いくら簡単なアプリだろうと、説明書になるのでしっかりとするべきと感じました。

## 4. タスク出し
実際にはフロントエンド、バックエンド、DB設計、環境構築など大まかにしか決めていませんでした。
余裕を持って開発を進めていたため、完成はしましたが、少なくともデータフローの観点から以下の内容ぐらいは決めておく必要があったと思います。
</br>

- フロントエンド
  - デザイン
  - バックエンドへのデータ送信(task,report)
  - 受け取ったデータの出力(task,report)
- バックエンド
  - DBへのデータの保存(task,report)
  - DBからデータの取得(task,report,user,time)
  - 取得したデータの処理
- 環境開発
  - dockerの構成

## 5. 実装

### チーム開発期間で担当したこと

チーム開発期間では、以下の実装を担当しました：

1. **データベースからデータの取得**
   - MySQLデータベースからタスク、日報、ユーザー、学習時間に関するデータを取得するための実装をしました。具体的には、適切なSQLクエリを用いて必要なデータを抽出しました。

2. **データの処理（バックエンド）**
   - 取得したデータをバックエンドで処理しました。これにはデータの集計や加工が含まれ、例えば日別や月別の学習時間を集計して、視覚化に適した形式に整えました。

3. **JSON形式での返却**
   - 処理されたデータをJSON形式でフロントへ返す実装を行いました。これにより、フロントエンドのJavaScriptでデータを受け取り、処理されたデータを映し出すことができます。

4. **タスクや時間の表示（フロントエンド）**
   - フロントエンドで、タスクや学習時間の表示をする機能を実装しました。具体的には、タスクごとの学習時間を表示し、ユーザーが簡単に確認できるようにしました。また、日報やその他の関連情報も視覚的にわかりやすく表示しました。

5. **グラフの表示（フロントエンド）**
   - Chart.jsを用いて、データの視覚化を実装しました。具体的には、以下の作業を行いました：
     - Chart.jsの設定: グラフの種類（スタックグラフや折れ線グラフなど）やデザインを設定し、理解しやすいようにデータを表現しました。
     - データの取得: 最初はサンプルデータで、その後に、JSONデータをChart.jsに渡し、データの受け渡しを簡単にできるようにしました。

# チーム開発で学んだこと
### タスク出しの重要性
開発が始まってから、いくつものタスクが出てきました。
これは、タスク出しの時や、設計の部分で詳細な部分まで作り込めっていなかったために起きたものだと考えています。
タスクを洗い出し、メンバーでコードの全体像を把握し、さらに細分化をしていれば、開発中に誰がどこをやるかや、どんなコードを書くのかに迷わずに、効率的に開発を進められていたと思います。
次回のチーム開発では、タスク出し、設計の部分に特にこだわって、全体像をメンバーで把握していこうと思います。

### コミュニケーション
開発中はずっとdiscordで通話状態にしていつでも相談をできる環境を作って作業をしていました。
そのおかげで、困っていることなどを共有、解決ができ、スムーズに開発できました。

### 言語化の重要性
開発を進める中で特に感じたのは、言語化の重要性です。どんな作業においても、自分が考えている内容を明確に言葉にして、「分かりやすく」伝えることが非常に重要だと強く感じました。

言語化でまず大切なのは、具体的に何について話しているのかを相手に伝え、共通のイメージを持ってもらうことです。その共通のイメージを持つことで、後からの説明もスムーズに進み、理解の食い違いが起こりにくくなると考えています。

自分の考えていることを明確に伝えるためにも、どうしていけばいいのかを調べていこうと思います。

# まとめ
チーム開発を通して、１番の気持ちは「**すんげえ楽しかった**」です。
イメージの共有や、タスク管理などチームで開発する難しさが多くありましたが、チームの方々がとてもいい人柄だったので、すごく楽しく開発ができました。
仲もより深まったことなので、これからの学習も一緒に頑張っていきましょう！！！