|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace App\Jobs; |
| 4 | + |
| 5 | +use App\Models\Person; |
| 6 | +use App\Services\RecordMatcher\Providers\ExampleProvider; |
| 7 | +use App\Services\RecordMatcher\RecordMatcherService; |
| 8 | +use Illuminate\Bus\Queueable; |
| 9 | +use Illuminate\Contracts\Queue\ShouldQueue; |
| 10 | +use Illuminate\Foundation\Bus\Dispatchable; |
| 11 | +use Illuminate\Queue\InteractsWithQueue; |
| 12 | +use Illuminate\Queue\SerializesModels; |
| 13 | + |
| 14 | +class RunRecordMatchingJob implements ShouldQueue |
| 15 | +{ |
| 16 | + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; |
| 17 | + |
| 18 | + public int $timeout = 1200; |
| 19 | + |
| 20 | + public function handle(RecordMatcherService $matcher) |
| 21 | + { |
| 22 | + // Providers could be defined in config; for now use ExampleProvider |
| 23 | + $providers = [ |
| 24 | + new ExampleProvider(), |
| 25 | + // Add real providers via DI/config |
| 26 | + ]; |
| 27 | + |
| 28 | + // Fetch a sample of persons to run against (could be queued per-person) |
| 29 | + $persons = Person::whereNotNull('last_name')->limit(200)->get(); |
| 30 | + |
| 31 | + foreach ($persons as $person) { |
| 32 | + foreach ($providers as $provider) { |
| 33 | + $candidates = $provider->search($person); |
| 34 | + $scored = $matcher->scoreCandidates($person, $candidates); |
| 35 | + |
| 36 | + foreach ($scored as $entry) { |
| 37 | + $candidate = $entry['candidate']; |
| 38 | + $score = $entry['score']; |
| 39 | + // Only persist suggestions above a threshold (e.g., 0.45) |
| 40 | + if ($score >= config('ai_record_match.min_confidence', 0.45)) { |
| 41 | + $matcher->persistSuggestion($person->id, (new \ReflectionClass($provider))->getShortName(), $candidate, $score); |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | +} |
0 commit comments