diff --git a/app/models/demo/generator.rb b/app/models/demo/generator.rb index 6e623cdcd..77ce710ee 100644 --- a/app/models/demo/generator.rb +++ b/app/models/demo/generator.rb @@ -1,6 +1,10 @@ require "securerandom" class Demo::Generator + # Deterministic API key for uptime monitoring + # This key is always the same so it can be hardcoded in monitoring tools + MONITORING_API_KEY = "demo_monitoring_key_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" + # @param seed [Integer, String, nil] Seed value used to initialise the internal PRNG. If nil, the ENV variable DEMO_DATA_SEED will # be honoured and default to a random seed when not present. # @@ -93,6 +97,9 @@ class Demo::Generator puts "πŸ‘₯ Creating demo family..." family = create_family_and_users!("Demo Family", email, onboarded: true, subscribed: true) + puts "πŸ”‘ Creating monitoring API key..." + create_monitoring_api_key!(family) + puts "πŸ“Š Creating realistic financial data..." create_realistic_categories!(family) create_realistic_accounts!(family) @@ -181,6 +188,32 @@ class Demo::Generator family end + def create_monitoring_api_key!(family) + admin_user = family.users.find_by(role: "admin") + return unless admin_user + + # Find existing key scoped to this admin user by the deterministic display_key value + existing_key = admin_user.api_keys.find_by(display_key: MONITORING_API_KEY) + + if existing_key + puts " β†’ Use existing monitoring API key" + return existing_key + end + + # Revoke any existing web API keys for this user to avoid one-per-source validation error + admin_user.api_keys.active.where(source: "web").find_each(&:revoke!) + + api_key = admin_user.api_keys.create!( + name: "monitoring", + key: MONITORING_API_KEY, + scopes: [ "read" ], + source: "web" + ) + + puts " β†’ Created monitoring API key: #{MONITORING_API_KEY}" + api_key + end + def create_realistic_categories!(family) # Income categories (3 total) @salary_cat = family.categories.create!(name: "Salary", color: "#10b981", classification: "income") diff --git a/lib/tasks/demo_data.rake b/lib/tasks/demo_data.rake index 810cabfb2..7e5c2f4b3 100644 --- a/lib/tasks/demo_data.rake +++ b/lib/tasks/demo_data.rake @@ -2,9 +2,10 @@ namespace :demo_data do desc "Load empty demo dataset (no financial data)" task empty: :environment do start = Time.now - puts "πŸš€ Loading EMPTY demo data…" + skip_clear = ENV.fetch("SKIP_CLEAR", "1") == "1" + puts "πŸš€ Loading EMPTY demo data#{skip_clear ? ' (preserving existing data)' : ' (clearing existing data)'}…" - Demo::Generator.new.generate_empty_data! + Demo::Generator.new.generate_empty_data!(skip_clear: skip_clear) puts "βœ… Done in #{(Time.now - start).round(2)}s" end @@ -12,9 +13,10 @@ namespace :demo_data do desc "Load new-user demo dataset (family created but not onboarded)" task new_user: :environment do start = Time.now - puts "πŸš€ Loading NEW-USER demo data…" + skip_clear = ENV.fetch("SKIP_CLEAR", "1") == "1" + puts "πŸš€ Loading NEW-USER demo data#{skip_clear ? ' (preserving existing data)' : ' (clearing existing data)'}…" - Demo::Generator.new.generate_new_user_data! + Demo::Generator.new.generate_new_user_data!(skip_clear: skip_clear) puts "βœ… Done in #{(Time.now - start).round(2)}s" end @@ -23,10 +25,11 @@ namespace :demo_data do task default: :environment do start = Time.now seed = ENV.fetch("SEED", Random.new_seed) - puts "πŸš€ Loading FULL demo data (seed=#{seed})…" + skip_clear = ENV.fetch("SKIP_CLEAR", "1") == "1" + puts "πŸš€ Loading FULL demo data (seed=#{seed})#{skip_clear ? ' (preserving existing data)' : ' (clearing existing data)'}…" generator = Demo::Generator.new(seed: seed) - generator.generate_default_data! + generator.generate_default_data!(skip_clear: skip_clear) validate_demo_data