システムコンポーネントの構成
本システムは「ファイル監視モジュール(Python)」と「Web インターフェース(Node.js + React)」の 2 つのプロセスで構成されています。それぞれ独立して動作し、SQLite データベースを介してデータを共有します。
PDF / TIFF
AI解析・DB登録
| コンポーネント | ディレクトリ | 役割 |
|---|---|---|
| ファイル監視モジュール | monitor/ |
受信フォルダの新規ファイルを検知し、Google Gemini API で AI 解析・分類して SQLite DB に登録する |
| Web アプリケーションサーバー | web/server/ |
SQLite DB を参照する REST API を提供する(Node.js + Express) |
| フロントエンド SPA | web/src/ |
ブラウザで動作する文書一覧・検索・詳細閲覧 UI(React + TypeScript + Tailwind CSS) |
| データベース | data/(設定で変更可) |
SQLite ファイル。文書メタデータ・AI解析結果・ユーザー情報を保持する |
| プラグイン | plugins/docTypeHandlers/ |
文書タイプ別の後処理ハンドラー(拡張用) |
開発言語・フレームワーク
サーバーサイドはオープンソース技術のみで構成されており、ライセンス費用はかかりません。
ファイル監視モジュール(monitor/)
| 言語 / 技術 | 用途・説明 |
|---|---|
| Python 3.10+ | メイン実行言語。ファイル監視ループ・AI 呼び出し・DB 書き込みをすべて Python で実装 |
| Google Gemini API | FAX 画像の OCR 相当処理および文書分類(JSON 応答スキーマ使用) |
| SQLite(標準ライブラリ) | 解析済みデータの永続化。Python 標準の sqlite3 モジュールを使用 |
| systemd service | Linux でのデーモン化。yokinsoft-paperless-monitor.service.sample を収録 |
Web インターフェース(web/)
| 言語 / 技術 | 用途・説明 |
|---|---|
| Node.js 18+ | API サーバー (Express) およびビルドツール (Vite) のランタイム |
| TypeScript | フロントエンド全体の型安全な実装 |
| React 18 | SPA フレームワーク。ページルーティングに React Router v6 を使用 |
| Tailwind CSS v4 | UI スタイリング。カスタムコンポーネントへの utility-first CSS |
| Express.js | REST API サーバー (server/index.mjs)。フロントエンドの静的ファイル配信も兼ねる |
| Vite | フロントエンドバンドラ・開発サーバー |
| better-sqlite3 | Node.js から SQLite DB を同期的に読み書きする高速 C++ バインディング |
依存ライブラリ一覧
主要な依存ライブラリをまとめます。各バージョン表記はリリース時点の推奨バージョンです。
Python ライブラリ(monitor/requirements.txt)
poppler 等の外部バイナリ不要で、pip install PyMuPDF 単体で完結する。Node.js ライブラリ(web/package.json)
/documents・/documents/:id・/admin 等)。ファイル監視の仕組み
monitor/monitor.py は起動し続け、指定フォルダに新しいファイルが作成されると即座に処理を開始します。以下にその動作フローを示します。
-
フォルダ監視の開始
起動時に
watchdogライブラリでフォルダの監視を開始します。watchdogは OS のファイルシステムイベントを抽象化するライブラリで、プラットフォームごとに適切なバックエンドを自動選択します。ただしネットワーク共有(NFS / Samba)では OS イベントが利用できないため、PollingObserver(定期ポーリング)への切り替えが必要です。 -
ファイル作成イベントの受信
on_createdイベントが発火します。対象は PDF または TIFF(設定で変更可)のみ。一時ファイル(.tmp・.part等)はスキップされます。 -
書き込み完了の待機
FAX サーバーがファイルを書き込み中の状態で処理を開始すると破損ファイルを読み込む可能性があります。ファイルサイズの変化がなくなるまで短い間隔でポーリングし、書き込み完了を確認してから次ステップへ進みます。
-
重複チェック
同じファイルパスが既に DB に登録されているかを確認します。再起動時や意図しない二重処理を防ぎます。
-
AI 解析(Google Gemini API 呼び出し)
PDF/TIFF をページ画像に変換し、Google Gemini API に送信。文書タイトル・送信者名・送信者組織・受信者・文書タイプ・信頼度などを含む JSON を受け取ります。
-
サムネイル生成
1 ページ目の画像から JPEG サムネイルを生成し、Base64 エンコードして DB に保存します。フロントエンドの文書詳細画面の原本プレビューに使用されます。
-
DB 登録
AI 解析結果・メタデータ・ファイルパス・受信日時を SQLite DB に INSERT します。Node.js API サーバーはこの DB を参照するだけのため、監視モジュールと Web サーバー間の直接通信は不要です。
スキャン一括処理:--scandir オプションでフォルダ内の既存ファイルを一括処理できます。導入初期に既存 FAX を一括登録する場合に便利です。
ファイル検知に関するトラブルと対処
ファイル監視は OS・ファイルシステム・ネットワーク共有など環境依存の要素が多く、さまざまな問題が発生しやすい箇所です。代表的なトラブルと原因・対処法をまとめます。
| 症状 | 原因と対処 |
|---|---|
| 新規ファイルを置いても何も起きない |
① 監視プロセスが起動していないps aux | grep monitor.py(Linux)または タスクマネージャー(Windows)でプロセスを確認。② 監視フォルダのパスが間違っている 設定ファイルの MONITOR_DIR(.env)の絶対パスを再確認。③ ファイル拡張子が対象外 デフォルトでは .pdf と .tif/.tiff のみ。FAX サーバーが出力する拡張子を確認し、必要なら設定を変更。
|
| NFS / Samba 共有フォルダで検知されない |
ネットワーク共有ファイルシステムでは OS のファイルシステムイベントが発火しない NFS・Samba マウントでは OS のファイルシステムイベントが利用できません。 watchdog を ポーリングモード(PollingObserver)で使用するように設定を変更するか、FAX サーバーと Paperless サーバーを同一マシンにする、または rsync / scp で定期コピーする構成を検討してください。
|
| ファイルが壊れた状態で登録される |
FAX サーバーの書き込みが完了する前に処理が始まった 大きな PDF ファイルでは書き込みに数秒かかることがあります。監視スクリプトの「書き込み完了待機」タイムアウト値( WRITE_WAIT_SECONDS)を長めに設定してください。
|
| 同じ文書が二重登録される |
① FAX サーバーがファイルを移動・コピーしている ファイルを別ディレクトリにコピーした後に削除する仕組みのFAXサーバーでは、コピー先+コピー元で 2 回イベントが発生することがあります。 ② 監視プロセスを再起動した 再起動時の既存ファイルの再処理を防ぐため、DB に登録済みのパスのスキップ処理が実装されていますが、パスが変わった場合はスキップされません。 |
| AI 解析がタイムアウトする |
Google Gemini API への通信が遅い・失敗している インターネット接続やプロキシ設定を確認。ページ数の多い PDF(10 ページ以上)では処理時間が長くなります。 API_TIMEOUT_SECONDS を増やすか、先頭数ページのみ送信する設定を検討してください。
|
| AI 解析は成功するが分類が「未分類」になる |
① 文書クラスの定義がない・一致しない 管理画面から文書クラス(文書タイプ)を追加してください。AI はここで定義したクラスに基づいて分類を試みます。 ② FAX 画像の品質が低い 手書き・かすれた文字は AI の認識精度が下がります。FAX 受信解像度(DPI)設定を高めるか、FAX 機器の調整を検討してください。 |
| PDF / TIFF が処理されない |
PyMuPDF のインストール不足またはバージョン不足pip show PyMuPDF でインストールを確認してください。バージョンが古い場合は pip install --upgrade PyMuPDF で更新してください。外部バイナリは不要です。
|
| Windows でモニターが突然停止する |
ReadDirectoryChangesW のバッファ溢れ 短時間に大量のファイルが作成されると Windows のイベントバッファが溢れることがあります。 watchdog の設定でバッファサイズを大きくするか、処理間隔を設けてください。Windowsサービスとして登録する場合は再起動ポリシーを設定することも推奨します。
|
| ログに permissionerror が出る |
実行ユーザーに監視フォルダへの読み取り権限がない FAX サーバーが保存したファイルのオーナー・パーミッションが monitor.py の実行ユーザーと異なる場合に発生します。chmod / chown でパーミッションを調整するか、FAX サーバーと同一ユーザーで実行してください。
|
ログの確認方法:トラブル時はまずモニタープロセスの標準出力・エラー出力を確認してください。systemd で動かしている場合は journalctl -u yokinsoft-paperless-monitor -f でリアルタイムログを確認できます。
データベース構造の概要
SQLite ファイルをデータストアとして使用します。外部 DB サーバーは不要で、シングルファイルなのでバックアップも容易です。
| テーブル | 概要 |
|---|---|
Documents |
受信 FAX 1 件ごとのレコード。タイトル・送信者・送信者組織・受信者・受信日時・ファイルパス・文書クラス・既読フラグ・AI 解析 JSON(DocumentData)などを保持する |
DocumentClasses |
文書タイプの定義(クラスID・名称・優先順位・有効フラグ・分類プロンプト)。管理画面から追加・編集可能 |
Users |
ログインユーザーアカウント(ユーザー名・パスワードハッシュ・塩・有効フラグ・管理者フラグ) |
ApiKeys |
API キー管理(キーハッシュ・有効期限・有効フラグ)。外部連携用 |
Queue |
処理待ちファイルのキュー。監視モジュールが登録し、リトライ管理にも使用する |
バックアップ:SQLite はシングルファイル(data/paperless.db 等)です。ファイルをコピーするだけでバックアップできます。定期的な cron コピーや rsync を推奨します。Monitor・Web サーバーが停止している状態でのコピーが最も安全です。
ディレクトリ構成
主要なファイルとその役割をまとめます。
YokinsPaperless/
├── monitor/ # ファイル監視モジュール(Python)
├── web/ # Web インターフェース(Node.js + React)
├── plugins/ # 文書タイプ別後処理ハンドラー(拡張用)
├── data/ # SQLite DB ファイルの保存先(設定で変更可)
├── scripts/ # DB 初期化スクリプト等
└── docs/ # このドキュメントサイト