```ruby
module Keymail
  module Authentication
    def self.request(email)
      # TODO: initializers for expires_at
      raise ArgumentError, 'Email cannot be nil' if email.nil?

      token = Token.create(email: email, expires_at: 10.minutes.since)
      AuthMailer.log_in(token).deliver

      token
    end

    def self.verify_url_key(url_key)
      token = Token.find_by(url_key: url_key)
      token.destroy! unless token.nil? # this does not destroy the reference, only the entry

      return Failure.new if token.nil?
      return Expired.new(token) if token.expired?

      Success.new(token)
    end
  end

  class TokenResponse
    def initialize(token)
      @token = token
    end
    delegate :email, :expired?, to: :@token
  end

  class Success < TokenResponse
    def authenticated?
      true
    end
  end

  class Expired < TokenResponse
    def authenticated?
      false
    end
  end

  class Failure
    def authenticated?
      false
    end
  end
end
```

Use bang methods, god the errors are awful without it...
user
```ruby
module Keymail
  module Authentication
    def self.request(email)
      # TODO: initializers for expires_at
      raise ArgumentError, 'Email cannot be nil' if email.nil?

      token = Token.create!(email: email, expires_at: 10.minutes.since)
      AuthMailer.log_in(token).deliver

      token
    end

    def self.verify_url_key(url_key)
      token = Token.find_by(url_key: url_key)
      token.destroy! unless token.nil? # this does not destroy the reference, only the entry

      return Failure.new if token.nil?
      return Expired.new(token) if token.expired?

      Success.new(token)
    end
  end

  class TokenResponse
    def initialize(token)
      @token = token
    end
    delegate :email, :expired?, to: :@token
  end

  class Success < TokenResponse
    def authenticated?
      true
    end
  end

  class Expired < TokenResponse
    def authenticated?
      false
    end
  end

  class Failure
    def authenticated?
      false
    end
  end
end
```
assistant