ואיך את יודעת מה המערכת עושה?
ביקשתי מהסוכן מנגנון שמוציא הזמנות למשתמשים מהמערכת כך שאני אוכל להקליד אימייל של משתמש והוא יקבל הזמנה לנסות את המוצר שלי. ניסיתי את המנגנון ושלחתי הזמנות לכמה כתובות מייל שלי וגם לחברים והכל עבד. ווידאתי גם שאפשר לבטל הזמנות ושאם שלחתי הזמנה ואז אני מבטל אותה או פג תוקף ההזמנה אז אי אפשר להשתמש בה כדי להירשם.
ובכל הניסויים האלה לא ראיתי סעיף אחד שגם לא היה כתוב באיפיון. הנה מה שהקוד מספר לי:
class IssueInvitation
class Rejected < StandardError; end
def self.call(email:, admin:)
raise Rejected, I18n.t("admin.forbidden") unless admin.admin?
token = SecureRandom.urlsafe_base64(32)
invitation = nil
# Serialize issue/resend calls, including invitations without an existing row.
admin.with_lock do
invitation = Invitation.find_or_initialize_by(email: email.to_s.strip.downcase)
raise Rejected, I18n.t("admin.invitations.existing_user") if User.exists?(email: invitation.email)
if invitation.accepted_at?
raise Rejected, I18n.t("admin.invitations.already_accepted")
end
if invitation.last_sent_at && invitation.last_sent_at > 1.minute.ago
raise Rejected, I18n.t("admin.invitations.cooldown")
end
invitation.assign_attributes(invited_by: admin, token_digest: Invitation.digest(token),
expires_at: 7.days.from_now, last_sent_at: Time.current)
invitation.save!
end
InvitationDeliveryJob.perform_later(invitation.id, token)
invitation
end
end
הסוכן יצר מנגנון קירור כדי לוודא שאני לא שולח יותר מדי הזמנות, אלה השורות:
if invitation.last_sent_at && invitation.last_sent_at > 1.minute.ago
raise Rejected, I18n.t("admin.invitations.cooldown")
end
בנוסף אני רואה שכל שליחת הזמנה מעדכנת token של ההזמנה כך שאם אני שולח מספר הזמנות לאותה כתובת הנמען יכול להשתמש רק בהזמנה האחרונה. אלה השורות:
token = SecureRandom.urlsafe_base64(32)
...
invitation.assign_attributes(invited_by: admin, token_digest: Invitation.digest(token),
expires_at: 7.days.from_now, last_sent_at: Time.current)
אנחנו בונים על הסוכן שיוסיף מנגנונים קטנים בכל פיצ'ר שאנחנו מאפיינים כי אי אפשר בתיאור פיצ'ר להתיחס לכל הדברים שצריכים או לא צריכים להיות בפיצ'ר (אחרת האיפיון היה הקוד). מכאן אנחנו חייבים לקבל שהאיפיון אינו תיאור מדויק של המערכת. התיאור המדויק היחיד הוא הקוד, זה כל מה שיש.
איפיון מספר מה אני רוצה שהמוצר יעשה. ניסוי ועבודה על המערכת מלמדים אותנו על התנהגות המוצר. קוד מלמד אותנו על ההתנהגות שלא ניסינו.