一键导入
dotnet-ocr-matching-workflow
こんなときに使う: 基盤・インフラ・プレゼンテーションの各スキルをエンドツーエンドで合成し、OCR→DBマッチングの完全なシステムをオーケストレーションします。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
こんなときに使う: 基盤・インフラ・プレゼンテーションの各スキルをエンドツーエンドで合成し、OCR→DBマッチングの完全なシステムをオーケストレーションします。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | dotnet-ocr-matching-workflow |
| description | こんなときに使う: 基盤・インフラ・プレゼンテーションの各スキルをエンドツーエンドで合成し、OCR→DBマッチングの完全なシステムをオーケストレーションします。 |
個別スキルを組み合わせて、OCRマッチングのフルパイプラインを構築するワークフローオーケストレーターです。DDDプロジェクトのセットアップ、セキュア設定、Oracle DB統合、Dify APIによるOCR抽出、重み付きフィールドマッチング、WPF比較UI、CSVエクスポートまでを、依存性注入(DI)で一貫して配線します。
以下の場合にこのスキルを使用してください:
前提条件:
dotnet-wpf-secure-config — DPAPI暗号化の基盤(Step 2)dotnet-oracle-wpf-integration — Oracle DB接続 + リポジトリ(Step 2)dotnet-wpf-dify-api-integration — Dify APIクライアント + SSEストリーミング(Step 2)dotnet-wpf-employee-input — 社員番号入力と保存(Step 3)dotnet-wpf-pdf-preview — PDFアップロードとWebView2プレビュー(Step 4)dotnet-wpf-ocr-parameter-input — OCRパラメータ入力タブ(Step 5)dotnet-generic-matching — Domainレイヤーの重み付きフィールドマッチング(Step 6)dotnet-wpf-comparison-view — 結果を左右に並べて比較するUI(Step 7)tdd-standard-practice — Red-Green-Refactorで生成コードをテストgit-commit-practices — 各ステップをアトミックな変更としてコミットdotnet-wpf-secure-config を適用する。理由:この順序はレイヤー単位で障害を切り分け、デバッグコストを低減します。
新しいソリューションを作成する場合、または既存のソリューションが4レイヤーDDD構造に従っているかを確認する場合に使用します。
ソリューションと4つのプロジェクトを作成します。Domainレイヤーは技術的関心ではなく、ユースケース単位で整理します。
YourApp/
├── YourApp.Domain/ # Domain Layer (no dependencies)
│ └── YourUseCase/ # Use-case based organization
│ ├── Services/
│ ├── ValueObjects/
│ ├── Specifications/
│ └── Interfaces (IRepository, IExtractor)
├── YourApp.Application/ # Application Layer (depends on Domain)
│ └── UseCases/YourUseCase/
├── YourApp.Infrastructure/ # Infrastructure Layer (implements Domain)
│ ├── Configuration/
│ ├── ExternalApis/ # Dify API etc.
│ ├── Databases/ # Oracle etc.
│ └── FileSystem/
└── YourApp.Presentation.Wpf/ # Presentation Layer (depends on Application)
├── ViewModels/
├── Views/
├── Converters/
└── Services/
依存関係ルールを強制するため、プロジェクト参照を設定します:
<!-- YourApp.Application.csproj -->
<ProjectReference Include="..\YourApp.Domain\YourApp.Domain.csproj" />
<!-- YourApp.Infrastructure.csproj -->
<ProjectReference Include="..\YourApp.Domain\YourApp.Domain.csproj" />
<!-- YourApp.Presentation.Wpf.csproj -->
<ProjectReference Include="..\YourApp.Application\YourApp.Application.csproj" />
<ProjectReference Include="..\YourApp.Infrastructure\YourApp.Infrastructure.csproj" />
依存関係ルール:
Values: 基礎と型 / 成長の複利
後続ステップすべてが依存する、3つのインフラ基盤をセットアップするときに使用します。
以下の既存スキルをこの順序どおりに適用してください。各スキルは前のスキルの上に構築されます:
| 順序 | スキル | 提供内容 | レイヤー |
|---|---|---|---|
| 1番目 | dotnet-wpf-secure-config | DpapiEncryptor, SecureConfigService, AppConfigModel | インフラ |
| 2番目 | dotnet-oracle-wpf-integration | Oracle接続、リポジトリ実装、接続テストダイアログ | インフラ |
| 3番目 | dotnet-wpf-dify-api-integration | DifyApiService, SSEストリーミング、APIテストダイアログ | インフラ |
🆕 この順序が重要な理由: OracleスキルとDifyスキルはいずれもSecureConfigServiceで認証情報を保存するため、secure-configが先に必要です。OracleとDifyは互いに独立ですが、どちらも設定基盤に依存します。
3つすべてを適用したら、各スキルが提供するテストダイアログで検証します:
%LOCALAPPDATA% に設定ファイルが作成されるValues: 基礎と型 / 継続は力
システムが「どのユーザーが文書を処理しているか」を識別する必要がある場合に使用します。
適用:dotnet-wpf-employee-input
既存インフラへの配線:
AppConfigModelに社員番号フィールドを追加SecureConfigServiceで暗号化して保存// AppConfigModel extension (added by employee-input skill)
public class AppConfigModel
{
// ... existing Oracle/Dify properties from Step 2
public string? EmployeeId { get; set; } // 🆕 Added
public string? EmployeeName { get; set; } // 🆕 Added
}
Values: ニュートラル / 継続は力
ドキュメント入力インターフェース(メインウィンドウ左側)を追加する場合に使用します。
適用:dotnet-wpf-pdf-preview
レイアウト統合:
┌──────────────────────────────────────────────────┐
│ Main Window │
│ ┌───────────────────┬──────────────────────────┐ │
│ │ Left Column │ Right Column │ │
│ │ ┌───────────────┐ │ ┌────────────────────┐ │ │
│ │ │ Upload Button │ │ │ TabControl │ │ │
│ │ ├───────────────┤ │ │ ┌──────┬─────────┐ │ │ │
│ │ │ │ │ │ │OCR │Results │ │ │ │
│ │ │ WebView2 │ │ │ │Input │Comparison│ │ │ │
│ │ │ PDF Preview │ │ │ │(Stp5)│(Step 7) │ │ │ │
│ │ │ │ │ │ └──────┴─────────┘ │ │ │
│ │ └───────────────┘ │ └────────────────────┘ │ │
│ └───────────────────┴──────────────────────────┘ │
└──────────────────────────────────────────────────┘
PDFプレビュースキルは左カラム用にPdfPreviewServiceを提供します。右カラムのTabControlには、Step 5とStep 7のタブを配置します。
Values: 基礎と型 / ニュートラル
右カラム最初のタブ(ユーザーがOCRパラメータを指定し、抽出をトリガーする画面)を作成する場合に使用します。
適用:dotnet-wpf-ocr-parameter-input
🆕 ユーザーに確認: どの分類フィールド/選択フィールドが必要かを確認してください。よくある例:
| フィールド種別 | 例 | バインド先 |
|---|---|---|
| カテゴリドロップダウン | "商品種別", "部署" | DB参照クエリ |
| 自由入力 | "備考", "特記事項" | Dify APIプロンプトパラメータ |
| 日付ピッカー | "注文日", "納期" | フィルタ条件 |
既存サービスへの配線:
DifyApiServiceに接続PdfPreviewServiceから選択済みPDFパスを渡すIProgress<(int, string)>パターンで進捗を表示// ViewModel wiring — connects OCR tab to Dify API
[RelayCommand]
private async Task ExecuteOcrAsync()
{
var progress = new Progress<(int percent, string message)>(p =>
{
ProgressValue = p.percent;
StatusText = p.message;
});
// PdfPath comes from Step 4, DifyApiService from Step 2
var results = await _processDocumentUseCase.ExecuteAsync(
PdfPath, SelectedCategory, Remarks, progress);
}
Values: 成長の複利 / ニュートラル
OCR抽出データをデータベースレコードと比較する中核ビジネスロジックを構築するときに使用します。
適用:dotnet-generic-matching
🆕 ユーザーに確認: 照合対象フィールドと、その相対的重要度(重み)を確認してください:
| 質問 | 回答例 | 対応先 |
|---|---|---|
| レコードを識別するフィールドは? | "商品名、得意先コード" | 重み 2.5–3.0 |
| 一致を確定するフィールドは? | "単価、数量" | 重み 1.5–2.5 |
| 補助的なフィールドは? | "寸法、備考" | 重み 0.5–1.5 |
dotnet-generic-matchingスキルは、Domainレイヤーに以下のコンポーネントを作成します:
YourApp.Domain/
└── YourUseCase/
├── ValueObjects/
│ ├── FieldComparison.cs
│ └── MatchingScore.cs
├── Services/
│ ├── SimilarityCalculator.cs
│ └── FieldMatchingService<TSource, TCandidate>.cs
└── Specifications/
└── HighQualityMatchingSpecification.cs
ユーザー指定の重みでフィールド定義を構成します:
var fields = new List<FieldDefinition<ExtractedItem, ReferenceRecord>>
{
new()
{
FieldName = "ProductName", // 🆕 User-specified
SourceExtractor = s => s.Name,
CandidateExtractor = c => c.ProductName,
CompareFunction = SimilarityCalculator.StringSimilarity,
Weight = 3.0 // 🆕 User-specified
},
new()
{
FieldName = "UnitPrice",
SourceExtractor = s => s.Price.ToString(),
CandidateExtractor = c => c.UnitPrice.ToString(),
CompareFunction = (a, b) =>
SimilarityCalculator.NumericSimilarityDecimal(
decimal.Parse(a), decimal.Parse(b)),
Weight = 2.0
}
};
Values: 基礎と型 / 成長の複利
マッチング結果を左右に並べて表示する2つ目のタブを作成する場合に使用します。
適用:dotnet-wpf-comparison-view
比較ビューはStep 6のMatchingResult<TSource, TCandidate>を受け取り、以下をレンダリングします:
┌─────────────────────────────────────────────────────┐
│ Results Tab │
│ ┌────────┬──────────────┬──────────┬───────┬─────┐ │
│ │ ☐ │ DB Record │ OCR Data │ Score │ Edit│ │
│ ├────────┼──────────────┼──────────┼───────┼─────┤ │
│ │ ☑ │ Widget A │ Widget A │ 95.2% │ ✎ │ │
│ │ ☐ │ Gadget B │ Gadget C │ 67.1% │ ✎ │ │
│ │ ☑ │ Part X │ Part X │ 100% │ ✎ │ │
│ └────────┴──────────────┴──────────┴───────┴─────┘ │
│ │
│ [Export CSV] │
└─────────────────────────────────────────────────────┘
comparison-viewスキルが提供する主な機能:
Values: ニュートラル / 継続は力
Applicationレイヤーで処理パイプライン全体を配線する(DomainとInfrastructureの接着剤)場合に使用します。
参照データ読み込み → OCR抽出 → マッチング、という全フローをオーケストレーションするユースケースを作成します。
namespace YourApp.Application.UseCases.YourUseCase
{
public class ProcessDocumentUseCase
{
private readonly IDocumentExtractor _extractor; // Dify API (Infrastructure)
private readonly IDataRepository _repository; // Oracle DB (Infrastructure)
private readonly FieldMatchingService<ExtractedItem, ReferenceRecord> _matcher; // Domain
public ProcessDocumentUseCase(
IDocumentExtractor extractor,
IDataRepository repository,
FieldMatchingService<ExtractedItem, ReferenceRecord> matcher)
{
_extractor = extractor;
_repository = repository;
_matcher = matcher;
}
public async Task<IEnumerable<MatchingResult<ExtractedItem, ReferenceRecord>>> ExecuteAsync(
string pdfPath, string category, string remarks,
IProgress<(int percent, string message)>? progress = null)
{
// 1. Load reference data from DB (10%)
progress?.Report((10, "Loading reference data..."));
var referenceData = await _repository.GetByCategoryAsync(category);
// 2. Extract data from PDF via OCR (30-60%)
progress?.Report((30, "Running OCR extraction..."));
var extractedItems = await _extractor.ExtractAsync(
pdfPath, remarks, progress);
// 3. Match extracted items against reference data (80%)
progress?.Report((80, "Matching records..."));
var results = _matcher.MatchAll(extractedItems, referenceData);
progress?.Report((100, "Complete"));
return results;
}
}
}
🆕 このユースケースは実装ではなくインターフェースに依存します — DIコンテナ(Step 9)が具体的なサービスを提供します。
Values: 基礎と型 / 成長の複利
これまでのステップで作成したすべてのサービスをDIコンテナに登録する場合に使用します。
依存の流れに沿って、App.xaml.csでサービスを登録します:
protected override void OnStartup(StartupEventArgs e)
{
var services = new ServiceCollection();
// ── Foundation (Step 2) ──
services.AddSingleton<ISecureConfigService, SecureConfigService>();
// ── Infrastructure (Steps 2-3) ──
services.AddSingleton<IDataRepository, OracleDatabaseRepository>();
services.AddSingleton<IDocumentExtractor, DifyApiService>();
// ── Domain (Step 6) ──
services.AddSingleton(provider =>
{
var fields = BuildFieldDefinitions(); // User-configured weights
return new FieldMatchingService<ExtractedItem, ReferenceRecord>(
fields, successThreshold: 70.0);
});
// ── Application (Step 8) ──
services.AddTransient<ProcessDocumentUseCase>();
// ── Presentation (Steps 4-5, 7) ──
services.AddTransient<MainWindowViewModel>();
services.AddTransient<OcrProcessTabViewModel>();
services.AddTransient<ResultTabViewModel>();
_serviceProvider = services.BuildServiceProvider();
var mainWindow = new MainWindow
{
DataContext = _serviceProvider.GetRequiredService<MainWindowViewModel>()
};
mainWindow.Show();
}
DI登録の順序が重要なのは可読性のためであり、実行時ではありません。依存フローと同じ順序で登録します:
SecureConfigService → OracleRepository → DifyApiService → MatchingService → UseCase → ViewModels
Values: 成長の複利 / 基礎と型
ユーザーがマッチング結果を検証した後に、CSVやRPA出力を追加する場合に使用します。
エクスポート前に、すべての品質ゲートを通過していることを要求します:
public class ExportService
{
public void ExportToCsv(
IEnumerable<MatchingResult<ExtractedItem, ReferenceRecord>> results,
string outputPath)
{
// Quality gate checks
var resultList = results.ToList();
if (resultList.Any(r => !r.IsVerified))
throw new InvalidOperationException(
"All rows must be verified (checkbox) before export.");
if (resultList.Any(r => r.Score.OverallPercentage < 70.0))
throw new InvalidOperationException(
"All matching scores must meet the quality threshold.");
// RFC 4180 compliant CSV output
using var writer = new StreamWriter(outputPath, false, Encoding.UTF8);
writer.WriteLine(BuildHeaderRow());
foreach (var result in resultList)
{
writer.WriteLine(BuildDataRow(result));
}
}
private static string EscapeCsvField(string field)
{
if (field.Contains(',') || field.Contains('"') || field.Contains('\n'))
return $"\"{field.Replace("\"", "\"\"")}\"";
return field;
}
}
✅ エクスポート前の品質チェック:
Values: 継続は力 / ニュートラル
すべてのスキルが正しく統合され、パイプライン全体が動作することを検証する場合に使用します。
以下のテストチェックリストを順番に実行します:
| # | テスト | 確認方法 | 依存 |
|---|---|---|---|
| 1 | Oracle接続 | 設定(Settings)→ 接続テスト(Test Connection)ボタン | Step 2 |
| 2 | Dify API接続 | 設定(Settings)→ APIテスト(Test API)ボタン | Step 2 |
| 3 | 社員番号の永続化 | IDを入力 → アプリを再起動 → 復元されることを確認 | Step 3 |
| 4 | PDFアップロード + プレビュー | PDFを選択し、WebView2で表示されることを確認 | Step 4 |
| 5 | OCRパラメータ入力 | フィールドを入力し、実行(Execute)をクリック | Step 5 |
| 6 | OCR進捗表示 | プログレスバーとステータステキストを確認 | Step 5, 8 |
| 7 | マッチング結果表示 | 左右比較テーブルが表示されることを確認 | Step 6, 7 |
| 8 | 編集時の再計算 | フィールドを編集し、スコア更新を確認 | Step 7 |
| 9 | チェックボックス検証 | 全行にチェックし、エクスポート(Export)が有効になることを確認 | Step 7 |
| 10 | CSVエクスポート | エクスポートしてExcelで開く | Step 10 |
🆕 いずれかのテストが失敗した場合は、レイヤーを切り分けてデバッグします:
Values: 継続は力 / 基礎と型
特定の業務ドメイン向けにシステムを適用する場合に使用します。
| カスタマイズ | 変更箇所 | スキル参照 |
|---|---|---|
| OCRパラメータの追加/削除 | OcrProcessTabViewModel | dotnet-wpf-ocr-parameter-input |
| マッチング対象フィールド/重みの変更 | DI内のFieldDefinitionリスト | dotnet-generic-matching |
| 品質閾値の調整 | FieldMatchingServiceコンストラクタ | dotnet-generic-matching |
| 新しいDBカラムの追加 | リポジトリ + Domainモデル | dotnet-oracle-wpf-integration |
| DifyワークフローIDの変更 | AppConfigModel + Settings UI | dotnet-wpf-dify-api-integration |
| エクスポート形式の変更 | ExportService | このスキルのStep 10 |
| 比較カラムの追加 | ResultTabViewModel + XAML | dotnet-wpf-comparison-view |
🆕 本番運用の堅牢化チェックリスト:
Values: 成長の複利 / 継続は力
✅ まず基盤スキル、次にインフラ、最後にプレゼンテーションを適用してください。依存チェーンは厳密です:
secure-config → oracle + dify → employee-input → pdf-preview → ocr-input → matching → comparison
先に進めすぎると、インターフェース不足やコンパイルエラーの原因になります。
✅ 各スキルにはそれぞれのテスト手段(接続テストダイアログ、ユニットテストパターン)が用意されています。次のステップへ進む前に、スキル単体で動作することを確認してください。
Step 2: Test Oracle connection → Pass ✅
Step 2: Test Dify API → Pass ✅
Step 4: Test PDF preview → Pass ✅
Step 8: Wire together → Confidence ✅
✅ ViewModelやユースケース内でインフラサービスを直接newしないでください。常にコンストラクタ注入し、DIコンテナ(Step 9)に登録します。
// ✅ CORRECT — Constructor injection
public ProcessDocumentUseCase(
IDocumentExtractor extractor,
IDataRepository repository,
FieldMatchingService<ExtractedItem, ReferenceRecord> matcher)
// ❌ WRONG — Direct instantiation
public ProcessDocumentUseCase()
{
_extractor = new DifyApiService(new SecureConfigService()); // Tight coupling
}
詳細な説明と例は detailed-patterns.md を参照してください。
主要ルール:
secure-configdotnet-wpf-secure-configを適用 — DPAPI基盤(Step 2)dotnet-oracle-wpf-integrationを適用 — Oracleリポジトリ(Step 2)dotnet-wpf-dify-api-integrationを適用 — Dify APIクライアント(Step 2)dotnet-wpf-employee-inputを適用 — 社員番号(Step 3)dotnet-wpf-pdf-previewを適用 — PDFアップロード + WebView2(Step 4)dotnet-wpf-ocr-parameter-inputを適用 — OCRパラメータタブ(Step 5)dotnet-generic-matchingを適用 — Domainマッチングロジック(Step 6)dotnet-wpf-comparison-viewを適用 — 結果比較タブ(Step 7)ProcessDocumentUseCaseを作成(Step 8)App.xaml.csでDIコンテナを配線(Step 9)dotnet-wpf-secure-config (foundation — no dependencies)
├── dotnet-oracle-wpf-integration (needs secure-config)
├── dotnet-wpf-dify-api-integration (needs secure-config)
└── dotnet-wpf-employee-input (needs secure-config)
dotnet-wpf-pdf-preview (independent — UI only)
dotnet-wpf-ocr-parameter-input (needs dify-api, pdf-preview)
dotnet-generic-matching (independent — Domain only)
dotnet-wpf-comparison-view (needs generic-matching)
| レイヤー | 含むもの | 依存先 | クラス例 |
|---|---|---|---|
| 🆕 ドメイン | ビジネスロジック、インターフェース、値オブジェクト | なし | FieldMatchingService, IDataRepository |
| ✅ アプリケーション | ユースケース、オーケストレーション | ドメイン | ProcessDocumentUseCase |
| ✅ インフラ | DBアクセス、APIクライアント、設定 | ドメイン | OracleDatabaseRepository, DifyApiService |
| ❌ プレゼンテーション | ViewModels、Views、XAML | アプリケーション | MainWindowViewModel, ResultTabView |
| From(提供側) | To(利用側) | 経由 | 登録箇所 |
|---|---|---|---|
SecureConfigService | Oracle、Dify、社員情報 | ISecureConfigService | DI(Step 9) |
OracleDatabaseRepository | ProcessDocumentUseCase | IDataRepository | DI(Step 9) |
DifyApiService | ProcessDocumentUseCase | IDocumentExtractor | DI(Step 9) |
FieldMatchingService | ProcessDocumentUseCase | 直接(ドメイン) | DI(Step 9) |
ProcessDocumentUseCase | OcrProcessTabViewModel | コンストラクタ注入 | DI(Step 9) |
dotnet-wpf-secure-config — DPAPI暗号化と設定管理dotnet-oracle-wpf-integration — Oracleデータベース統合dotnet-wpf-dify-api-integration — Dify APIによるOCR抽出dotnet-generic-matching — 汎用の重み付きフィールドマッチングdotnet-wpf-comparison-view — 左右比較の結果UI| バージョン | 日付 | 変更 |
|---|---|---|
| 1.0.0 | 2025-07-13 | 🆕 初回リリース — OCRマッチングシステム用の12ステップ・オーケストレーター |
モダン C#(12+)で record、パターンマッチング、合成、Result 型エラーハンドリングを使った 慣用的で高性能なコードを書く。こんなときに使う: 新規 C# コードの作成、API 設計、 または C# 12+ イディオムへのリファクタリング。
こんなときに使う: WPFアプリケーションに社員番号入力ダイアログを追加し、 DPAPIで暗号化された設定として社員IDを安全に保存したいとき。
こんなときに使う: 繰り返し発生する業務問い合わせ(監査、アンケート、コンプライアンス調査)に対して、 過去の回答実績とエビデンスを活用して回答するためのテンプレートスキル。 再利用可能な7ステップワークフローとスキャフォールディングファイルを提供する。
こんなときに使う: PDFテキスト抽出、Optical Character Recognition (OCR)、結合/分割、フォーム処理をuvベースの再現可能コマンドで実行したいときに使う。
こんなときに使う: Migrate Access SQL to Oracle, generate .NET C# code. Use when converting Access queries to Oracle.
こんなときに使う: .NETドメイン層で汎用的な重み付きフィールドマッチングとスコアリングを実装。