Refactors duplicate payment check in Fava

Improves payment recording logic by fetching recent entries and filtering using Python, replacing the BQL query.

This addresses issues with matching against set types in BQL, enhancing reliability.
This commit is contained in:
padreug 2025-11-10 10:25:05 +01:00
parent fbda8e2980
commit 8342318fde
2 changed files with 44 additions and 24 deletions

View file

@ -1356,24 +1356,34 @@ async def api_record_payment(
fava = get_fava_client()
# Query Fava for existing entry with this payment hash link
query = f"SELECT * WHERE links ~ 'ln-{data.payment_hash[:16]}'"
# Check if payment already recorded by fetching recent entries
# Note: We can't use BQL query with `links ~ 'pattern'` because links is a set type
# and BQL doesn't support regex matching on sets. Instead, fetch entries and filter in Python.
link_to_find = f"ln-{data.payment_hash[:16]}"
try:
async with httpx.AsyncClient(timeout=5.0) as client:
# Get recent entries from Fava's journal endpoint
response = await client.get(
f"{fava.base_url}/query",
params={"query_string": query}
f"{fava.base_url}/api/journal",
params={"time": ""} # Get all entries
)
result = response.json()
if result.get('data', {}).get('rows'):
# Payment already recorded, return existing entry
balance_data = await fava.get_user_balance(target_user_id)
return {
"journal_entry_id": f"fava-exists-{data.payment_hash[:16]}",
"new_balance": balance_data["balance"],
"message": "Payment already recorded",
}
if response.status_code == 200:
response_data = response.json()
entries = response_data.get('entries', [])
# Check if any entry has our payment link
for entry in entries:
entry_links = entry.get('links', [])
if link_to_find in entry_links:
# Payment already recorded, return existing entry
balance_data = await fava.get_user_balance(target_user_id)
return {
"journal_entry_id": f"fava-exists-{data.payment_hash[:16]}",
"new_balance": balance_data["balance"],
"message": "Payment already recorded",
}
except Exception as e:
logger.warning(f"Could not check Fava for duplicate payment: {e}")
# Continue anyway - Fava/Beancount will catch duplicate if it exists