mirror of
https://github.com/we-promise/sure
synced 2026-04-25 17:15:07 +02:00
* SimpleFIN: setup UX + same-provider relink + card-replacement detection Fixes three bugs and adds auto-detection for credit-card fraud replacement. Bugs: - Importer: per-institution auth errors no longer flip the whole item to requires_update. Partial errors stay on sync_stats so other institutions keep syncing. - Setup page: new activity badges (recent / dormant / empty / likely-closed) via SimplefinAccount::ActivitySummary. Likely-closed (dormant + near-zero balance + prior history) defaults to "skip" in the type picker. - Relink: link_existing_account allows SimpleFIN to SimpleFIN swaps by atomically detaching the old AccountProvider inside a transaction. Adds "Change SimpleFIN account" menu item on linked-account dropdowns. Feature (credit-card scope only): - SimplefinItem::ReplacementDetector runs post-sync. Pairs a linked dormant zero-balance sfa with an unlinked active sfa at the same institution and account type. Persists suggestions on Sync#sync_stats. - Inline banner on the SimpleFIN item card prompts relink via CustomConfirm. Per-pair dismiss button scoped to the current sync (resurfaces on next sync if still applicable). Auto-suppresses once the relink has landed. Dev tooling: - bin/rails simplefin:seed_fraud_scenario[email] creates a realistic broken pair for manual QA; cleanup_fraud_scenario reverses it. * Address review feedback on #1493 - ReplacementDetector: symmetric one-to-one matching. Two dormant cards pointing at the same active card are now both skipped — previously the detector could emit two suggestions that would clobber each other if the user accepted both. - ReplacementDetector: require non-blank institution names on both sides before matching. Blank-vs-blank was accidentally treated as equal, risking cross-provider false matches when SimpleFIN omitted org_data. - ActivitySummary: fall back to "posted" when "transacted_at" is 0 (SimpleFIN's "unknown" sentinel). Integer 0 is truthy in Ruby, so the previous `|| fallback` short-circuited and ignored posted. - Controller: dismiss key is now the (dormant, active) pair so dismissing one candidate for a dormant card doesn't suppress others. - Helper test: freeze time around "6.hours.ago" and "5.days.ago" assertions so they don't flake when the suite runs before 06:00. * Address second review pass on #1493 - ReplacementDetector: canonicalize account_type in one place so filtering (supported_type?) and matching (type_matches?) agree on "credit card" vs "credit_card" variants. - ReplacementDetector: skip candidates with nil current_balance. nil is "unknown," not "zero" — previously fell back to 0 and passed the near- zero gate, allowing suggestions without balance evidence.
133 lines
6.9 KiB
YAML
133 lines
6.9 KiB
YAML
---
|
||
en:
|
||
simplefin_items:
|
||
new:
|
||
title: Connect SimpleFIN
|
||
setup_token: Setup token
|
||
setup_token_placeholder: paste your SimpleFIN setup token
|
||
connect: Connect
|
||
cancel: Cancel
|
||
create:
|
||
success: SimpleFIN connection added successfully! Your accounts will appear shortly as they sync in the background.
|
||
errors:
|
||
blank_token: Please enter a SimpleFIN setup token.
|
||
invalid_token: Invalid setup token. Please check that you copied the complete token from SimpleFIN Bridge.
|
||
token_compromised: The setup token may be compromised, expired, or already used. Please create a new one.
|
||
create_failed: "Failed to connect: %{message}"
|
||
unexpected: An unexpected error occurred. Please try again.
|
||
destroy:
|
||
success: SimpleFIN connection will be removed
|
||
update:
|
||
success: SimpleFIN connection updated successfully! Your accounts are being reconnected.
|
||
errors:
|
||
blank_token: Please enter a SimpleFIN setup token.
|
||
invalid_token: Invalid setup token. Please check that you copied the complete token from SimpleFIN Bridge.
|
||
token_compromised: The setup token may be compromised, expired, or already used. Please create a new one.
|
||
update_failed: "Failed to update connection: %{message}"
|
||
unexpected: An unexpected error occurred. Please try again.
|
||
edit:
|
||
setup_token:
|
||
label: "SimpleFIN Setup Token:"
|
||
placeholder: "Paste your SimpleFIN setup token here..."
|
||
help_text: "The token should be a long string starting with letters and numbers"
|
||
setup_accounts:
|
||
account_card:
|
||
balance: "Balance"
|
||
activity:
|
||
recent:
|
||
one: "1 transaction • latest %{when}"
|
||
other: "%{count} transactions • latest %{when}"
|
||
dormant: "No activity in %{days} days"
|
||
empty: "No transactions imported yet"
|
||
likely_closed: "No recent activity and zero balance — this may be a closed or replaced card"
|
||
today: "today"
|
||
yesterday: "yesterday"
|
||
days_ago:
|
||
one: "1 day ago"
|
||
other: "%{count} days ago"
|
||
stale_accounts:
|
||
title: "Accounts No Longer in SimpleFIN"
|
||
description: "These accounts exist in your database but are no longer provided by SimpleFIN. This can happen when account configurations change upstream."
|
||
action_prompt: "What would you like to do?"
|
||
action_delete: "Delete account and all transactions"
|
||
action_move: "Move transactions to:"
|
||
action_skip: "Skip for now"
|
||
transaction_count:
|
||
one: "%{count} transaction"
|
||
other: "%{count} transactions"
|
||
complete_account_setup:
|
||
all_skipped: "All accounts were skipped. No accounts were created."
|
||
no_accounts: "No accounts to set up."
|
||
success:
|
||
one: "Successfully created %{count} SimpleFIN account! Your transactions and holdings are being imported in the background."
|
||
other: "Successfully created %{count} SimpleFIN accounts! Your transactions and holdings are being imported in the background."
|
||
stale_accounts_processed: "Stale accounts: %{deleted} deleted, %{moved} moved."
|
||
stale_accounts_errors:
|
||
one: "%{count} stale account action failed. Check logs for details."
|
||
other: "%{count} stale account actions failed. Check logs for details."
|
||
simplefin_item:
|
||
add_new: Add new connection
|
||
confirm_accept: Delete connection
|
||
confirm_body: This will permanently delete all the accounts in this group and all associated data.
|
||
confirm_title: Delete SimpleFIN connection?
|
||
delete: Delete
|
||
deletion_in_progress: "(deletion in progress...)"
|
||
error: Error occurred while syncing data
|
||
no_accounts_description: This connection doesn't have any synchronized accounts yet.
|
||
no_accounts_title: No accounts found
|
||
requires_update: Reconnect
|
||
setup_needed: New accounts ready to set up
|
||
setup_description: Choose account types for your newly imported SimpleFIN accounts.
|
||
setup_action: Set Up New Accounts
|
||
setup_accounts_menu: Set Up Accounts
|
||
more_accounts_available:
|
||
one: "%{count} more account available to set up"
|
||
other: "%{count} more accounts available to set up"
|
||
accounts_skipped_tooltip: "Some accounts were skipped due to errors during sync"
|
||
accounts_skipped_label: "Skipped: %{count}"
|
||
rate_limited_ago: "Rate limited (%{time} ago)"
|
||
rate_limited_recently: "Rate limited recently"
|
||
status: Last synced %{timestamp} ago
|
||
status_never: Never synced
|
||
status_with_summary: "Last synced %{timestamp} ago • %{summary}"
|
||
syncing: Syncing...
|
||
update: Update
|
||
stale_pending_note: "(excluded from budgets)"
|
||
stale_pending_accounts: "in: %{accounts}"
|
||
reconciled_details_note: "(see sync summary for details)"
|
||
duplicate_accounts_skipped: "Some accounts were skipped as duplicates — use 'Link existing accounts' to merge."
|
||
select_existing_account:
|
||
title: "Link %{account_name} to SimpleFIN"
|
||
description: Select a SimpleFIN account to link to your existing account
|
||
cancel: Cancel
|
||
link_account: Link account
|
||
no_accounts_found: "No SimpleFIN accounts found for this %{moniker}."
|
||
wait_for_sync: If you just connected or synced, try again after the sync completes.
|
||
unlink_to_move: To move a link, first unlink it from the account’s actions menu.
|
||
all_accounts_already_linked: All SimpleFIN accounts appear to be linked already.
|
||
currently_linked_to: "Currently linked to: %{account_name}"
|
||
|
||
link_existing_account:
|
||
success: Account successfully linked to SimpleFIN
|
||
errors:
|
||
only_manual: Only manual accounts can be linked
|
||
different_provider: This account is linked to a different provider. Unlink it from that provider first, then link to SimpleFIN.
|
||
invalid_simplefin_account: Invalid SimpleFIN account selected
|
||
dismiss_replacement_suggestion:
|
||
dismissed: Replacement suggestion dismissed
|
||
replacement_prompt:
|
||
title: "Your %{institution} card may have been replaced"
|
||
description: "“%{account_name}” is linked to “%{old_name}”, which has had no recent activity and a zero balance. A new card, “%{new_name}”, is now active at the same institution. Relink to keep your history intact."
|
||
relink: Relink to new card
|
||
confirm_title: Relink to the new card?
|
||
confirm_body: "“%{account_name}” will be linked to “%{new_name}”. Your transaction history stays; future transactions come from the new card."
|
||
dismiss_aria: Dismiss replacement suggestion
|
||
reconciled_status:
|
||
message:
|
||
one: "%{count} duplicate pending transaction reconciled"
|
||
other: "%{count} duplicate pending transactions reconciled"
|
||
stale_pending_status:
|
||
message:
|
||
one: "%{count} pending transaction older than %{days} days"
|
||
other: "%{count} pending transactions older than %{days} days"
|