「完全に理解した」状態の僕が「チョットワカル…」になるまでのとある企業の新人研修 part.2

▼前半part.1こちらから▼
https://qiita.com/kobayashimakoto/items/4fe942815c7fc941821f
今回は前回に引き続いて、どのような流れでアプリを作ったのかをご紹介します。
# はじめに
会社員の皆さん

**他部署の人の「名前」や「趣味」をいくつ言えますか？**

「みんなの趣味くらい余裕で知ってるわ」と言えるように
**お手伝い**をするアプリを作ったのでご紹介します。

## アプリ概要 〜TeaTime〜

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/6d6f9ffa-87bf-e825-e585-ba3d1e7955d9.png)

**TeaTime（茶会）とは**
**広く、お茶などを飲みながら話を交わすのを楽しむ集まり。**
※ 精選版 日本国語大辞典「茶会」の解説

## 簡単な使い方説明
・TeaTimeに登録するだけ。以上！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/654ccc04-4980-aa6b-d197-c387034e71fd.png)

つまり、このアプリに登録しといたら、登録者の間でいい感じにお茶会をセッティングしてくれて
そのお茶会に参加することで、**仲良くなれる機会を得る**というわけです。


# なんで作ったのか？
・近年、会社の成長に伴い社員の新陳代謝が激しい
・コロナ禍による社員間の交流の減少
などの原因から社内での交流が著しく低下している。
その結果、誰がどの部門に所属してどんな業務をしているか分からない状態。

そこで

「社内交流アプリをみんなに使ってもらって、お互いのことをもっと知ろう！」
という背景があって、このアプリの開発がスタートしました。


# ユーザー体験シナリオの作成

アプリを作る上で最初に着手したのがユーザー体験シナリオでした。
ユーザー体験シナリオとは、ユーザーがアプリを起動して、その体験を得るまでにどのような工程を踏むかを言語化したものです。
僕は[lucid](https://www.lucidchart.com/pages/alternative-to-visio-for-mac-OS-X)を使って、作成しました。

>部門長
>「ユーザー体験シナリオを描き始める時、どこを起点にするかわかる？」
>
>僕
「やっぱり、一番最初のログインから順番に・・・じゃないでしょうか。。。（自信なさげ）」
>
>部門長
「答えの一つとして  **ユーザーが一番嬉しくなる瞬間**  がいいかもね」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/09c5537a-1358-3022-231f-eb33f61b0747.png)


今回は「お茶会を通じて社員同士の仲を深める」ことが **ユーザーに価値を与える瞬間** になります。
それを叶えるために

**・どんな機能があれば嬉しいか**
**・どんなイベントがあればお茶会に出席してもらえるか**
**・どうすればリピートしてもらえるか**
etc・・・

を考えました。
その結果、「絶対に必要な機能」「あれば嬉しい機能」などが見えてきました。


アプリに限らず、「どうすればプロダクトの価値をユーザーに届けられるのか」は超重要。
単にコーディングだけじゃなく、マーケティング的な考え方も必要なんだと考えさせられました。

# TASKの優先順位つけた？
>先輩
>「どこから着手しますか？」
>
>僕
>「とりあえず書きやすいHTML/CSSからやろうかなと・・」
>
>先輩
>「優先順位はつけた？」
>
>僕
>「まだっすね・・」

### TASKに優先順位をつける

**期間内に動くものを作るために「アプリが動く > デザイン」** を前提に置きつつ、必要な機能を
重要度順で**MUST > HAVE TO > WILL** にバラしました。

**MUST （これがないとアプリとして成立しない）**
・特定のチャンネルにメッセージ送信機能
・ユーザーのslack_id 取得機能
・お茶会リストの作成機能

**HAVE TO （なくてもアプリとして成立するが、できる限り着手したい）**
・スラックによる外部認証を用いたログイン/ユーザー登録機能
・過去のお茶会リスト一覧
・定期実行処理の設定
・ログイン時にslackのアイコン画像取得機能
・HTML/CSSの記述（「動くものをつくること」が重要なので優先度が下がる）

**WILL （時間的に余裕があればやる）**
・SP対応



まずはHTML/CSSガン無視で**MUST機能**から着手しました。
理由としては、**「アプリとして動くもの」をいち早く作るため。**

なので最初の方はアプリというよりかは、機能パーツが散在しているような感じでした。
次第に機能同士が結合して、ストーリーを帯びている感じがワクワクしました。


# DB構造

DBは以下のように、「お茶会テーブル」、「スタッフテーブル」とそれらをつなぐ中間テーブル「お茶会リスト」、日付テーブルのみとかなりシンプルな内容になりました。
ここで転けると終盤、**ちゃぶ台返し** を喰らいかねないので、先輩方にがっつりレビューしていただきました。
（ちゃぶ台返し：必要な機能に対し、DB構造が適応できず、テーブル設計からやり直すこと）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/298b31df-d800-8aec-d8fe-3c9e9060cc59.png)



## コードの一部 ご紹介

メインギミックの一つである**slackログイン**について当時実装したコードをご紹介します。
```ruby
class OauthsController < ApplicationController
  require "net/http" #URLメソッドを使用するために必要
  require 'json' #JSON を使うために必要

  def oauth
    login_at(params[:provider])
  end

  def callback
    # 「login_from」はsorceryのメソッド
    #  Slack-apiにより取得したユーザーの情報が@user_hashに格納されて返される。
    @user = login_from(params[:provider])
    id = @user_hash[:user_info]['user']['id']

    # 画像取得処理（API投げる）
    uri = URI.parse("https://slack.com/api/users.info?user=#{id}")
    request = Net::HTTP::Get.new(uri)
    #発行されたトークンをセット
    request["Authorization"] = Rails.application.credentials.authorization
    request_options = {
      use_ssl: uri.scheme == "https"
    }

    response = Net::HTTP.start(uri.hostname, uri.port, request_options) do |http|
      http.request(request)
    end

    #取得したJSONデータをハッシュに変換
    result = JSON.parse(response.body)
    #画像取得完了

    avatar = result['user']['profile']['image_1024']
    name =  @user_hash[:user_info]['user']['name']
    email =  @user_hash[:user_info]['user']['email']

    # DBの文字が20文字以内の制限になっているため
    if name.size > 20
      name = name.slice(0, 20)
    end

    # スラックIDでMstUser内検索し、見つかればsessionにデータを格納するのみ。
    # 見つからなければ新しくユーザーを作成した上で、sessionにデータを格納する。
    if  existing_user = User.find_by(slack_id: id)
      existing_user.update!(name: name, image_url: avatar, recess_flag: '0')
      session[:user_id] = id
      redirect_to root_path
    else
      User.create!(name: name, slack_id: id, email: email, image_url: avatar)
      reset_session
      session[:user_id] = id
      redirect_to root_path
    end
  end

  def logout
    current_user.update!(recess_flag: '1')
    reset_session
  end
end
```
改めて見るとツッコミどころ満載な内容になっています(⌒-⌒; )。
・クラス名分かりにくい！（何やねんOauthsって）
・`require` はクラスの外に置こうよ・・・
・どっからどこまでどんな処理してるか分からん・・・
・名前の文字数削る処理はモデルに書けよ。ていうかDBの設定直せよ・・・
・メソッド名「`callback`とか`aoth`」ってよく分からん
・gemである`sorcey`を使っているけど中途半端な使い方してる・・・
・API叩く処理は外部クラスに切り分けようよ・・・
・コメントがわかりにくい・・・
etc


先輩曰く、「3ヶ月前に書いたコードは改善したくなってる」の意味がなんとなく分かりました。
ただ、上記のように、すぐに改善する方法が頭に浮かぶのは、それだけ研修や業務を経て、
プログラマーとして成長できたと前向きに考えています。

そして、「動くアプリ」を作ったことは自分にとって大きな自信にもつながりました。

## 最後に

ここまで見ていただきありがとうございました。

次回は、
**・アプリを実際に運用してみてどうだった？　
・改善するなら何を考えるか？
・アプリを作る上で「やらかしたこと」**
についてご紹介します。

続きの[part.3 はこちら](https://qiita.com/kobayashimakoto/items/628e76e1b61b843b218d)から！