خوارزمية فحص تعارض المصالحConflict of interest matching
تطابق المعرفات الدقيقة بالبصمة، ثم الأسماء بعد التطبيع بمطابقة تقريبية موزونة، ثم شبكة العلاقات حتى قفزتين، وتعطي كل نتيجة سببًا ودرجة وخطورة مقترحة. لا تُصدر قرارًا.
الميزات التي تستخدمها: B16 فحص تعارض المصالح، B17 الزوار والاستقبال والمواعيد، B06 فريق الملف وحواجز المعلومات، B02 الموكّلون والأطراف والعلاقات
1الغرض والمصطلحات القانونية المرتبطة
دعم قرار بشري في تعارض المصالح. تشابه الاسم وحده معلومة لا رفض.
2المدخلات وأنواعها ومصادرها
- أسماء ومعرّفات الموضوع (زيارة، ملف، طرف، موظف).
- فهرس الأطراف:
normalized_name،id_hmac،aliases،name_en. Related PartyوStaff Prior Engagement.- عتبات وأوزان من الإعداد.
3المخرجات والحالات
Conflict Hit لكل تطابق: الطرف، الملف، الصفة، سبب المطابقة، الدرجة 0–100، الخطورة المقترحة من Conflict Rule.
4خطوات المعالجة بالتسلسل
- طبّع الاسم تطبيع الأسماء والنصوص العربية.
- معرّف موجود ← بحث بالبصمة: تطابق = «مؤكد» 100.
- مفتاح حجب (blocking): أول حرفين من اسم العائلة الموحد لتقليل المرشحين اقتراح هندسي.
- لكل مرشح: درجة السلسلة الكاملة
token_sort_ratio، ودرجة الأول+العائلة موزونة، والاسم اللاتيني. - أعلى درجة ≥ العتبة ← تطابق.
- لكل تطابق: علاقاته حتى قفزتين ← تطابقات «علاقة».
- تصنيف الخطورة من نوع الصفة وجدول القواعد.
5الشروط والفروع والاستثناءات
ثلاثة مستويات في الوثيقة المعمارية: عالٍ، متوسط للمراجعة، منخفض كملاحظة (الوثيقة المعمارية). في هذا التوثيق: «عالٍ» يوقف التقدم حتى قرار بشري، ولا يرفض العميل آليًا.
6Pseudocode كامل
function run_conflict_check(subject):
hits = []
for person in subject.names_and_ids:
if person.id:
for p in Party.where(id_hmac = hmac(person.id)):
hits += Hit(p, reason="معرّف", score=100)
n = normalize(person.name)
for p in Party.candidates(block_key(n)):
full = rapidfuzz.token_sort_ratio(n, p.normalized_name)
short = weighted(first_token(n) ~ first_token(p), last_token(n) ~ last_token(p), w_first, w_family)
latin = rapidfuzz.ratio(person.name_en, p.name_en) if both else 0
s = max(full, short, latin, max(alias scores))
if s >= settings.threshold: hits += Hit(p, reason=best_reason, score=s)
hits += expand_relations(hits, depth=2)
for h in hits: h.severity = ConflictRule.lookup(h.role, h.reason) # [legal] table
return hits # never a decisionRapidFuzz بدل كتابة Levenshtein من الصفر (قرار تقييم القرارات) (التقييم الهندسي).
7مثال اصطناعي خطوة بخطوة
| المدخل | المخزن | النتيجة |
|---|---|---|
| مُحمّد بن عبدالله العتيبي | محمد عبد الله العتيبي | بعد التطبيع متطابقان ← تطابق عالٍ (اسم) |
| أحمد بن محمد العنزي | محمد أحمد العنزي | ترتيب مختلف ← token_sort يرفع الدرجة؛ للمراجعة |
| أي اسم + هوية ١٠٠٠٠٠٠٠٠١ | هوية 1000000001 باسم مختلف | مؤكد بالمعرّف |
كل الأسماء والأرقام اصطناعية.
8حالات الفشل والتعامل معها
فهرس غير محدث ← إعادة فهرسة قبل الفحص. مهلة الفحص ← حالة «قيد الفحص» وإعادة في الطابور.
9منع التكرار والتزامن
الفحص في طابور short؛ قرار واحد لكل فحص (submittable).
10الصلاحيات والتدقيق والأمن
الطالب يرى الحالة فقط. البصمة لا تُكشف.
11اختبارات الوحدات والتكامل والقبول
| المعرّف | النوع | السيناريو | النتيجة المتوقعة |
|---|---|---|---|
ALG-CF-01 | وحدة | أمثلة الجدول | كما هو متوقع |
ALG-CF-02 | وحدة | الاسم وحده بدرجة 95 | لا قرار آلي |
ALG-CF-03 | أداء | 50,000 طرف | زمن ضمن حد معلن بعد القياس غير مثبت |
12ما هو قاعدة تقنية وما هو قرار قانوني
| قاعدة تقنية (ينفذها المطور) | قرار قانوني (يعتمده مختص) |
|---|---|
| التطبيع، الدرجات، الحجب، العلاقات | جدول الخطورة ومدد التبريد |
| العتبات والأوزان (تُضبط على بيانات المكتب) | القرار في كل حالة |