はじめに
- タイトルには「勤怠集計自動化」と記載しましたが、「勤怠入力の乖離状況チェック作業の自動化」です
- ざっくりとした説明になりますが、勤怠管理に利用しているラクローというSaaSで入力された「客観的記録(PCのログオンのログ)」と「自己申告記録」との入力時間の乖離状況を四半期ごとに確認するというものです
- 目的としては「従業員の健康を守ったり健全な業務環境の推進をしたりするため、意図しない残業等が発生していないかを確認する」というものです💪
ラクローについて
「ラクロー(Rakuro)」とは、PCのログオン・ログオフ時間などのデジタルデータ(PCログ)を基に、従業員の労働時間を自動で記録する「打刻レス」な 勤怠管理サービスです

これまでの課題
- 人事総務チームの担当メンバー(1~2名ほど)が全社員の勤怠入力結果をブラウザの管理画面から目視でチェックしていました
- 担当メンバーは作業に慣れているとはいえ、工数にすると2~3人日程度はかかってしまうそうです(他の差込みタスクもあるので、タスクスイッチコストも発生)
2025年現在の社員数は170名前後ですが、順調に仲間も増え続けているので、このままでは特定のチームの負担が増えると予想されます
事前調査
- 当初は「ラクローが提供しているAPIから簡単にデータを取ってこれるので、スプシでGAS(Google App Script)を動かせば自動化できるのではないか」と考え、まずはそこから試してみたのですが、以下の壁にぶつかりました
- 第1の壁
- 💻 ラクローのAPIで取得できる客観的記録(PCのログオン時間のログ)が日付区切りで整形されていないので、自分たちで整形してから集計実装を組まないといけない
- 第2の壁
- ⏳ 集計機能を実装しても、GASのタイムアウト以内に全処理を終えることができない
- 全従業員の3ヶ月分の集計だと普通に実行してもそこそこな時間がかかる
- ⏳ 集計機能を実装しても、GASのタイムアウト以内に全処理を終えることができない
- 第3の壁
- 🕒 集計を並列化して高速に処理しようとしても、ラクローAPIのレートリミット(毎分120リクエスト) に当たってしまい結局sleep処理が必要になる
- 第1の壁
まとめると、実装のロジックはある程度イメージができたものの、プログラムの実行時間制約によってGASやAWS Lambdaでは難しいということがわかりました。(※ この時はまだLambdaのマネージドインスタンスが無かったため)
解決手法
- 今回は「ECS on Fargete」での四半期バッチ処理としてアプリケーションを用意する方針となりました
- 集計結果は人事総務チームでも簡単に確認できるように、Googleドライブにスプレッドシートとして書き出すようにしました
- Googleドライブの権限設定で、アクセス可能な社員を絞っています
アーキテクチャ・設計詳細
システム概要
- 4半期ごと(3,6,9,12月)の20日にEventBridge SchedulerからECSタスクを起動します
- ECSタスクはラクローのAPIを叩きながら集計処理を進めていきます
- GCPのAPIの認証を経て、会社の特定のGoogle Driveのフォルダに集計結果のスプレッドシートを作成します
- 下の図にはないですが、作成したスプシのリンクをSlackに通知してタスク終了です
アプリケーション概要
どのようにデータが整形・集計されているかを区切りごとに確認しながら開発する都合で、DynamoDBのテーブルをこまめに分けるという実装になりました
Users,PCLogs,SelfReportedLogsはラクローから取得した情報を整形して格納するテーブルです- 上記のテーブルの情報をユーザーと日付毎に結合したものが
MergedLogsテーブルで、その中からヒアリング対象のものだけ抜き出したのがFilteredLogsです - それらをスプシ反映用に再集計したり加工したものが
MonthlySummaryとForSpreadsheetsです
👍全て通しで実行するととても時間がかかるため、処理の途中経過をテーブル毎に都度確認できる設計にしたことで効率的に開発ができました
DynamoDBをサイドカー構成としたのは「管理者とはいえ全従業員の勤怠情報を簡単に見れる状態にはしたくない(ので、アプリの実行に合わせて作成・削除する)」という理由です
スプシに書き出される内容(例)
MonthlySummaryの例- ビットバンクは11日~翌月10日が勤怠締めなので、12月のチェックの時は以下の区切りで集計します
- 9月11日 ~ 10月10日
- 10月11日 ~ 11月10日
- 11月11日 ~ 12月10日
- 各期間で、何日分ヒアリング候補として集計されたかを↓のように確認できます
- ※ユーザー名・日時・数値はすべてダミーデータです
- ビットバンクは11日~翌月10日が勤怠締めなので、12月のチェックの時は以下の区切りで集計します

ForSpreadsheetsの例MonthlySummaryに集計する対象となった勤怠のレコードを1日分ずつ詳細を確認できるようになっています (一部のカラムを抜粋)- ※ユーザー名・日時・数値はすべてダミーデータです
- ここを見ながら人事総務チームのメンバーが「この方にはヒアリングした方が良さそうだな」「これはヒアリング対象外だな」というのを判断しています (ここは柔軟に判断する必要があり、システム化は不要という判断になりました)
- たまにラクローのシステムの誤検知の場合もあるので、勤怠のコメントの確認もこのタイミングで行っています

感想
客観的記録ログが日付区切りではなく、処理が大変だった
- 自己申告ログ(
SelfReportedLogs)のログは以下のように、あらかじめ日付区切りのデータのリストを取得することができるので、データの挿入は簡単です (一部抜粋)- ※ user_idは実在しない架空IDです
{
"user_id": 99999, # ユーザーID
"date": "2025/07/01", # 日付
"start_at_text": "08:38", # 自己申告の業務開始時刻
"end_at_text": "19:05", # 自己申告の業務終了時刻
"break_time_1_start_at_text": "14:00", # 自己申告の休憩開始時刻
"break_time_1_end_at_text": "15:00", # 自己申告の休憩終了時刻
},
- 一方で客観的ログ(
PCLogs)は以下のように、PCのログオン~ログオフの区切りで、日付関係なく断続的に渡ってきます(一部抜粋)- ※ user_idは実在しない架空IDです
- PCがスクリーンセーバーやスリープ状態になったらログオフ判定になるので、席を離れたり休憩に入ったりする度にログのデータが分割されます
- また、日付が変わっても勝手にそこで区切れたりはしないので、たまにバグが起きて前日の20時から翌日の朝9時までずっとログオン判定で記録されていることもありました
{
"user_id": 99999, # ユーザーID
"started_at": "2025-07-01T08:38:00.000+09:00", # ログオン時刻
"ended_at": "2025-07-01T08:52:00.000+09:00" # ログオフ時刻
},
{
"user_id": 99999, # ユーザーID
"started_at": "2025-07-01T08:53:00.000+09:00", # ログオン時刻
"ended_at": "2025-07-01T09:06:21.000+09:00" # ログオフ時刻
},
{
"user_id": 99999, # ユーザーID
"started_at": "2025-07-01T09:09:30.000+09:00", # ログオン時刻
"ended_at": "2025-07-01T12:18:10.000+09:00" # ログオフ時刻
},
これを毎日特定の時間を基準にして日付毎に集計しなおす処理が、今回一番複雑になった部分です
フルスタック技術が求められていい経験になった
- 今回のプロジェクトでは用件定義・アーキテクチャ設計からアプリ実装まで一貫して担当することになり、想像していた以上に「最初の設計イメージ」が後工程に効いてくる場面が多かった気がします
- 実装中に修正するよりも、要件整理や構成を考えている段階でどれだけ詰められるかが、最終的な作業量や安心感に直結することを実感しました
- 👍 結果的に、システム全体を前提にした設計や実装を考える良い経験になったと思います!
さいごに
- 今回の作業をきっかけに人事総務チームで他にどんなことを効率化したいかなどをお聞きする機会があり、まだまだ効率化したい・効率化できそうという作業は多々あることがわかりました
- 他の多くの企業でも、コーポレートの業務改善や効率化は進めたいと思っても「SaaSを導入」や「スプシなどで工夫」で止まってしまっていて、日常的なルーティーンワークは減らない...というパターンはあるのではないでしょうか
- きっと様々な事情もあってコーポレート専門のDXエンジニアを雇用するというのもハードルが高いのではないかと想像しています
- しかし、今回のようなきっかけとなる取り組みで「これだけの工数削減につながった!」などの実績が出れば何かが動き出すかもしれません!!
- 社内のエンジニアに雑談という感じで「効率化できそうか」のアイデアを聞いてみるのもありかもしれません (今回の取り組みも、元は情シスに寄せられていた相談がきっかけでした)

長くなりましたが、読んでくださった方のご参考になれば幸いです。お読みいただきありがとうございました。

