請求書類が本当にその書類かを確かめる
目標
請求の種類別の必須書類をルール表で点検し、ファイル形式をマジックバイトで判定し、内容ハッシュで使い回された書類を見つけ出し、ファイル名の個人情報と提出期限と孤立ファイルまで調べて、請求ごとの補完依頼の一覧を出します。
なぜ重要なのか
書類は支払判断の根拠ですが、そのファイルが本当にその書類なのかは、ファイル名では教えてくれません。スキャナーが作った画像にpdf拡張子が付き、同じ領収書が名前だけ変わって2つの請求に使われます。 受付時点の自動点検は安価で、支払いのあとに見つけるのは非常に高くつきます。必要なのは、ルール表1つとファイルの先頭の数バイト、そしてハッシュだけです。 この受付箱のファイルには、NULバイトが混ざっています。grepを使うと、何も見つからないか、バイナリファイルだという言葉だけが返ってきます。odで見るか、Pythonでバイトとして読んでください。
ステップ
- 素材スクリプトを**/root/docs/gen_docs.py** として保存して実行し、/root/docs/claims.db と**/root/docs/inbox** を作ります。
- ルール表と受付記録を突き合わせて、欠けた書類を**/root/docs/missing.txt** に書きます。
- /root/docs/sniff.py で形式を判定し、受付箱全体の判定表を**/root/docs/filetypes.tsv** に出します。
- 内容ハッシュで使い回された書類をまとめて、/root/docs/reuse.txt に書きます。
- ファイル名に載ってきた個人情報を数えて、/root/docs/namescan.txt に書きます。
- 提出期限を事故日から計算して、/root/docs/overdue.txt に書きます。
- 記録と実物を双方向で突き合わせて、/root/docs/orphans.txt に書きます。
- 請求ごとの補完依頼の一覧を**/root/docs/followup.json** に、報告書を**/root/docs/docs_report.md** に出します。
参考
- 形式名は、pdf、png、jpg、zip、unknownの5つだけを使います。sniff.pyは、ファイルパスを1つ引数に受け取り、形式名を1行出します。
- filetypes.tsvは、1ファイルに1行で、タブで区切られた3つの欄です: ファイル名、拡張子(名前から取り出した小文字)、判定した形式。
- 提出期限は、事故日から30日です。これはこのラボの仮定であり、法定期限ではありません。期限が過ぎたかどうかは、2026-09-17を今日として数えます。
- ファイル名の個人情報の判定ルール: ハングル2文字から4文字が含まれていれば名前、6桁にハイフンが付いて7桁の数字の形なら番号とみなします。
- sqlite3は
sqlite3 -readonly /root/docs/claims.db "SELECT ..."で接続します。受付箱はod -c /root/docs/inbox/K0001_claim_form.pdf | head -2で覗いてみます。 - よくある間違いは、拡張子で形式を判定すること、期限の起算日を受付日にすること、記録と実物を片方向にしか突き合わせないこと、報告書に個人情報の値をそのまま書き写すことです。
請求表と受付箱を作る
素材スクリプトを**/root/docs/gen_docs.py** として保存して実行し、/root/docs/claims.db と**/root/docs/inbox** を作ってください。
まず/root/docsを作って、その中でpython3で実行します。表はclaim、doc_rule、submissionの3つで、受付箱にはファイル189個ができます。作られたファイルは直さないでください。
種類別の必須書類チェックリストを回す
ルール表と受付記録を突き合わせて、/root/docs/missing.txt にincomplete_claims・missing_docs・missing_inj・missing_ill・missing_medを書いてください。
doc_ruleは、請求の種類ごとに必要な書類の種別を持っています。請求ごとに、その集合からsubmissionにある種別を引くと、欠けたものが残ります。種類別の数は、欠けた書類がある請求を種類で分けて数えた値です。
拡張子ではなく先頭のバイトで形式を見分ける
/root/docs/sniff.py を作成し、受付箱全体の判定表を**/root/docs/filetypes.tsv** に出してください。
PDFは%PDF-、PNGは10進数で137 80 78 71 13 10 26 10、JPEGはFF D8 FF、ZIPはPK 03 04で始まります。どれにも当てはまらなければunknownです。ファイルは必ずバイトで開いてください。表は、ファイル名、拡張子、判定の3つの欄をタブで区切ります。
同じ書類が使い回された場所を見つける
内容ハッシュで同じファイルをまとめて、/root/docs/reuse.txt にreused_groups・reused_files・affected_claimsを書いてください。
ファイル名はいくらでも変えられるので、sha256でまとめます。2個以上の塊だけを数えます。引っかかった請求数は、submissionのfilenameでたどって、異なるclaim_idを数えた値です。
ファイル名に載ってきた個人情報を数える
/root/docs/namescan.txt にname_in_filename・rrn_in_filename・flagged_filesを書いてください。
内容をいくらうまく隠しても、ファイル名は、一覧画面やバックアップの索引、エラーログにそのまま残ります。ハングル2文字から4文字が含まれていれば名前、6桁にハイフンが付いて7桁の数字の形なら番号です。flagged_filesは、どちらか一方でも引っかかったファイルの数です。
期限を事故日から数える
/root/docs/overdue.txt にlate_docs・late_claims・overdue_missingを書いてください。
起算日は受付日ではなく、事故日です。事故日から30日を超えて提出された書類を数え、そうした書類が1つでもある請求を数えます。overdue_missingは、欠けた書類があり、かつ期限が2026-09-17以前に過ぎた請求の数です。
記録と実物を双方向で突き合わせる
/root/docs/orphans.txt にorphan_files・missing_files・claims_with_missing_fileを書いてください。
受付箱にしかないファイルと、記録にしかないファイルは、別の事故です。前者は誰のものかわからない個人情報が残っている状態で、後者は支払いの根拠が空の状態です。2つの集合の差集合を、両方向で求めてください。
請求ごとの補完依頼の一覧を出す
/root/docs/followup.json に請求ごとのmissing・no_file・reused・type_mismatchを入れ、/root/docs/docs_report.md に5つの節の報告書を書いてください。
4つの理由を、1つの請求の中で分けて書きます。理由が1つもない請求は、一覧に入れません。ファイルの一覧は、ソートして入れてください。報告書の節の見出しは、確認したこと、欠けた書類、形式と再利用、ファイル名の個人情報、勧告です。報告書には、個人情報の値を書き写さないでください。