mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
Add deterministic API key for uptime monitoring (#834)
* Preserve existing demo data by default Add SKIP_CLEAR environment variable to demo_data rake tasks. Defaults to true (preserving existing data). Set SKIP_CLEAR=0 to wipe data before generating new demo data. https://claude.ai/code/session_01GcoMc2SH3czPrbeGkHbmpE * Add deterministic instatus.com API key for demo data Create a read-only API key named "instatus.com" with a fixed value when generating demo data. This allows uptime monitoring tools to use a hardcoded API key that doesn't change between demo data runs. The key is idempotent - if it already exists, it will be reused. https://claude.ai/code/session_01GcoMc2SH3czPrbeGkHbmpE * OK to name instatus to a point * Remove all Instatus references * Rename to create_monitoring_api_key! and scope lookup to admin_user - Rename create_instatus_api_key! to create_monitoring_api_key! (snake_case) - Scope API key lookup to admin_user instead of global ApiKey lookup - Each family's admin now has their own monitoring API key https://claude.ai/code/session_01GcoMc2SH3czPrbeGkHbmpE --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
require "securerandom"
|
require "securerandom"
|
||||||
|
|
||||||
class Demo::Generator
|
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
|
# @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.
|
# be honoured and default to a random seed when not present.
|
||||||
#
|
#
|
||||||
@@ -93,6 +97,9 @@ class Demo::Generator
|
|||||||
puts "👥 Creating demo family..."
|
puts "👥 Creating demo family..."
|
||||||
family = create_family_and_users!("Demo Family", email, onboarded: true, subscribed: true)
|
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..."
|
puts "📊 Creating realistic financial data..."
|
||||||
create_realistic_categories!(family)
|
create_realistic_categories!(family)
|
||||||
create_realistic_accounts!(family)
|
create_realistic_accounts!(family)
|
||||||
@@ -181,6 +188,32 @@ class Demo::Generator
|
|||||||
family
|
family
|
||||||
end
|
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)
|
def create_realistic_categories!(family)
|
||||||
# Income categories (3 total)
|
# Income categories (3 total)
|
||||||
@salary_cat = family.categories.create!(name: "Salary", color: "#10b981", classification: "income")
|
@salary_cat = family.categories.create!(name: "Salary", color: "#10b981", classification: "income")
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ namespace :demo_data do
|
|||||||
desc "Load empty demo dataset (no financial data)"
|
desc "Load empty demo dataset (no financial data)"
|
||||||
task empty: :environment do
|
task empty: :environment do
|
||||||
start = Time.now
|
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"
|
puts "✅ Done in #{(Time.now - start).round(2)}s"
|
||||||
end
|
end
|
||||||
@@ -12,9 +13,10 @@ namespace :demo_data do
|
|||||||
desc "Load new-user demo dataset (family created but not onboarded)"
|
desc "Load new-user demo dataset (family created but not onboarded)"
|
||||||
task new_user: :environment do
|
task new_user: :environment do
|
||||||
start = Time.now
|
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"
|
puts "✅ Done in #{(Time.now - start).round(2)}s"
|
||||||
end
|
end
|
||||||
@@ -23,10 +25,11 @@ namespace :demo_data do
|
|||||||
task default: :environment do
|
task default: :environment do
|
||||||
start = Time.now
|
start = Time.now
|
||||||
seed = ENV.fetch("SEED", Random.new_seed)
|
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 = Demo::Generator.new(seed: seed)
|
||||||
generator.generate_default_data!
|
generator.generate_default_data!(skip_clear: skip_clear)
|
||||||
|
|
||||||
validate_demo_data
|
validate_demo_data
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user