"""Transit (self-transfer) detection rules. Identifies transactions that are internal transfers between the victim's own accounts (e.g. bank -> Alipay -> WeChat) and should NOT be counted as fraud loss. """ from app.models.transaction import TransactionRecord SELF_KEYWORDS = ["本人", "自己", "余额", "充值", "提现", "银行卡转入", "银行卡充值"] def is_self_transfer(tx: TransactionRecord, known_self_accounts: list[str]) -> bool: """Check if a transaction is an inter-account transfer by the victim.""" counterparty = (tx.counterparty_name or "").lower() remark = (tx.remark or "").lower() # Rule 1: counterparty matches known self accounts for acct in known_self_accounts: if acct and acct.lower() in counterparty: return True # Rule 2: counterparty contains self-transfer keywords for kw in SELF_KEYWORDS: if kw in counterparty or kw in remark: return True # Rule 3: counterparty references another payment app owned by victim app_keywords = ["支付宝", "微信", "银行卡", "数字钱包"] victim_patterns = [f"{app}-" for app in app_keywords] + app_keywords for pat in victim_patterns: if pat in counterparty: if tx.direction.value == "out": return True return False