TL;DR
監査法人の工数管理で大事なのは、タイマーではありません。2つのことです。誰がどのクライアントの工数を見られるか、そしてレポートの合計が正しいか。ある監査法人のために工数管理アプリを構築する中で、どの画面にも表れない4つのミスを見つけました。気づかないうちに低く出てしまうレポートの合計、何も保存されていないのに「保存しました」と表示する約30の操作、レポートやタグの件数から存在が漏れる機密クライアント、そして後の承認で隠れてしまう却下済みのエントリです。どれも、購入したツールでも自作のツールでも、数分あれば確認できます。
Denysです。フルスタック・AIエンジニアです。2026年5月から10月にかけて、ある監査法人は、誰もがすべてのクライアントを開けるツールから、その法人のためだけに私が388コミットで構築したアプリへ移行しました。法人名はここでは伏せます。この記事は、法人を運営し、ツールを選ぶ立場の方に向けたものです。監査法人が工数管理に求めること、見つけた4つのミス、そしてどのツールでもそれを確認する方法を紹介します。
監査法人は工数管理に何を求めるのか?
監査法人が売っているのは時間です。工数管理は、事業全体が拠って立つ記録になります。私が構築した法人に必要だったのは次のものです。
- クライアント・プロジェクト・タスクごとの工数。 すべてのエントリは1つの契約に属するため、工数をクライアント別、プロジェクト別、個人別に見られます。
- 承認つきの週次タイムシート。 スタッフが1週間分を提出し、プロジェクト管理者が各エントリを承認または却下します。カウントされるのは承認済みの工数だけです。
- リマインダー。 期限までにタイムシートが空のままの人には、メールが届きます。2026年9月以降は、未入力の工数についてのみ通知し、稼働可能時間がゼロの人は対象外です。
- リソース配分。 今後数週間、誰がどの契約に就くかを、各人の稼働可能時間と照らして管理します。
- 機密クライアント。 オーナーは、クライアントとそのプロジェクト、タスク、工数を、選んだメンバーだけに制限できます。
- 削除せず、アーカイブする。 退職したメンバーは無効化して匿名化し、終了したプロジェクトはアーカイブして、タイムシートの履歴をそのまま残します。
請求書は発行しません。プロジェクトの請求形態と工数予算は別の権限の背後にあり、請求は法人の会計システムで行います。
監査法人では、誰が誰の工数を見られるべきか?
このプロジェクトの前は、法人の全員がすべてのクライアントと全員の工数を開けました。監査法人にとってこれは、ソフトウェアの問題である前に守秘義務の問題です。すべてのメンバーがすべてのクライアントを見る必要はなく、同僚の1週間は、承認する立場でなければ誰も見る必要がありません。
法人が確認したアクセスモデルは次のとおりです。
| ロール | 見られる範囲 | 承認できる範囲 |
|---|---|---|
| スタッフ | 自分の工数のみ | なし |
| プロジェクト管理者 | 自分のプロジェクトのチームの工数 | そのプロジェクトでのチームの週 |
| オーナー | すべてのクライアント、プロジェクト、人 | すべて |
| 機密クライアント | オーナーが選んだメンバーにのみ見える | — |
オーナーは、領域と操作を組み合わせたチェックボックスのマトリクスで各ロールを調整します。すべてのルールは画面ではなくデータベースにあるため、データベースが拒否するものを画面が表示することはありません。各チェックボックスは、リリース前に本番のコピーでテストしました。その方法と見つかったことは、Supabase RLSのテストにまとめています。
マトリクスでは答えられなかった問いが、法人自身から出ました。2026年6月、最も権限の限られたロールのメンバーが、配分画面に他のメンバーとそのプロジェクトが表示されることに気づきました。本人は、自分自身と同僚1人だけが見えるはずだと考えていました。制限付きのメンバーは、自分のプロジェクトにいる人を見てよいのか。決まったルールは、見てよい。ただし共有しているプロジェクトに限り、他の人の稼働可能時間と休暇は隠す、というものです。
法人が本当に納得するアクセスモデルは、どうすれば得られるのか。クライアントに記憶から説明してもらうことはしませんでした。9つのセクション、72の質問からなるアンケートを送り、権限のグリッドには、2026年8月7日時点で稼働中のシステムが実際にそうなっていた状態で、あらかじめチェックを入れておきました。クライアントは間違っている箇所を直し、変更されたセルにはすべて印をつけました。人は、現実を説明するより、現実を直すほうが得意です。
ミス1:レポートの合計が低く出るはずだった
タイムシートのページには、法人全体の「今四半期」と「年初来」のビューがあります。これらは、範囲内のすべての工数エントリを1回のリクエストで読み込んでいました。アプリの裏にあるデータベースAPIは、1リクエストあたり最大1,000行を返し、1,000行で止まってもエラーは出しません。最初の1,000行を返すだけです。
Supabaseはこの既定値を文書化しています。API設定で上限を変えない限り、プロジェクトが返す行は最大1,000行です。
そのため、ある範囲のエントリが1,000件を超えると、メンバーや週がビューから落ち、画面には何も表示されないまま合計が低く出ることになります。週に約70件のペースでは、年初来ビューは2026年11月中旬ごろに1,000件を超える見込みでした。2026年9月24日のコード監査で、それが起きる前に見つかりました。修正は、すべての範囲をページごとに読み込む方式で、レポートのエクスポートもすべて同じようにページ分割で読み込みます。
自分のツールを確認する方法: 長い期間を選び、生のエントリをエクスポートして、自分で合計し、レポートの合計と比べます。両者が違えば、レポートは行を切り捨てています。
ミス2:何も保存されていないのに「保存しました」
権限が理由で、あるいはルールが二要素のサインインを求めているためにデータベースが変更を拒否した場合、エラーなしで「0行変更」と答えることがあります。レコードを更新または削除するアプリの約30か所は、この答えを成功と読み取り、「保存しました」と表示していました。本人は次に進みます。変更は一度も行われていません。
修正は、失敗側に倒すことです。1行も触れていない書き込みはエラーとして扱い、エラーとして表示します。そして今は、すべての書き込み経路がそう扱うことをテストで確認しています。
自分のツールを確認する方法: 編集する権利のないメンバーとしてサインインし、編集を試みて、ページを再読み込みします。「保存しました」と表示されたのに古い値に戻っていたら、そのツールは保存について嘘をついています。
ミス3:機密クライアントがレポートから漏れた
契約によっては、関わる人だけが知っているものがあります。2026年8月24日から、オーナーはクライアントを指名したメンバーに限定できるようになりました。それ以外の人には、そのクライアントも、プロジェクトも、タスクも、工数も何も返りません。オーナーは常にアクセスでき、そのアクセスは現在オーナーのロールを持つ人から都度計算され、保存はされないため、ロールが移れば一緒に移ります。
クライアント一覧から隠すのは簡単な部分でした。漏れは、横の入り口にありました。2026年9月8日のレビューで、次のことが見つかりました。
- 3つのレポート関数が制限を無視していました。 通常のアクセスルールを飛ばす権限で動いていたため、機密クライアントの工数がレポートに現れる可能性がありました。
- 管理画面のタグ概要の使用件数が、機密クライアントのプロジェクトとタスクを数えていました。契約が存在すること、そしておおよその規模が分かってしまいます。
- エラーメッセージで違いが分かりました。 実在するが隠されたレコードの変更を試すと「forbidden」、でっち上げのレコードを試すと「not found」が返り、誰でも機密クライアントの存在を探れました。
3つとも、メインのテーブルと同じチェックを適用するようにし、隠されたレコードは、存在しないレコードとまったく同じに見えます。機密クライアントからプロジェクトやエントリを移動するには、オーナーか専用の権限も必要で、すべての移動が記録されます。
自分のツールを確認する方法: 1人だけにクライアントを制限します。そのうえで別の人として、すべてのレポートを実行し、すべての件数とフィルターを確認し、クライアント名を検索し、そのプロジェクトの1つへの直接リンクを開きます。エラーメッセージも含めて、痕跡は何も見つからないはずです。
ミス4:後の承認で却下が隠れることがあった
1週間には複数のプロジェクトのエントリがあり得るため、承認者も複数います。あるプロジェクト管理者がエントリを却下し、別の管理者が後から自分の担当分を承認すると、後の承認が週全体を確定させて、却下を覆い隠すことがありました。エントリをタスク間で移動したり、週を再オープンしたりしても、同じように隠れることがありました。
2026年9月24日に承認ロジックを変更しました。有効な却下済みエントリが残っている間は、その週は却下のままです。また、プロジェクト管理者が却下済みエントリをアーカイブできるのは、自分が却下した場合だけです。今は、データベースのプローブがこれらのケースをそれぞれ実行し、すべてでPASSと表示されなければなりません。
自分のツールを確認する方法: 1つの週に承認者を2人用意します。1人目として1つのエントリを却下し、2人目としてそれ以外をすべて承認して、週がどの状態で終わるかを見ます。
監査法人の工数管理は、買うか作るか?
まずは買いましょう。Toggl、BigTime、ZenWorkflowなどのツールは、タイマー、週次承認、クライアントへの請求をすでにカバーしていて、今週から使い始められます。自作が意味を持つのは、製品では表現できないルールが法人にある場合です。たとえば、指名したメンバーにだけ見える機密クライアント、1週間に複数のプロジェクト管理者が承認する仕組み、オーナーがチェックボックス単位で形を決めたいロールなどです。
どちらを選んでも、上の4つの確認は午後1回あれば終わり、機能の一覧より多くのことが分かります。製品ページはどれも「きめ細かな権限」と謳っています。チェックボックスを外したときに何が起きるかを見せるところは、ほとんどありません。
このレポートの限界
- 1つの法人だけ。 アクセスモデル、週に約70件というボリューム、アンケートは、1つの法人のものです。
- ミス1は、発生する前に見つかりました。 11月中旬という日付は、法人のエントリ数のペースからの予測であり、実際に起きた事故ではありません。
- 請求書の発行はなし。 このアプリは工数、請求形態、工数予算を保持しますが、クライアントへの請求は行わないため、工数から請求までの流れについては語れません。
ここでのアクセスルールは、PostgresのRow Level Securityです。ロールのマトリクスでは見つからない2つの抜け穴は、別記事にまとめています。2つの組織に属するユーザーと、NULLで通り抜けてしまうIFです。構築そのものは監査法人の工数管理の事例にあり、この種の仕事は社内ツールとダッシュボードに当たります。