mirror of
https://github.com/we-promise/sure.git
synced 2026-08-05 16:42:18 +00:00
* Fix two crashes in `rake demo_data:default` - Demo::Generator#generate_credit_card_cycles!: the balance-adjust step created a $0 "Balance Adjust" transfer whenever a card's balance was already under its target (negative diff), which fails Transfer's opposite-amounts validation (a transfer can't have a zero amount). Only create the adjustment transfer when the diff is actually positive. - Demo::DataCleaner#destroy_everything!: ApiKey has a before_destroy guard (prevent_demo_monitoring_key_destroy!) that throws :abort to stop the demo monitoring key being revoked from the UI. That abort silently no-ops the whole Family.destroy_all cascade below it (accounts/entries/ trades all survive undestroyed), which only then surfaces downstream as a NOT NULL violation in Security.destroy_all. Delete the demo monitoring key directly (bypassing callbacks) before destroying families; safe since this class is dev/test only. Verified end-to-end: db:drop/create/schema:load, then `rake demo_data:default` followed by `SKIP_CLEAR=0 rake demo_data:default` (exercises both the generation and the clear-and-regenerate paths) complete without error. * Reconcile below-target card balances with a charge instead of skipping The previous fix avoided the $0 transfer crash by skipping the balance adjustment entirely when a card's ending balance landed more than $250 under its target, but that let demo_data:default finish with Amex/Sapphire balances far from their documented targets. A transfer can't carry a negative payment amount, so when the diff is negative, add a direct "Balance Reconciliation" charge on the card instead of a transfer. Verified across 10 seeds: Sapphire now lands exactly on its $4,200 target instead of drifting below it, with no validation errors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
41 lines
1.3 KiB
Ruby
41 lines
1.3 KiB
Ruby
# SAFETY: Only operates in development/test environments to prevent data loss
|
|
class Demo::DataCleaner
|
|
SAFE_ENVIRONMENTS = %w[development test]
|
|
|
|
def initialize
|
|
ensure_safe_environment!
|
|
end
|
|
|
|
# Main entry point for destroying all demo data
|
|
def destroy_everything!
|
|
# Clear SSO audit logs first (they reference users)
|
|
SsoAuditLog.destroy_all
|
|
|
|
# ApiKey#prevent_demo_monitoring_key_destroy! throws :abort to stop the demo
|
|
# monitoring key being revoked from the UI. That abort silently no-ops the
|
|
# entire Family.destroy_all cascade below (accounts/entries/trades all
|
|
# survive), which only then surfaces as a NOT NULL crash in
|
|
# `Security.destroy_all`. Safe to bypass here: this class only runs in
|
|
# dev/test (see #ensure_safe_environment!).
|
|
|
|
ApiKey.where(display_key: ApiKey::DEMO_MONITORING_KEY).delete_all
|
|
|
|
Family.destroy_all
|
|
Setting.destroy_all
|
|
InviteCode.destroy_all
|
|
ExchangeRate.destroy_all
|
|
Security.destroy_all
|
|
Security::Price.destroy_all
|
|
|
|
puts "Data cleared"
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_safe_environment!
|
|
unless SAFE_ENVIRONMENTS.include?(Rails.env)
|
|
raise SecurityError, "Demo::DataCleaner can only be used in #{SAFE_ENVIRONMENTS.join(', ')} environments. Current: #{Rails.env}"
|
|
end
|
|
end
|
|
end
|