MCPcopy Create free account
hub / github.com/RASAAS/docmcp-knowledge / classify

Method classify

scripts/fetch_updates.py:530–608  ·  view source on GitHub ↗

Classify a detection against the database. Returns: ('new', description) | ('update', diff) | ('known', '') | ('irrelevant', reason)

(self, category: str, title: str, link: str = "", date: str = "")

Source from the content-addressed store, hash-verified

528 self.db_stats["fda/guidance"] = {"count": len(self.fda_guidance_titles)}
529
530 def classify(self, category: str, title: str, link: str = "", date: str = "") -> tuple[str, str]:
531 """Classify a detection against the database.
532
533 Returns: ('new', description) | ('update', diff) | ('known', '') | ('irrelevant', reason)
534 """
535 title_lower = title.strip().lower()
536
537 if category == "eu_mdr/mdcg":
538 mdcg_match = re.search(r"MDCG\s+(20\d{2}[-/]\d+)", title, re.IGNORECASE)
539 if not mdcg_match:
540 return ("irrelevant", "No MDCG ID pattern in title")
541 mdcg_id = mdcg_match.group(1).replace("/", "-")
542 normalized = f"mdcg-{mdcg_id}"
543
544 # Check for revision indicator attached to THIS MDCG document
545 # Only match rev.X that appears near the MDCG ID (within ~30 chars),
546 # NOT revision markers belonging to other referenced documents
547 # e.g. "MDCG 2021-24 Rev.1" -> rev.1 (correct)
548 # e.g. "...MDCG 2020-6 and MEDDEV 2.7/1 rev.4..." -> ignore rev.4
549 mdcg_end = mdcg_match.end()
550 nearby_text = title[mdcg_end:mdcg_end + 30]
551 rev_match = re.search(r"^\s*[-–/]?\s*[Rr]ev[\.\s]*(\d+)", nearby_text)
552 new_rev = rev_match.group(0).strip() if rev_match else ""
553
554 if normalized in self.mdcg_ids or f"MDCG {mdcg_id}" in self.mdcg_ids:
555 if new_rev:
556 # Search result mentions a revision -- check if our DB already has it
557 db_entry = next(
558 (e for e in self._mdcg_entries if e.get("id") == normalized), None
559 )
560 db_rev = ""
561 if db_entry:
562 db_rev = db_entry.get("revision", "")
563 for lang in ("zh", "en"):
564 t = (db_entry.get("title") or {}).get(lang, "")
565 if t and not db_rev:
566 rm = re.search(r"[Rr]ev[\.\s]*(\d+)", t)
567 if rm:
568 db_rev = rm.group(0).strip()
569 if db_rev and db_rev.lower().replace(" ", "") == new_rev.lower().replace(" ", ""):
570 return ("known", "")
571 return ("update", f"Revision update: {normalized} has {new_rev} (DB: {db_rev or 'original'})")
572 return ("known", "")
573 return ("new", f"New MDCG document: {mdcg_match.group(0)}")
574
575 elif category == "eu_mdr/standards":
576 cid_match = re.search(r"20\d{2}/\d+", title)
577 if cid_match:
578 cid = cid_match.group(0)
579 if self.standards_latest_amendment and cid > self.standards_latest_amendment:
580 return ("update", f"New amendment {cid} (DB latest: {self.standards_latest_amendment})")
581 return ("known", "")
582 return ("irrelevant", "No CID amendment number found")
583
584 elif category == "nmpa/regulations":
585 for known in self.nmpa_reg_titles:
586 if known in title or title in known:
587 return ("known", "")

Callers 2

checkMethod · 0.80
_apply_db_comparisonMethod · 0.80

Calls 2

getMethod · 0.80
searchMethod · 0.45

Tested by

no test coverage detected