contacts: mint web-created contact ids with ChangeId
The web form's contacts get twelve letters, not a UUID's thirty-six;
put overwrites a match, and 48 bits keeps that out of the mix.
Assisted-by: Claude Opus 5 via Claude Code
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
diff --git a/lib/pro_tacts/web/contacts.rb b/lib/pro_tacts/web/contacts.rb
index 1066d81..b7f95f1 100644
--- a/lib/pro_tacts/web/contacts.rb
+++ b/lib/pro_tacts/web/contacts.rb
@@ -1,10 +1,9 @@
-require "securerandom"
-
require "pro_tacts/admin/card_form"
require "pro_tacts/admin/contact_dialog"
require "pro_tacts/admin/contacts_edit"
require "pro_tacts/admin/contacts_index"
require "pro_tacts/admin/contacts_show"
+require "pro_tacts/change_id"
module ProTacts
class Web < Roda
@@ -37,7 +36,9 @@ module ProTacts
if first.empty? && last.empty?
dashboard(query: r.params["q"], notice: "A contact needs a name.")
else
- id = SecureRandom.uuid
+ # Store#put overwrites, so the width has to make a collision
+ # unthinkable rather than caught: 48 bits, for a family's book.
+ id = ChangeId.mint(12)
store.put(id, Admin::CardForm.new_card(id, first, last))
r.redirect "/contacts/#{id}", 303
end
diff --git a/test/pro_tacts/admin/test_contacts_pages.rb b/test/pro_tacts/admin/test_contacts_pages.rb
index 1bc5f57..8edd47c 100644
--- a/test/pro_tacts/admin/test_contacts_pages.rb
+++ b/test/pro_tacts/admin/test_contacts_pages.rb
@@ -857,7 +857,7 @@ class AdminContactsPagesTest < Minitest::Test
assert_equal 303, last_response.status
id = last_response["Location"].delete_prefix("/contacts/")
- assert_match(/\A[\w-]+\z/, id)
+ assert_match(/\A[k-z]{12}\z/, id)
follow_redirect!
assert_equal 200, last_response.status