Refactor main application structure and improve logging
- Reorganized imports in main.py for better readability and structure. - Enhanced logging configuration and added more detailed log messages throughout the application. - Improved error handling and response formatting in transaction import endpoints. - Streamlined transaction processing logic for CSV and image uploads. - Updated matching engine to enhance match results with rules and improved logging. - Refactored tax rules engine for better clarity and maintainability. - Cleaned up requirements.txt by removing specific versioning for easier dependency management.
This commit is contained in:
+36
-24
@@ -1,46 +1,53 @@
|
||||
from typing import List, Dict, Any
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from ai_matcher import AIMatcher
|
||||
from ai_rules import AIRulesEngine
|
||||
from feedback_logger import FeedbackLogger
|
||||
from models import Receipt, Transaction, Match
|
||||
from models import Match, Receipt, Transaction
|
||||
|
||||
|
||||
class MatchingEngine:
|
||||
def __init__(self):
|
||||
self.ai_matcher = AIMatcher()
|
||||
self.rules_engine = AIRulesEngine()
|
||||
self.feedback_logger = FeedbackLogger()
|
||||
|
||||
def process_matching(self, receipts: List[Receipt], transactions: List[Transaction]) -> List[Match]:
|
||||
|
||||
def process_matching(
|
||||
self, receipts: List[Receipt], transactions: List[Transaction]
|
||||
) -> List[Match]:
|
||||
# Get AI matches
|
||||
ai_matches = self.ai_matcher.match_receipts_to_transactions(receipts, transactions)
|
||||
|
||||
ai_matches = self.ai_matcher.match_receipts_to_transactions(
|
||||
receipts, transactions
|
||||
)
|
||||
|
||||
# Apply rules and enhance matches
|
||||
enhanced_matches = []
|
||||
for match in ai_matches:
|
||||
enhanced_match = self._enhance_match_with_rules(match)
|
||||
enhanced_matches.append(enhanced_match)
|
||||
|
||||
|
||||
return enhanced_matches
|
||||
|
||||
|
||||
def _enhance_match_with_rules(self, match: Match) -> Match:
|
||||
rule_results = self.rules_engine.apply_rules(match.receipt, match.transaction)
|
||||
|
||||
|
||||
# Apply confidence boost from rules
|
||||
if rule_results["confidence_boost"] > 0:
|
||||
match.confidence_score = min(1.0, match.confidence_score + rule_results["confidence_boost"])
|
||||
|
||||
match.confidence_score = min(
|
||||
1.0, match.confidence_score + rule_results["confidence_boost"]
|
||||
)
|
||||
|
||||
# Auto-approve if rules say so
|
||||
if rule_results["auto_approve"]:
|
||||
match.confidence_score = 1.0
|
||||
match.match_reason += " (Auto-approved by rules)"
|
||||
|
||||
|
||||
# Add tax analysis to match
|
||||
if rule_results.get("tax_analysis"):
|
||||
match.tax_analysis = rule_results["tax_analysis"]
|
||||
|
||||
|
||||
return match
|
||||
|
||||
|
||||
def approve_match(self, match: Match, user_id: str):
|
||||
# Log the approval
|
||||
self.feedback_logger.log_override(
|
||||
@@ -48,9 +55,9 @@ class MatchingEngine:
|
||||
original_match=f"AI Score: {match.confidence_score}",
|
||||
correction="Approved",
|
||||
reason="User approved match",
|
||||
user_id=user_id
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
|
||||
def reject_match(self, match: Match, reason: str, user_id: str):
|
||||
# Log the rejection
|
||||
self.feedback_logger.log_override(
|
||||
@@ -58,20 +65,25 @@ class MatchingEngine:
|
||||
original_match=f"AI Score: {match.confidence_score}",
|
||||
correction="Rejected",
|
||||
reason=reason,
|
||||
user_id=user_id
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
|
||||
def get_matching_stats(self, matches: List[Match]) -> Dict[str, Any]:
|
||||
if not matches:
|
||||
return {"total": 0, "high_confidence": 0, "low_confidence": 0, "avg_score": 0}
|
||||
|
||||
return {
|
||||
"total": 0,
|
||||
"high_confidence": 0,
|
||||
"low_confidence": 0,
|
||||
"avg_score": 0,
|
||||
}
|
||||
|
||||
high_confidence = len([m for m in matches if m.confidence_score >= 0.8])
|
||||
low_confidence = len([m for m in matches if m.confidence_score < 0.8])
|
||||
avg_score = sum(m.confidence_score for m in matches) / len(matches)
|
||||
|
||||
|
||||
return {
|
||||
"total": len(matches),
|
||||
"high_confidence": high_confidence,
|
||||
"low_confidence": low_confidence,
|
||||
"avg_score": round(avg_score, 3)
|
||||
}
|
||||
"avg_score": round(avg_score, 3),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user