feat: Add admin user creation support and fix user entity

This commit is contained in:
2026-03-27 13:37:07 -07:00
parent 4935b146e5
commit 99571be9a1
5 changed files with 94 additions and 5 deletions
+5 -4
View File
@@ -20,14 +20,15 @@ module EuchreCamp
end end
# Create new user # Create new user
def create(email:, password_digest:, player_id:) def create(email:, password_digest:, player_id:, role: 'player', confirmed: false)
users.changeset(:create, { users.changeset(:create, {
email: email, email: email,
password_digest: password_digest, password_digest: password_digest,
player_id: player_id, player_id: player_id,
confirmed: false, role: role,
confirmation_token: generate_token, confirmed: confirmed,
confirmation_sent_at: Time.now confirmation_token: confirmed ? nil : generate_token,
confirmation_sent_at: confirmed ? nil : Time.now
}).commit }).commit
end end
+1 -1
View File
@@ -7,7 +7,7 @@ ROM::SQL.migration do
foreign_key :player_id, :players, null: false foreign_key :player_id, :players, null: false
column :email, String, null: false, unique: true column :email, String, null: false, unique: true
column :password_digest, String, null: false column :password_digest, String, null: false
column :confirmed, Boolean, default: false column :confirmed, TrueClass, default: false
column :confirmation_token, String column :confirmation_token, String
column :confirmation_sent_at, DateTime column :confirmation_sent_at, DateTime
column :reset_password_token, String column :reset_password_token, String
+1
View File
@@ -7,6 +7,7 @@ module EuchreCamp
attribute :player_id, Types::Integer attribute :player_id, Types::Integer
attribute :email, Types::String attribute :email, Types::String
attribute :password_digest, Types::String attribute :password_digest, Types::String
attribute :role, Types::String, default: 'player'
attribute :confirmed, Types::Bool attribute :confirmed, Types::Bool
attribute? :confirmation_token, Types::String.optional attribute? :confirmation_token, Types::String.optional
attribute? :confirmation_sent_at, Types::Time.optional attribute? :confirmation_sent_at, Types::Time.optional
@@ -0,0 +1,28 @@
# frozen_string_literal: true
module EuchreCamp
module Persistence
module Relations
class Users < ROM::Relation[:sql]
schema(:users, infer: true) do
attribute :id, ROM::Types::Integer, primary_key: true
attribute :player_id, ROM::Types::Integer
attribute :email, ROM::Types::String
attribute :password_digest, ROM::Types::String
attribute :role, ROM::Types::String
attribute :confirmed, ROM::Types::Bool
attribute :confirmation_token, ROM::Types::String.optional
attribute :confirmation_sent_at, ROM::Types::Time.optional
attribute :reset_password_token, ROM::Types::String.optional
attribute :reset_password_sent_at, ROM::Types::Time.optional
attribute :failed_login_attempts, ROM::Types::Integer
attribute :locked_until, ROM::Types::Time.optional
attribute :last_login_at, ROM::Types::Time.optional
attribute :last_login_ip, ROM::Types::String.optional
attribute :created_at, ROM::Types::Time
attribute :updated_at, ROM::Types::Time
end
end
end
end
end
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require_relative '../config/app'
require 'hanami/prepare'
require 'bcrypt'
# Get arguments
email = ARGV[0] || 'david@dhg.lol'
password = ARGV[1] || 'admin'
if password.nil?
puts "Error: Password required"
puts "Usage: ruby scripts/create_admin.rb [email] [password]"
exit 1
end
puts "Creating admin user..."
puts "Email: #{email}"
# Initialize repositories
players_repo = EuchreCamp::App['repositories.players']
users_repo = EuchreCamp::App['repositories.users']
# Check if user already exists
existing_user = users_repo.by_email(email)
if existing_user
puts "User #{email} already exists with ID #{existing_user.id}"
puts "Updating role to club_admin..."
users_repo.users.where(id: existing_user.id).update(role: 'club_admin', confirmed: true)
puts "Done!"
exit 0
end
# Create player
player = players_repo.create(name: email.split('@').first.capitalize, rating: 1000)
puts "Created player with ID: #{player[:id]}"
# Hash password
password_digest = BCrypt::Password.create(password)
puts "Password hashed"
# Create user
user = users_repo.create(
email: email,
password_digest: password_digest,
player_id: player[:id],
role: 'club_admin',
confirmed: true
)
puts ""
puts "✅ Admin user created successfully!"
puts " Email: #{email}"
puts " Player ID: #{player[:id]}"
puts " Role: club_admin"
puts " Confirmed: true"
puts ""
puts "Login at: http://localhost:2300/login"