【初めてのAWS】チームの勤怠管理システムを作ってみた（その２）

# 1. 初めに
勤怠管理システムの全貌としては以下の3つである。3本に分けて残していく。今回はその２！
[その１：名前を選択して「出勤」or「退勤」ボタンを押し、記録する](https://qiita.com/waiiioss/items/6c2ca747a55d3dca9224)
その２：勤怠記録のデータを可視化する <--IMAKOKO
その３：過去の勤怠を編集できるようにする

**本Qiitaの内容**
* LambdaからDynamoDBのデータ取得
* 可視化手法

今回はJSが大きく絡んでくる

# 2. Lambda関数からDynamoDBのデータ取得
前回作ったDynamoDBでアクセスして、データを取得するためのコードを書く。今回のコードは引数にユーザーのインプットがあるわけではなく、データベースにある情報を全て取ってくるというモノなので、特に面白いことはない。
淡々と書こう。当然だけど文字列と数値の扱いは気をつけよう！ロールの付与も当然しよう！Lambda関数->設定->アクセス権限でロール名と書いてあるところからロールの管理をする。前回書いたハンズオンをやっていればわかると思う。

```Python read.py
def lambda_handler(event, context):
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('TableName')  # DynamoDBのテーブル名を設定

    try:
        response = table.scan()  # テーブルの全データをスキャン
        items = response['Items']
        
        # Decimalオブジェクトを文字列に変換してからJSONにシリアライズ
        serialized_items = json.dumps(items, default=decimal_default)
        
        return {
            'statusCode': 200,
            'body': serialized_items
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps(str(e))
        }
```

# 3. HTML, CSS, JSをChatGPTに作ってもらう
前回と同じように可視化したい手法を指定して、プロンプトを書きChat GPTにwebを作ってもらおう。
今回は、可視化手法について以下の四つを採用した。
* チーム全員の総勤務時間
* チーム内の出勤ランキング
* メンバー別の勤務時間棒グラフ
* 直近1週間のカレンダー記録

### JSを作るときにした方がいいこと
最初漠然とこの手法を達成するコード書いてって頼んでたけど、結局苦戦することになった。プロンプトの書き方が良くなかったと反省。API実行した後に渡されるデータの形をChat GPTに教えて、このデータ形式に合うよう作ってもらわないと時間がかかってしまう。
以下のようにプロンプトを書いてあげると、すんなりそのまま使えるコードを書いてくれる。
``` text prompt.txt
{
  "statusCode": 200,
  "body": "[{\"WorkHours\": \"0.2\", \"Timestamp\": \"2024-04-22T22:52:32.593172\", \"EndTime\": \"2024-04-22T23:04:32.427279\", \"Name\": \"A\\u3055\\u3093\"}, {\"WorkHours\": \"0.24\", \"Timestamp\": \"2024-04-22T23:05:25.838179\", \"EndTime\": \"2024-04-22T23:19:34.611489\", \"Name\": \"A\\u3055\\u3093\"}]"
}
この形のjsonを受け取る
それぞれ可視化するためのJSコードを書いて
```

# 4. JSでAPI呼び出し
API GatewayでAPI化してエンドポイントを取得して、JSに組み込む。

```Javascript datalaod.js
document.addEventListener('DOMContentLoaded', function() {
  // ローディング画面を表示
  document.getElementById('loading').style.display = 'flex';
  
  fetch('https:///endpoint')//エンドポイント
    .then(response => response.json())
    .then(data => {
      const rawData = JSON.parse(data.body);
      processData(rawData); //可視化の関数１
      createTimeChart(rawData); // 可視化の関数２

      // データ処理が完了したら、1秒後にローディング画面を非表示にする
      setTimeout(() => {
        document.getElementById('loading').style.display = 'none';
      }, 0);
    })
    .catch(error => {
      console.error('Error fetching data:', error);
      setTimeout(() => {
        document.getElementById('loading').style.display = 'none';
      }, 0);
    });
});

```

# 5. 可視化手法
今回はAWSの記事なのでこのパートはサクッとコードを載せるだけにしとく。

**出勤ランキング**
出勤ランキングのJSコード事前にhtml側でidがあるdivを作ってidをJSにはる。
``` Javascript ranking.js
function createAttendanceRanking(attendance) {
  const list = document.getElementById('Ranking');//表示する場所のhtml id
  list.innerHTML = '';

  const sortedAttendance = Object.entries(attendance).sort((a, b) => b[1] - a[1]);

  sortedAttendance.forEach((entry, index) => {
    const li = document.createElement('li');
    li.textContent = `${index + 1}位: ${entry[0]} (${entry[1]}回)`;
    list.appendChild(li);
  });
}
```
他にもあるけど、Chat GPTと協力しながら作ってみてほしい。
プロンプトで受け取るデータ形式だけ教えてあげたら、すぐに作りたいものが作れると思う。

# 6. 最後に
前回APIに苦戦したおかげで今回はすんなり進められた気がする。
やっぱりChat GPTとの協働は大事だなと思った。ただ、何が必要かはある程度認識しておかないと、適切なアウトプットが返ってこないってのは当たり前だけど念頭に置いとくべき。

これでできた！って思ったら、「入力し忘れたとき過去の記録ってどうするの？」って言われてしまったので、次回過去の記録をつけられるように機能をつける。過去の勤怠の記録って何やねんと思いながら、必要と言われてしまったら作ってやるか精神で作ることにした。

次回：過去の勤怠記録機能作るぞおー