"""In-memory RuleRepository for testing — no ChromaDB, no embeddings.""" from typing import Optional from domain.models import RuleDocument, RuleSearchResult from domain.ports import RuleRepository class FakeRuleRepository(RuleRepository): """Stores rules in a list; search returns all rules sorted by naive keyword overlap.""" def __init__(self): self.documents: list[RuleDocument] = [] def add_documents(self, docs: list[RuleDocument]) -> None: self.documents.extend(docs) def search( self, query: str, top_k: int = 10, section_filter: Optional[str] = None ) -> list[RuleSearchResult]: query_words = set(query.lower().split()) results = [] for doc in self.documents: if section_filter and doc.section != section_filter: continue content_words = set(doc.content.lower().split()) overlap = len(query_words & content_words) if overlap > 0: similarity = min(1.0, overlap / max(len(query_words), 1)) results.append( RuleSearchResult( rule_id=doc.rule_id, title=doc.title, content=doc.content, section=doc.section, similarity=similarity, ) ) results.sort(key=lambda r: r.similarity, reverse=True) return results[:top_k] def count(self) -> int: return len(self.documents) def clear_all(self) -> None: self.documents.clear() def get_stats(self) -> dict: sections: dict[str, int] = {} for doc in self.documents: sections[doc.section] = sections.get(doc.section, 0) + 1 return {"total_rules": len(self.documents), "sections": sections}