# Script for populating the database. You can run it as: # # mix run priv/repo/seeds.exs # # Safe to run multiple times — all inserts use get_or_insert patterns so # existing rows are not duplicated. import Ecto.Query, warn: false alias DaProductApp.Repo alias DaProductApp.Users.{User, Module, Permission} alias DaProductApp.Merchants.Merchant alias DaProductApp.Providers.Provider alias DaProductApp.TerminalManagement.{TmsTerminal, TerminalGroup} alias DaProductApp.ParameterManagement.ParameterCategory # --------------------------------------------------------------------------- # Helper — idempotent module + permission upsert # --------------------------------------------------------------------------- get_or_create_module = fn name, description -> case Repo.get_by(Module, name: name) do nil -> Repo.insert!(%Module{name: name, description: description, active: true}) existing -> existing end end get_or_create_permission = fn module, name, description -> case Repo.get_by(Permission, name: name) do nil -> Repo.insert!(%Permission{ name: name, description: description, module_id: module.id, active: true }) existing -> # Update description in case it changed, keep module_id stable if existing.description != description do Repo.update!(Ecto.Changeset.change(existing, description: description)) else existing end end end # --------------------------------------------------------------------------- # Modules # --------------------------------------------------------------------------- user_module = get_or_create_module.("User Management", "User and authentication management") terminal_module = get_or_create_module.("Terminal Management", "Terminal device management") transaction_module = get_or_create_module.("Transaction Management","Payment transaction management") settlement_module = get_or_create_module.("Settlement Management", "Payment settlement processing") recon_module = get_or_create_module.("Reconciliation", "Transaction reconciliation and exception handling") config_version_module = get_or_create_module.("Config Version Management", "Parameter and EMV config version lifecycle management") # --------------------------------------------------------------------------- # User Management permissions # --------------------------------------------------------------------------- get_or_create_permission.(user_module, "users.account.view", "View user accounts") get_or_create_permission.(user_module, "users.account.edit", "Create and edit user accounts") get_or_create_permission.(user_module, "users.account.delete", "Delete user accounts") get_or_create_permission.(user_module, "users.role.assign", "Assign roles to users") get_or_create_permission.(user_module, "users.permission.view", "View user permissions") get_or_create_permission.(user_module, "users.permission.manage", "Grant and revoke permissions") # --------------------------------------------------------------------------- # Terminal Management permissions # --------------------------------------------------------------------------- get_or_create_permission.(terminal_module, "terminal.device.view", "View terminal devices") get_or_create_permission.(terminal_module, "terminal.device.edit", "Create and edit terminal devices") # --------------------------------------------------------------------------- # Transaction Management permissions # --------------------------------------------------------------------------- get_or_create_permission.(transaction_module, "transaction.record.view", "View transaction records") # --------------------------------------------------------------------------- # Settlement permissions # --------------------------------------------------------------------------- get_or_create_permission.(settlement_module, "settlement.dashboard.view", "View settlement dashboard") get_or_create_permission.(settlement_module, "settlement.files.view", "View settlement files") get_or_create_permission.(settlement_module, "settlement.mis.view", "View MIS reports") get_or_create_permission.(settlement_module, "settlement.mis.generate", "Generate MIS reports") get_or_create_permission.(settlement_module, "settlement.mis.approve_l1", "Level-1 approve MIS") get_or_create_permission.(settlement_module, "settlement.mis.approve_l2", "Level-2 approve MIS") get_or_create_permission.(settlement_module, "settlement.mis.reject", "Reject MIS reports") get_or_create_permission.(settlement_module, "settlement.adjustments.view", "View merchant adjustments") get_or_create_permission.(settlement_module, "settlement.adjustments.edit", "Create and edit adjustments") get_or_create_permission.(settlement_module, "settlement.payouts.view", "View payout batches") get_or_create_permission.(settlement_module, "settlement.payouts.transmit", "Transmit payout batches to bank") get_or_create_permission.(settlement_module, "settlement.payouts.reinitiate", "Re-initiate failed payouts") get_or_create_permission.(settlement_module, "settlement.risk_holds.view", "View risk-held transactions") get_or_create_permission.(settlement_module, "settlement.risk_holds.release", "Release risk-held transactions") get_or_create_permission.(settlement_module, "settlement.tid_master.view", "View TID master records") get_or_create_permission.(settlement_module, "settlement.merchant_portal.view", "View merchant settlement portal") # --------------------------------------------------------------------------- # Reconciliation permissions # --------------------------------------------------------------------------- get_or_create_permission.(recon_module, "reconciliation.exceptions.view", "View reconciliation exceptions") get_or_create_permission.(recon_module, "reconciliation.exceptions.release", "Release reconciliation exceptions") get_or_create_permission.(recon_module, "reconciliation.exceptions.bulk_release", "Bulk-release reconciliation exceptions") # --------------------------------------------------------------------------- # Config Version Management permissions # --------------------------------------------------------------------------- get_or_create_permission.(config_version_module, "config.version.view", "View config file versions (EMV, keys)") get_or_create_permission.(config_version_module, "config.version.manage", "Register new config versions and set active version") get_or_create_permission.(config_version_module, "config.compliance.view", "View terminal version compliance dashboard") get_or_create_permission.(config_version_module, "config.compliance.remediate", "Trigger re-push for outdated terminals") # --------------------------------------------------------------------------- # Default admin user (idempotent) # --------------------------------------------------------------------------- _admin_user = case Repo.get_by(User, email: "admin@example.com") do nil -> Repo.insert!(%User{ email: "admin@example.com", hashed_password: Bcrypt.hash_pwd_salt("admin123"), confirmed_at: DateTime.utc_now() |> DateTime.truncate(:second), role: :superuser, name: "System Administrator", first_name: "Admin", last_name: "User" }) existing -> existing end # --------------------------------------------------------------------------- # Sample providers (idempotent) # --------------------------------------------------------------------------- unless Repo.get_by(Provider, name: "Alipay") do Repo.insert!(%Provider{ name: "Alipay", status: "active", production_url: "https://api.alipay.com", production_mode: "sandbox", description: "Alipay payment gateway" }) end unless Repo.get_by(Provider, name: "WeChat Pay") do Repo.insert!(%Provider{ name: "WeChat Pay", status: "active", production_url: "https://api.wechatpay.com", production_mode: "sandbox", description: "WeChat Pay payment gateway" }) end # --------------------------------------------------------------------------- # Sample merchants (idempotent) # --------------------------------------------------------------------------- unless Repo.get_by(Merchant, merchant_id: "MERCH001") do Repo.insert!(%Merchant{ id: Ecto.UUID.generate(), name: "Sample Restaurant", email: "restaurant@example.com", phone: "+1234567890", status: "active", merchant_id: "MERCH001", category: "Cat B", mcc_code: "5812", risk_tier: "Mid-Market Merchant" }) end unless Repo.get_by(Merchant, merchant_id: "MERCH002") do Repo.insert!(%Merchant{ id: Ecto.UUID.generate(), name: "Sample Retail Store", email: "retail@example.com", phone: "+1234567891", status: "active", merchant_id: "MERCH002", category: "Cat C", mcc_code: "5732", risk_tier: "Known Entity" }) end # --------------------------------------------------------------------------- # Sample terminal groups + terminals (idempotent) # --------------------------------------------------------------------------- group1 = Repo.get_by(TerminalGroup, name: "Restaurant Terminals") || Repo.insert!(%TerminalGroup{ name: "Restaurant Terminals", description: "Terminals deployed in restaurant locations", is_active: true }) group2 = Repo.get_by(TerminalGroup, name: "Retail Terminals") || Repo.insert!(%TerminalGroup{ name: "Retail Terminals", description: "Terminals deployed in retail locations", is_active: true }) unless Repo.get_by(TmsTerminal, serial_number: "T001234567890") do Repo.insert!(%TmsTerminal{ serial_number: "T001234567890", status: "online", model: "POS-X1", vendor: "TechCorp", area: "North Zone", group: group1.name, merchant_id: "MERCH001", app_version: "1.0.0", data_version: "1.0.0", system_version: "1.0.0" }) end unless Repo.get_by(TmsTerminal, serial_number: "T001234567891") do Repo.insert!(%TmsTerminal{ serial_number: "T001234567891", status: "online", model: "POS-X2", vendor: "TechCorp", area: "South Zone", group: group2.name, merchant_id: "MERCH002", app_version: "1.0.0", data_version: "1.0.0", system_version: "1.0.0" }) end # --------------------------------------------------------------------------- # Parameter categories (idempotent) # --------------------------------------------------------------------------- for {name, desc} <- [ {"Network Configuration", "Network and connectivity settings"}, {"Display Settings", "Screen and UI configuration"}, {"Payment Settings", "Payment processing configuration"} ] do unless Repo.get_by(ParameterCategory, name: name) do Repo.insert!(%ParameterCategory{name: name, description: desc, is_active: true}) end end IO.puts("Database seeded successfully!") IO.puts("Admin user: admin@example.com / admin123") IO.puts("Modules: #{Repo.aggregate(Module, :count, :id)}") IO.puts("Permissions: #{Repo.aggregate(Permission, :count, :id)}") IO.puts("Users: #{Repo.aggregate(User, :count, :id)}") IO.puts("Merchants: #{Repo.aggregate(Merchant, :count, :id)}") IO.puts("Terminals: #{Repo.aggregate(TmsTerminal, :count, :id)}") # Seed Risk Management rules IO.puts("Seeding risk management rules...") DaProductApp.RiskManagement.Seeds.seed_risk_rules()