diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8e97fa00c..fbd69f579 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -100,8 +100,8 @@ DATABASE_URL=trilogy://user:password@host:port/database?encoding=utf8mb4&collati - Running mise should have run `rake db:seed` - This will populate the basic data needed to use the app -- To add more sample data for development, run `rake db:dev:seed` - - This will add sample workshops, community news, stories, resources, FAQs, and more +- To add more sample data for development, run `rake db:seed:dev` + - This will add sample workshops, community news, stories, resources, FAQs, payments, and more - To see your data - The home page will show Workshops, CommunityNews, Resources, Events, and Stories - The [Admin Home](http://localhost:3000/admin) provides CRUD access for most models diff --git a/db/seeds.rb b/db/seeds.rb index 974c1e0f4..87612402c 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,10 +1,6 @@ # Disable email delivery during seeding ActionMailer::Base.perform_deliveries = false -def seed(file) - require_relative "seeds/#{file}" -end - puts "Creating Users…" # Helper: case-insensitive find-or-create by name @@ -488,5 +484,3 @@ def find_or_create_by_name!(klass, name, **attrs, &block) end cat.update!(published: true) unless cat.published? end - -seed "payments" diff --git a/db/seeds/dummy_dev_seeds.rb b/db/seeds/dev/dummy.rb similarity index 96% rename from db/seeds/dummy_dev_seeds.rb rename to db/seeds/dev/dummy.rb index 4ca1e5724..d4c1a4e80 100644 --- a/db/seeds/dummy_dev_seeds.rb +++ b/db/seeds/dev/dummy.rb @@ -1502,91 +1502,6 @@ end end -puts "Creating Scholarships, Payments, and Allocations…" -# Gives the paid dev events real money + scholarship records so the event -# overview dashboard (registrants / received / outstanding / scholarships) -# shows meaningful numbers. Registrations and applications (registration-form -# submissions) are created above; this fills in the financial side. -# -# Each registration is funded at most once — the guard skips any registration -# that already has allocations, so the section is safe to re-run. - -org_payer = Organization.find_by(name: "Angel Step Inn") - -# Mirrors ScholarshipsController: build the scholarship with a $0 allocation, -# then set the amount + tasks_completed so sync_allocation_amount funds the -# allocation only when the recipient's tasks are complete. -award_scholarship = ->(registration, amount_cents:, tasks_completed:) do - scholarship = Scholarship.new(recipient: registration.registrant) - scholarship.build_allocation(allocatable: registration, amount: 0) - scholarship.save! - scholarship.update!(amount_cents: amount_cents, tasks_completed: tasks_completed) - scholarship -end - -# payer is a Person or an Organization; kind is :cash or :check. -record_payment = ->(registration, payer:, amount_cents:, kind: :cash) do - payer_attrs = payer.is_a?(Organization) ? { organization: payer } : { person: payer } - created_at = rand(3..30).days.ago - payment = case kind - when :check - CheckPayment.create!(**payer_attrs, amount_cents: amount_cents, check_number: "CHK-#{rand(10_000..99_999)}", created_at: created_at) - else - CashPayment.create!(**payer_attrs, amount_cents: amount_cents, created_at: created_at) - end - Allocation.create!(source: payment, allocatable: registration, amount: amount_cents, created_at: created_at) -end - -# Funds a registration once. `scholarship` and `payments` describe what to build. -fund_registration = ->(event, person, scholarship: nil, payments: []) do - return unless event && person - registration = EventRegistration.find_by(event: event, registrant: person) - return unless registration - return if registration.allocations.exists? - - award_scholarship.(registration, **scholarship) if scholarship - payments.each { |payment| record_payment.(registration, **payment) } -end - -# --- AWBW Facilitator Training ($150) --- -# Amy: pending scholarship (tasks incomplete → $0 allocated) + partial cash → still owes -fund_registration.(facilitator_training, amy_person, - scholarship: { amount_cents: 10_000, tasks_completed: false }, - payments: [ { payer: amy_person, amount_cents: 5_000, kind: :cash } ]) -# Maria: paid in full by cash -fund_registration.(facilitator_training, maria_j, - payments: [ { payer: maria_j, amount_cents: 15_000, kind: :cash } ]) -# Anna: paid in full by check from her organization (org-payer scenario) -fund_registration.(facilitator_training, anna_g, - payments: [ { payer: org_payer || anna_g, amount_cents: 15_000, kind: :check } ]) -# Mario: partial cash → still owes -fund_registration.(facilitator_training, mario_j, - payments: [ { payer: mario_j, amount_cents: 5_000, kind: :cash } ]) - -# --- Facilitator Training: Trauma-Informed Art Practices ($120) --- -# Sarah: paid in full by check -fund_registration.(trauma_training, sarah_s, - payments: [ { payer: sarah_s, amount_cents: 12_000, kind: :check } ]) -# Jessica: completed scholarship ($80) + cash for the remainder → paid in full -fund_registration.(trauma_training, jessica_b, - scholarship: { amount_cents: 8_000, tasks_completed: true }, - payments: [ { payer: jessica_b, amount_cents: 4_000, kind: :cash } ]) -# Angel: partial cash → still owes -fund_registration.(trauma_training, angel_g, - payments: [ { payer: angel_g, amount_cents: 6_000, kind: :cash } ]) - -# --- Mindful Art for Survivors Workshop ($50) --- -# Amy: paid in full by cash -fund_registration.(mindful_art, amy_person, - payments: [ { payer: amy_person, amount_cents: 5_000, kind: :cash } ]) - -[ facilitator_training, trauma_training, mindful_art ].compact.each do |event| - dashboard = EventDashboard.new(event) - puts " #{event.title}: #{dashboard.registrant_count} registrants, " \ - "received #{dashboard.received_cents / 100.0}, outstanding #{dashboard.outstanding_cents / 100.0}, " \ - "scholarships #{dashboard.scholarship_total_cents / 100.0} (#{dashboard.scholarship_recipient_count})" -end - puts "Creating Resources…" 10.times do |i| kind = Resource::PUBLISHED_KINDS.sample diff --git a/db/seeds/dev/payments.rb b/db/seeds/dev/payments.rb new file mode 100644 index 000000000..88107f15e --- /dev/null +++ b/db/seeds/dev/payments.rb @@ -0,0 +1,278 @@ +# Payment seeds (dev-only) - run on their own via `rake db:seed:payments`, or +# as part of `rake db:seed:dev`. + +puts "Seeding Payments, Allocations, and Refunds..." + +payment_ids_start = Payment.maximum(:id) || 0 +allocation_ids_start = Allocation.maximum(:id) || 0 +refund_ids_start = Refund.maximum(:id) || 0 +event_reg_ids_start = EventRegistration.maximum(:id) || 0 + +Refund.where("id > ?", refund_ids_start).delete_all +Allocation.where("id > ?", allocation_ids_start).delete_all +Payment.where("id > ?", payment_ids_start).delete_all +EventRegistration.where("id > ?", event_reg_ids_start).delete_all + +event_cost_cents = 150000 + +bob = Person.find_or_create_by!(email: "bob.payment@seed.example.com") do |p| + p.first_name = "Bob" + p.last_name = "Barker" +end + +alice = Person.find_or_create_by!(email: "alice.payment@seed.example.com") do |p| + p.first_name = "Alice" + p.last_name = "Test" +end + +charlie = Person.find_or_create_by!(email: "charlie.payment@seed.example.com") do |p| + p.first_name = "Charlie" + p.last_name = "Test" +end + +diana = Person.find_or_create_by!(email: "diana.payment@seed.example.com") do |p| + p.first_name = "Diana" + p.last_name = "Test" +end + +eve = Person.find_or_create_by!(email: "eve.payment@seed.example.com") do |p| + p.first_name = "Eve" + p.last_name = "Test" +end + +frank = Person.find_or_create_by!(email: "frank.payment@seed.example.com") do |p| + p.first_name = "Frank" + p.last_name = "Test" +end + +gary = Person.find_or_create_by!(email: "gary.payment@seed.example.com") do |p| + p.first_name = "Gary" + p.last_name = "Test" +end + +holly = Person.find_or_create_by!(email: "holly.payment@seed.example.com") do |p| + p.first_name = "Holly" + p.last_name = "Test" +end + +iris = Person.find_or_create_by!(email: "iris.payment@seed.example.com") do |p| + p.first_name = "Iris" + p.last_name = "Test" +end + +event = Event.find_or_create_by!(title: "Test Payments Workshop") do |e| + e.start_date = 1.month.from_now.to_date + e.end_date = 1.month.from_now.to_date + 2.days + e.published = true + e.cost_cents = event_cost_cents +end +event.update!(start_date: 1.month.from_now.to_date, end_date: 1.month.from_now.to_date + 2.days, published: true, cost_cents: event_cost_cents) + +reg_bob = EventRegistration.find_or_create_by!(registrant: bob, event: event) +reg_alice = EventRegistration.find_or_create_by!(registrant: alice, event: event) +reg_charlie = EventRegistration.find_or_create_by!(registrant: charlie, event: event) +reg_diana = EventRegistration.find_or_create_by!(registrant: diana, event: event) +reg_eve = EventRegistration.find_or_create_by!(registrant: eve, event: event) +reg_frank = EventRegistration.find_or_create_by!(registrant: frank, event: event) +reg_gary = EventRegistration.find_or_create_by!(registrant: gary, event: event) +reg_iris = EventRegistration.find_or_create_by!(registrant: iris, event: event) + +puts " Payment made but allocation reverted)" +payment1 = CashPayment.find_or_create_by!( + person: bob, + amount_cents: event_cost_cents +) do |p| + p.created_at = 5.days.ago +end +original_allocation1 = Allocation.create!( + source: payment1, + allocatable: reg_bob, + amount: event_cost_cents, + created_at: 5.days.ago +) +reversal_allocation1 = Allocation.create!( + source: payment1, + allocatable: reg_bob, + amount: -event_cost_cents, + created_at: 4.days.ago +) +original_allocation1.update!(reverted_id: reversal_allocation1.id) + +puts " Overpayment with full allocation (Alice pays $6000, covers 4 people)" +payment2 = CashPayment.find_or_create_by!( + person: alice, + amount_cents: 600000 +) do |p| + p.created_at = 4.days.ago +end +Allocation.find_or_create_by!(source: payment2, allocatable: reg_alice, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } +Allocation.find_or_create_by!(source: payment2, allocatable: reg_charlie, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } +Allocation.find_or_create_by!(source: payment2, allocatable: reg_diana, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } +Allocation.find_or_create_by!(source: payment2, allocatable: reg_eve, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } + +puts " Payment with remaining available ($2000 payment, $1500 allocated, $500 remaining)" +payment3 = CashPayment.find_or_create_by!( + person: frank, + amount_cents: 200000 +) do |p| + p.created_at = 3.days.ago +end +Allocation.find_or_create_by!( + source: payment3, + allocatable: reg_frank, + amount: 150000 +) do |a| + a.created_at = 3.days.ago +end + +puts " Full refund ($1500 payment, fully allocated, fully refunded)" +payment4 = CashPayment.find_or_create_by!( + person: gary, + amount_cents: event_cost_cents +) do |p| + p.created_at = 2.days.ago +end +original_alloc = Allocation.create!( + source: payment4, + allocatable: reg_gary, + amount: event_cost_cents, + created_at: 2.days.ago +) +reversal_alloc = Allocation.create!( + source: payment4, + allocatable: reg_gary, + amount: -event_cost_cents, + created_at: 1.day.ago +) +original_alloc.update!(reverted_id: reversal_alloc.id) +Refund.create!( + refundable: payment4, + recipient: gary, + amount_cents: event_cost_cents, + method: "check", + created_at: 1.day.ago +) + +puts " Creating Scenario 8: Payment with no allocations ($10000, full amount remaining)" +CashPayment.find_or_create_by!( + person: holly, + amount_cents: 1000000 +) do |p| + p.created_at = 7.days.ago +end + +puts " Partial payment" +payment9 = CashPayment.find_or_create_by!( + person: iris, + amount_cents: 100000 +) do |p| + p.created_at = 3.days.ago +end +Allocation.find_or_create_by!( + source: payment9, + allocatable: reg_iris, + amount: 100000 +) do |a| + a.created_at = 3.days.ago +end + +puts "Creating Scholarships, Payments, and Allocations for dev events…" +# Funds registrations on the paid dev events with real money + scholarship +# records so the event overview dashboard (registrants / received / outstanding +# / scholarships) shows meaningful numbers. The events, people, and registrations +# are created in db/seeds/dev/dummy.rb, so this only fills in the financial side +# when the dummy seeds have already run (e.g. via `rake db:seed:dev`); on its own +# `rake db:seed:payments` simply skips events that aren't present. +# +# Each registration is funded at most once — the guard skips any registration +# that already has allocations, so the section is safe to re-run. + +amy_person = User.find_by(email: "amy.user@example.com")&.person +maria_j = Person.find_by(first_name: "Maria", last_name: "Johnson") +anna_g = Person.find_by(first_name: "Anna", last_name: "Garcia") +sarah_s = Person.find_by(first_name: "Sarah", last_name: "Smith") +jessica_b = Person.find_by(first_name: "Jessica", last_name: "Brown") +mario_j = Person.find_by(first_name: "Mario", last_name: "Johnson") +angel_g = Person.find_by(first_name: "Angel", last_name: "Garcia") + +facilitator_training = Event.find_by(title: "AWBW Facilitator Training") +trauma_training = Event.find_by(title: "Facilitator Training: Trauma-Informed Art Practices") +mindful_art = Event.find_by(title: "Mindful Art for Survivors Workshop") + +org_payer = Organization.find_by(name: "Angel Step Inn") + +# Mirrors ScholarshipsController: build the scholarship with a $0 allocation, +# then set the amount + tasks_completed so sync_allocation_amount funds the +# allocation only when the recipient's tasks are complete. +award_scholarship = ->(registration, amount_cents:, tasks_completed:) do + scholarship = Scholarship.new(recipient: registration.registrant) + scholarship.build_allocation(allocatable: registration, amount: 0) + scholarship.save! + scholarship.update!(amount_cents: amount_cents, tasks_completed: tasks_completed) + scholarship +end + +# payer is a Person or an Organization; kind is :cash or :check. +record_payment = ->(registration, payer:, amount_cents:, kind: :cash) do + payer_attrs = payer.is_a?(Organization) ? { organization: payer } : { person: payer } + created_at = rand(3..30).days.ago + payment = case kind + when :check + CheckPayment.create!(**payer_attrs, amount_cents: amount_cents, check_number: "CHK-#{rand(10_000..99_999)}", created_at: created_at) + else + CashPayment.create!(**payer_attrs, amount_cents: amount_cents, created_at: created_at) + end + Allocation.create!(source: payment, allocatable: registration, amount: amount_cents, created_at: created_at) +end + +# Funds a registration once. `scholarship` and `payments` describe what to build. +fund_registration = ->(event, person, scholarship: nil, payments: []) do + return unless event && person + registration = EventRegistration.find_by(event: event, registrant: person) + return unless registration + return if registration.allocations.exists? + + award_scholarship.(registration, **scholarship) if scholarship + payments.each { |payment| record_payment.(registration, **payment) } +end + +# --- AWBW Facilitator Training ($150) --- +# Amy: pending scholarship (tasks incomplete → $0 allocated) + partial cash → still owes +fund_registration.(facilitator_training, amy_person, + scholarship: { amount_cents: 10_000, tasks_completed: false }, + payments: [ { payer: amy_person, amount_cents: 5_000, kind: :cash } ]) +# Maria: paid in full by cash +fund_registration.(facilitator_training, maria_j, + payments: [ { payer: maria_j, amount_cents: 15_000, kind: :cash } ]) +# Anna: paid in full by check from her organization (org-payer scenario) +fund_registration.(facilitator_training, anna_g, + payments: [ { payer: org_payer || anna_g, amount_cents: 15_000, kind: :check } ]) +# Mario: partial cash → still owes +fund_registration.(facilitator_training, mario_j, + payments: [ { payer: mario_j, amount_cents: 5_000, kind: :cash } ]) + +# --- Facilitator Training: Trauma-Informed Art Practices ($120) --- +# Sarah: paid in full by check +fund_registration.(trauma_training, sarah_s, + payments: [ { payer: sarah_s, amount_cents: 12_000, kind: :check } ]) +# Jessica: completed scholarship ($80) + cash for the remainder → paid in full +fund_registration.(trauma_training, jessica_b, + scholarship: { amount_cents: 8_000, tasks_completed: true }, + payments: [ { payer: jessica_b, amount_cents: 4_000, kind: :cash } ]) +# Angel: partial cash → still owes +fund_registration.(trauma_training, angel_g, + payments: [ { payer: angel_g, amount_cents: 6_000, kind: :cash } ]) + +# --- Mindful Art for Survivors Workshop ($50) --- +# Amy: paid in full by cash +fund_registration.(mindful_art, amy_person, + payments: [ { payer: amy_person, amount_cents: 5_000, kind: :cash } ]) + +[ facilitator_training, trauma_training, mindful_art ].compact.each do |event| + dashboard = EventDashboard.new(event) + puts " #{event.title}: #{dashboard.registrant_count} registrants, " \ + "received #{dashboard.received_cents / 100.0}, outstanding #{dashboard.outstanding_cents / 100.0}, " \ + "scholarships #{dashboard.scholarship_total_cents / 100.0} (#{dashboard.scholarship_recipient_count})" +end + +puts " Payment seeds complete!" diff --git a/db/seeds/payments.rb b/db/seeds/payments.rb deleted file mode 100644 index f946bffd2..000000000 --- a/db/seeds/payments.rb +++ /dev/null @@ -1,179 +0,0 @@ - # Payment seeds - can be run independently - # Usage: "rails runner db/seeds/payments.rb" - - puts "Seeding Payments, Allocations, and Refunds..." - - payment_ids_start = Payment.maximum(:id) || 0 - allocation_ids_start = Allocation.maximum(:id) || 0 - refund_ids_start = Refund.maximum(:id) || 0 - event_reg_ids_start = EventRegistration.maximum(:id) || 0 - - Refund.where("id > ?", refund_ids_start).delete_all - Allocation.where("id > ?", allocation_ids_start).delete_all - Payment.where("id > ?", payment_ids_start).delete_all - EventRegistration.where("id > ?", event_reg_ids_start).delete_all - - event_cost_cents = 150000 - - bob = Person.find_or_create_by!(email: "bob.payment@seed.example.com") do |p| - p.first_name = "Bob" - p.last_name = "Barker" - end - - alice = Person.find_or_create_by!(email: "alice.payment@seed.example.com") do |p| - p.first_name = "Alice" - p.last_name = "Test" - end - - charlie = Person.find_or_create_by!(email: "charlie.payment@seed.example.com") do |p| - p.first_name = "Charlie" - p.last_name = "Test" - end - - diana = Person.find_or_create_by!(email: "diana.payment@seed.example.com") do |p| - p.first_name = "Diana" - p.last_name = "Test" - end - - eve = Person.find_or_create_by!(email: "eve.payment@seed.example.com") do |p| - p.first_name = "Eve" - p.last_name = "Test" - end - - frank = Person.find_or_create_by!(email: "frank.payment@seed.example.com") do |p| - p.first_name = "Frank" - p.last_name = "Test" - end - - gary = Person.find_or_create_by!(email: "gary.payment@seed.example.com") do |p| - p.first_name = "Gary" - p.last_name = "Test" - end - - holly = Person.find_or_create_by!(email: "holly.payment@seed.example.com") do |p| - p.first_name = "Holly" - p.last_name = "Test" - end - - iris = Person.find_or_create_by!(email: "iris.payment@seed.example.com") do |p| - p.first_name = "Iris" - p.last_name = "Test" - end - - event = Event.find_or_create_by!(title: "Test Payments Workshop") do |e| - e.start_date = 1.month.from_now.to_date - e.end_date = 1.month.from_now.to_date + 2.days - e.published = true - e.cost_cents = event_cost_cents - end - event.update!(start_date: 1.month.from_now.to_date, end_date: 1.month.from_now.to_date + 2.days, published: true, cost_cents: event_cost_cents) - - reg_bob = EventRegistration.find_or_create_by!(registrant: bob, event: event) - reg_alice = EventRegistration.find_or_create_by!(registrant: alice, event: event) - reg_charlie = EventRegistration.find_or_create_by!(registrant: charlie, event: event) - reg_diana = EventRegistration.find_or_create_by!(registrant: diana, event: event) - reg_eve = EventRegistration.find_or_create_by!(registrant: eve, event: event) - reg_frank = EventRegistration.find_or_create_by!(registrant: frank, event: event) - reg_gary = EventRegistration.find_or_create_by!(registrant: gary, event: event) - reg_iris = EventRegistration.find_or_create_by!(registrant: iris, event: event) - - puts " Payment made but allocation reverted)" - payment1 = CashPayment.find_or_create_by!( - person: bob, - amount_cents: event_cost_cents - ) do |p| - p.created_at = 5.days.ago - end - original_allocation1 = Allocation.create!( - source: payment1, - allocatable: reg_bob, - amount: event_cost_cents, - created_at: 5.days.ago - ) - reversal_allocation1 = Allocation.create!( - source: payment1, - allocatable: reg_bob, - amount: -event_cost_cents, - created_at: 4.days.ago - ) - original_allocation1.update!(reverted_id: reversal_allocation1.id) - - puts " Overpayment with full allocation (Alice pays $6000, covers 4 people)" - payment2 = CashPayment.find_or_create_by!( - person: alice, - amount_cents: 600000 - ) do |p| - p.created_at = 4.days.ago - end - Allocation.find_or_create_by!(source: payment2, allocatable: reg_alice, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } - Allocation.find_or_create_by!(source: payment2, allocatable: reg_charlie, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } - Allocation.find_or_create_by!(source: payment2, allocatable: reg_diana, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } - Allocation.find_or_create_by!(source: payment2, allocatable: reg_eve, amount: event_cost_cents) { |a| a.created_at = 4.days.ago } - - puts " Payment with remaining available ($2000 payment, $1500 allocated, $500 remaining)" - payment3 = CashPayment.find_or_create_by!( - person: frank, - amount_cents: 200000 - ) do |p| - p.created_at = 3.days.ago - end - Allocation.find_or_create_by!( - source: payment3, - allocatable: reg_frank, - amount: 150000 - ) do |a| - a.created_at = 3.days.ago - end - - puts " Full refund ($1500 payment, fully allocated, fully refunded)" - payment4 = CashPayment.find_or_create_by!( - person: gary, - amount_cents: event_cost_cents - ) do |p| - p.created_at = 2.days.ago - end - original_alloc = Allocation.create!( - source: payment4, - allocatable: reg_gary, - amount: event_cost_cents, - created_at: 2.days.ago - ) - reversal_alloc = Allocation.create!( - source: payment4, - allocatable: reg_gary, - amount: -event_cost_cents, - created_at: 1.day.ago - ) - original_alloc.update!(reverted_id: reversal_alloc.id) - Refund.create!( - refundable: payment4, - recipient: gary, - amount_cents: event_cost_cents, - method: "check", - created_at: 1.day.ago - ) - - puts " Creating Scenario 8: Payment with no allocations ($10000, full amount remaining)" - CashPayment.find_or_create_by!( - person: holly, - amount_cents: 1000000 - ) do |p| - p.created_at = 7.days.ago - end - - puts " Partial payment" - payment9 = CashPayment.find_or_create_by!( - person: iris, - amount_cents: 100000 - ) do |p| - p.created_at = 3.days.ago - end - Allocation.find_or_create_by!( - source: payment9, - allocatable: reg_iris, - amount: 100000 - ) do |a| - a.created_at = 3.days.ago - end - - puts " Payment seeds complete!" diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index ed649734d..b64fdc035 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -1,8 +1,16 @@ namespace :db do - namespace :dev do - desc "Generate dev seed data" - task seed: [ :environment, "db:seed" ] do - load Rails.root.join("db/seeds/dummy_dev_seeds.rb") + namespace :seed do + desc "Generate representative sample data for development" + task dev: [ :environment, "db:seed", "db:seed:dummy", "db:seed:payments" ] + + desc "Seed generic dummy dev data (workshops, people, stories, etc.)" + task dummy: :environment do + load Rails.root.join("db/seeds/dev/dummy.rb") + end + + desc "Seed sample payments, allocations, and refunds (dev only)" + task payments: :environment do + load Rails.root.join("db/seeds/dev/payments.rb") end end end