Class: AgentCode::Commands::InvitationLinkCommand

Inherits:
BaseCommand
  • Object
show all
Defined in:
lib/agentcode/commands/invitation_link_command.rb

Overview

Generate an invitation link for testing — mirrors Laravel php artisan invitation:link exactly.

Usage: rails invitation:link EMAIL ORG [--role=ROLE] [--create]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeInvitationLinkCommand

Returns a new instance of InvitationLinkCommand.



13
14
15
16
# File 'lib/agentcode/commands/invitation_link_command.rb', line 13

def initialize
  super
  @options = { role: nil, create: false }
end

Instance Attribute Details

#emailObject

Returns the value of attribute email.



11
12
13
# File 'lib/agentcode/commands/invitation_link_command.rb', line 11

def email
  @email
end

#optionsObject

Returns the value of attribute options.



11
12
13
# File 'lib/agentcode/commands/invitation_link_command.rb', line 11

def options
  @options
end

#organization_identifierObject

Returns the value of attribute organization_identifier.



11
12
13
# File 'lib/agentcode/commands/invitation_link_command.rb', line 11

def organization_identifier
  @organization_identifier
end

Instance Method Details

#perform(email = @email, organization_identifier = @organization_identifier) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/agentcode/commands/invitation_link_command.rb', line 18

def perform(email = @email, organization_identifier = @organization_identifier)
  role_identifier = options[:role]
  should_create = options[:create]

  # Find organization
  identifier_column = AgentCode.config.multi_tenant[:organization_identifier_column] || "slug"

  org_class = "Organization".safe_constantize
  unless org_class
    say "Organization model not found.", :red
    return
  end

  organization = org_class.find_by(identifier_column => organization_identifier)

  unless organization
    say "Organization '#{organization_identifier}' not found.", :red
    return
  end

  # Find or create invitation
  invitation = OrganizationInvitation
                 .where(email: email, organization_id: organization.id, status: "pending")
                 .first

  if !invitation && !should_create
    say "No pending invitation found for '#{email}' in organization '#{organization.name}'.", :red
    say "Use --create flag to create a new invitation."
    return
  end

  if !invitation && should_create
    unless role_identifier
      say "Role is required when creating a new invitation. Use --role option.", :red
      return
    end

    role_class = "Role".safe_constantize
    unless role_class
      say "Role model not found.", :red
      return
    end

    role = if role_identifier.match?(/\A\d+\z/)
             role_class.find_by(id: role_identifier)
           else
             role_class.find_by(slug: role_identifier)
           end

    unless role
      say "Role '#{role_identifier}' not found.", :red
      return
    end

    user_class = "User".safe_constantize
    invited_by = user_class&.first

    unless invited_by
      say "No user found to assign as 'invited_by'. Please create a user first.", :red
      return
    end

    invitation = OrganizationInvitation.create!(
      organization_id: organization.id,
      email: email,
      role_id: role.id,
      invited_by: invited_by.id
    )

    say "Created new invitation for #{email}.", :green
  end

  # Build the invitation URL
  frontend_url = ENV.fetch("FRONTEND_URL", "http://localhost:5173")
  url = "#{frontend_url}/accept-invitation?token=#{invitation.token}"

  say ""
  say "Invitation link for #{email}:", :green
  say url
  say ""
  say "Token: #{invitation.token}"
  say "Organization: #{organization.name} (#{organization.try(:slug) || organization.id})"
  say "Role: #{invitation.role&.name}" if invitation.respond_to?(:role) && invitation.role
  say "Status: #{invitation.status}"
  say "Expires: #{invitation.expires_at&.strftime('%Y-%m-%d %H:%M:%S')}" if invitation.expires_at
  say ""
end