MENU

勤怠管理システムを自分たちで作った話

目次

〜チャットでの勤怠報告から卒業して、AIと一緒に初めてのシステム開発〜


はじめに

株式会社ホノカは、岡山でWeb制作・グラフィックデザインを手がける小さな会社です。

社員数は数名。これまで勤怠管理は、正直なところ「なんとなく」で回していました。出勤したらチャットで「出勤しました」と報告、有給を取るときもチャットで連絡。小規模だからこそ、それでもなんとかなっていた部分があります。

でも、スタッフが増えてくると「あれ、今月の残業時間どのくらいだっけ」「有給の残り何日?」という確認が増えてきました。月末にまとめて集計する作業も地味に面倒。そろそろちゃんとしたシステムが必要かも、と思い始めたのが開発のきっかけです。

この記事では、Claudeと一緒にゼロから勤怠管理システムを作った過程を、ハマったことも含めて書いておきます。実は、これがAIと一緒に作った初めてのシステムでした。


なぜ既存サービスを使わなかったのか

freeeやジョブカン、KING OF TIMEなど、勤怠管理のSaaSはたくさんあります。でも、あえて自分で作ることにしたのには理由があります。

自分たちの運用に合わせたかった。

既存サービスは機能が豊富すぎて、うちの規模には持て余す部分が多い。逆に「こうしたい」という細かい要望は対応できないことも多い。

長期的なコスト。

社員数×月額の料金体系だと、長い目で見ればサーバー代だけで済む自社開発の方が安くなる。

税理士事務所との連携。

給与計算は税理士事務所に依頼しているので、勤怠データを自動でメール送信できれば、こちらが介入することなく給与明細まで完結する。ここを自動化したかった。

そして、「AIと一緒にシステムを作る」ということ自体に興味がありました。Web制作の仕事でコードは書いてきましたが、業務システムをゼロから作るのは初めて。Claudeとの対話でどこまでできるか、試してみたかったというのもあります。


作った機能

基本の打刻機能

出勤・退勤・休憩開始・休憩終了のボタンを押すだけ。シンプルな画面を意識しました。

残業時間は自動計算。ただし、0〜10分の残業は0分として扱う(いわゆる「10分切り捨て」)というルールを入れています。これは実際の運用に合わせた仕様です。

有給・欠勤・遅刻・早退の申請

当日だけでなく、事前申請にも対応しています。

有給は「全日」「午前休」「午後休」の3種類から選択可能。申請するとGoogleカレンダーに自動で予定が登録されるので、チームメンバーが休みを把握しやすくなります。

申請の取り消しや編集もできるようにしました。カレンダーの予定も連動して削除・更新されます。

通知機能

Slack・Chatworkへの通知に対応しています。

  • 出勤・退勤したらチャットに通知
  • 有給などの申請があったら通知
  • 22時時点で未入力の人がいたら管理者に通知(Cronで自動実行)

管理者機能

  • 社員の追加・編集・削除
  • 全員の勤怠一覧
  • 申請一覧
  • 日報一覧
  • CSV出力(社員別に残業時間の合計付き)

毎月の自動レポート

20日締めで、前月21日〜当月20日の勤怠データをCSVにまとめて、指定したメールアドレスに自動送信する機能も作りました。毎月21日の朝9時にCronで実行されます。

これが一番作って良かった機能かもしれません。

給与計算は税理士事務所に依頼しているのですが、このCSVが自動で送られることで、こちらが何もしなくても給与計算が進み、給与明細がチャットで届くようになりました。感覚的には給与周りが完全に自動化された感じです。ここは本当に楽になりました。


開発で苦労したこと

Googleカレンダー連携の404エラー

有給申請をGoogleカレンダーに登録する機能を作ったとき、OAuthトークンは取得できているのにカレンダーへの書き込みが404エラーになり続けました。

原因を探ると、**Google Calendar APIがプロジェクトで有効化されていなかった**ことが判明。認証(OAuth)とAPI有効化は別の設定だということを学びました。

さらに、特定のグループカレンダーに書き込もうとすると、また404が出る。CLIから直接叩くとうまくいくのに、Web経由だとダメという謎の状況。最終的には「primary」(メインカレンダー)に書き込む方針に切り替えてスッキリ解決しました。

Cronが動かない問題

月次のCSVメール送信がなぜか届かない問題が発生しました。

ブラウザからテスト用のPHPを叩くと正常に送信される。でもCronからは動かない。

原因を調査すると、PHPのパスが違っていたことが判明。

エックスサーバーでは、Cronで指定する`/usr/bin/php`がPHP 8.2を指しているとは限りません。明示的に`/usr/bin/php8.2`と指定する必要がありました。


# NG

/usr/bin/php /path/to/script.php

# OK

/usr/bin/php8.2 /path/to/script.php

さらに、Cronの実行結果がメールで届いてしまう問題もあったので、出力を捨てる設定を追加。


/usr/bin/php8.2 /path/to/script.php > /dev/null 2>&1

エックスサーバー特有というより、複数のPHPバージョンが共存している共用サーバーでよくある問題だと思います。

休憩ボタンが反応しない

「休憩開始」ボタンを押しても、ボタンの表示が変わらない問題が発生しました。

調べてみると、DBには`break_start`と`break_end`の両方に値が入っている状態でした。休憩開始を押しても、古い`break_end`が残っているため、条件的に「休憩開始」ボタンが表示され続けていたのです。

修正は「休憩開始時に`break_end`をNULLにクリアする」という1行。

$stmt = $this->db->prepare(
'UPDATE attendances SET break_start = ?, break_end = NULL WHERE user_id = ? AND work_date = ?'
);

ロジックの見落としというより、**実際に使ってみて初めて気づくバグ**でした。

ファイルのアップロード忘れ

これは恥ずかしい話ですが、何度かありました。

ローカルでコードを修正して「直った!」と思っても、サーバーにアップロードしていないから当然動かない。「あれ、反映されてない…」と悩んだ末に気づく、というパターンです。

AIと開発していると、コードの生成や修正はスムーズに進むのですが、ファイルをサーバーに上げるという物理的な作業は人間がやる必要があります。ここを忘れると時間を無駄にします。


占い機能を追加した話

勤怠管理システムとしては完成したのですが、ふと「毎朝出勤ボタンを押すのが、ちょっと楽しくなる仕掛けがあってもいいな」と思いました。

そこで追加したのが今日の占い機能です。

出勤ボタンを押すと、AIが「今日の運勢」を生成して表示します。星1〜5個と、一言メッセージ。

🔮 今日の運勢

⭐⭐⭐⭐☆

「午後から運気上昇!大事な仕事は午後に回そう」

技術的にはClaude APIを呼び出して、JSON形式で占いを生成させています。1日1回だけ生成して、その日はずっと同じ内容を表示する仕様です(DBに保存して使い回し)。

占い1回あたりのAPI料金は約0.1〜0.3円。社員数人で毎日使っても月数十円程度です。

最初は「試用クレジットがあるから大丈夫」と思っていたのですが、いざ動かそうとしたらクレジットが切れていて動かない、ということがありました。Anthropic Consoleでクレジットを追加購入して解決しています。


やらなかったこと

機能を詰め込みすぎず、シンプルに保つことを意識しました。

時間休の申請機能は見送りました。実装しようとすると「何時間単位?」「1日の上限は?」「有給残日数との関係は?」など考えることが多く、現状の規模では半休(午前休・午後休)で十分運用できると判断しました。時間休が必要な場合は「遅刻」「早退」で申請して、備考欄に「時間休:10:00-12:00」と書く運用でカバーしています。

承認ワークフローも今は不要と判断しました。社員数が少ないので、申請したら即確定で問題ない。将来的に人数が増えたら追加を検討します。

有給残日数の自動管理も見送り。年度初めに付与日数を設定して、消化するたびに自動で減っていく…という機能は便利ですが、今は手動管理で十分。ここも将来の拡張候補です。

給与計算機能も作りませんでした。所得税・住民税・社会保険など、計算ルールが複雑で毎年変わる。間違えると労基署や年金事務所から指摘が来るリスクもある。ここは税理士事務所にお任せする方が安全で安い、という判断です。


技術スタック

  • PHP 8.2(フレームワークなし)
  • MySQL(MariaDB)
  • エックスサーバー
  • Vanilla JavaScript(ReactやVueは使わず)
  • 外部連携:Slack、Chatwork、Googleカレンダー、Claude API

フレームワークを使わなかったのは、AIと一緒にコードを生成・修正していくときに、フレームワークの複雑さがノイズになると判断したからです。シンプルなPHPの方が、Claudeとの対話でコードを書き進めやすかった。


振り返り

これがAIと一緒に作った初めてのシステムでしたが、想像以上にスムーズに進みました。

AIとの開発で変わったこと

– 仕様を言語化する力が上がった。「こんな感じで」ではなく「○○の場合は△△する」と具体的に伝える習慣がついた

– 「この機能は必要か?」をAIと壁打ちすることで、判断が速くなった

– PHPやJSを自分で書かなくても、仕様を伝えることでシステムが完成した

自社開発のメリット

  • 自分たちの運用にぴったり合わせられる
  • – 機能を自由に追加・変更できる
  • – データを自社で管理できる
  • – 税理士事務所への自動連携で、給与計算まで自動化できた
  • – 長期的にはSaaSより安い

自社開発のデメリット

  • 初期の開発時間がかかる
  • バグ対応や保守が必要
  • AIなしでは正直難しかった

この勤怠管理システムがうまくいったことで、その後タスク管理システム(HONOKA Tasks)、在庫管理・会計システムと、次々に社内ツールを作っていくことになりました。最初の成功体験が大きかったと思います。


今後の展望

今のところ十分に使えていますが、追加したい機能もあります。

  • 有給残日数管理:年度初めに付与して、消化ごとに自動減算
  • 残業アラート:月45時間を超えそうなら警告
  • 勤務時間グラフ:月別の勤務状況を可視化

ただ、「あったらいいな」と「今必要」は違うので、実際に困ってから追加していく方針です。


おわりに

勤怠管理システムは、業務システムの中では比較的シンプルな部類だと思います。出勤・退勤を記録して、月末に集計する。基本はそれだけです。

でも、自分たちの運用に合わせて細かいルール(10分切り捨て、20日締め、Googleカレンダー連携、税理士への自動送信など)を組み込めるのは、自社開発ならではの強みでした。

AIがあれば、非エンジニアでも社内ツールを自分で作れる時代になったと実感しています。

タスク管理ツールやSEO保守ツール、会計まわりのシステムも、実はこの勤怠管理システムの成功体験があったからこそ広げていけました。よければそちらの記事も読んでみてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次