コンテンツにスキップ

日報と勤怠報告の連携ツール

現在では、アルバイトの稼働について、Slackのtech-activityチャンネルに日々の日報を記入している。作業内容の可視化だけでなく、できたこと・できなかったことを言語化して社員の方に見てもらう意味を持っている。

それとは別に、勤怠管理と給与計算のために、毎月スプレッドシートに稼働実績を自分たちで記入している。基本的にはtech-activityに記入する日報から内容を抜き出せばよいが、1日に様々なプロジェクトで稼働していたり、休憩を多く挟んでいたりすると、そのままではスプレッドシートの記入制約を満たすことができず、フォーマットを整形しなおす必要がある。

また、日報の写し間違えがないかといったことの確認作業も発生しており、担当者に少なくはない負担がかかっているため、tech-activityの内容と勤怠管理シートの内容を自動的に同期させる仕組みがあれば、アルバイトとプロパー社員両方にとってメリットがある。

  • tech-activityでの日報の内容と、勤怠管理シートの内容の同期
  • 日報のフォーマットの統一
  • スプレッドシートの記入行数制限についての管理や、制限を超えたときの対応方法について、その運用手続きをはっきりとさせる。
  • プロジェクトコードを探したりする記入に関する負担軽減
  • (追加で)毎月のアルバイトの稼働実績の可視化
日報と勤怠報告の連携ツールのイメージ
  • 要件定義
  • 技術選定
  • テーブル設計
  • 認証機能の実装
  • 記入アプリのUI作成
  1. ユーザーがUIから日報を入力
  2. 入力内容はSupabase上のDBで管理するTIMESHEETSテーブルに格納されて保存
  3. ボタンを押してSlackに日報、スプレッドシートに勤怠を投稿する
  • USERS
    • アプリのログインユーザー情報を格納する
  • PROJECTS
    • プロジェクトコードとプロジェクト名の対応を格納する
  • TIMESHEETS
    • 最新の日報の内容を保持。通常はこれを見れば良い。
  • TIMESHEET_REVISIONS
    • 日報の更新/削除前のスナップショットを保存する。versionは自動採番。 これにより、いつ・誰が・なぜ変更したのかを追跡できる。

勤怠データとSlackメッセージの対応テーブル

Section titled “勤怠データとSlackメッセージの対応テーブル”
  • SLACK_MESSAGES
    • 1つの勤怠に対してSLACKに投稿するメッセージと、投稿状況を保持する。 どのSlackメッセージ(channel_id + message_ts)に対応するかを保持。

勤怠データとSpreadsheet行の対応テーブル

Section titled “勤怠データとSpreadsheet行の対応テーブル”

まだ設計していないが、同様に勤怠データとスプレッドシートの行を対応付けるテーブルを作成する予定。

カラム名制約説明
iduuidPKユーザーID
emailtextUNIQUEメールアドレス
passwordtextNOT NULLパスワード
カラム名制約説明
codetextPKプロジェクトコード
nametextNOT NULLプロジェクト名
カラム名制約説明
iduuidPK勤怠ID
work_datedateNOT NULL作業日
start_timetimeNOT NULL開始時間
end_timetimeNOT NULL終了時間
project_codetextFK (PROJECTS.code)プロジェクトコード
tasktextNOT NULL作業内容
donetextできたこと
not_donetextできなかったこと
next_actiontext次にやること
propertext担当社員
user_iduuidFK (USERS.id)ユーザーID
created_attimestamptzNOT NULL作成日時
updated_attimestamptzNOT NULL更新日時
deleted_attimestamptz削除日時
カラム名制約説明
iduuidPKスナップショットID
timesheet_iduuidFK (TIMESHEETS.id)勤怠ID
versionintegerNOT NULLバージョン
snapshotjsonbNOT NULLスナッショット
changed_byuuidFK (USERS.id)変更者
change_reasontext変更理由
changed_attimestamptzNOT NULL変更日時
カラム名制約説明
iduuidPKレコードID
timesheet_iduuidFK (TIMESHEETS.id)勤怠ID
payloadjsonbNOT NULLSlackメッセージのペイロード
operationtext(create, update, delete)操作
channel_idtextNOT NULLチャンネルID
message_tstextNOT NULLSlackメッセージのタイムスタンプ
statustext(sent, failed)送信ステータス
attempt_countintegerNOT NULL試行回数
last_errortext最終エラー
last_synced_attimestamptz最終同期日時
created_attimestamptzNOT NULL作成日時
updated_attimestamptzNOT NULL更新日時
idempotency_keytextUNIQUE冪等キー
erDiagram USERS { uuid id PK "supabase auth uid" text email text password } PROJECTS { text code PK text name } TIMESHEETS { uuid id PK date work_date time start_time time end_time text project_code text task text done text not_done text next_action text proper uuid user_id FK timestamptz created_at timestamptz updated_at timestamptz deleted_at } TIMESHEET_REVISIONS { uuid id PK uuid timesheet_id FK integer version jsonb snapshot uuid changed_by FK text change_reason timestamptz changed_at } SLACK_MESSAGES { uuid id PK uuid timesheet_id FK jsonb payload text channel_id text message_ts text status integer attempt_count text last_error timestamptz last_synced_at timestamptz created_at timestamptz updated_at text idempotency_key } USERS ||--o{ TIMESHEETS : has PROJECTS ||--o{ TIMESHEETS : has TIMESHEETS ||--|{ TIMESHEET_REVISIONS : versions TIMESHEETS ||--|| SLACK_MESSAGES : syncs
Mermaidソースコードを表示
erDiagram
USERS {
uuid id PK "supabase auth uid"
text email
text password
}
PROJECTS {
text code PK
text name
}
TIMESHEETS {
uuid id PK
date work_date
time start_time
time end_time
text project_code
text task
text done
text not_done
text next_action
text proper
uuid user_id FK
timestamptz created_at
timestamptz updated_at
timestamptz deleted_at
}
TIMESHEET_REVISIONS {
uuid id PK
uuid timesheet_id FK
integer version
jsonb snapshot
uuid changed_by FK
text change_reason
timestamptz changed_at
}
SLACK_MESSAGES {
uuid id PK
uuid timesheet_id FK
jsonb payload
text channel_id
text message_ts
text status
integer attempt_count
text last_error
timestamptz last_synced_at
timestamptz created_at
timestamptz updated_at
text idempotency_key
}
USERS ||--o{ TIMESHEETS : has
PROJECTS ||--o{ TIMESHEETS : has
TIMESHEETS ||--|{ TIMESHEET_REVISIONS : versions
TIMESHEETS ||--|| SLACK_MESSAGES : syncs
  1. ユーザーがUIから日報を入力
  2. 入力内容はSupabase上のDBで管理しているTIMESHEETSテーブルにINSERT
  3. Slackへの投稿ボタンを押すと、Slack_MESSAGESstatus='sending'でINSERT
  4. SlackAPI chat.postMessageをawait
  • 成功:SLACK_MESSAGESstatus='sent', last_synced_at=now()にUPDATE
  • 失敗:status='failed' / attempt_count++ / last_error=error_msgにUPDATEして、再送を促す
  1. TIMESHEETSをUPDATE(トリガーでTIMESHEET_REVISIONSに旧値が保存)
  2. Slackへの更新ボタンを押すと、SLACK_MESSAGESstatus='sending'にUPDATE / INSERTする。
  • message_tsがあればSlackAPI chat.updateをawaitして編集。
  • なければchat.postMessageをawaitして送信。
  1. TIMESHEETSdeleted_at=now()にUPDATE(トリガーでTIMESHEET_REVISIONSに旧値が保存)

もしSlackにメッセージ送信済みならば、

  1. SLACK_MESSAGESstatus='sending'にUPDATE
  2. SlackAPI chat.deleteをawait
  • 成功: TIMESHEETSを削除する。(Slackでの削除が完了したことを確認してDB削除)
  • 失敗:status='failed', last_errorにUPDATEして、再送を促す

スプシの行数制限の対応について

Section titled “スプシの行数制限の対応について”