- ensureShop: concurrent installs reuse the row created by the other request (P2002)
- order tagging and booking metafield log Shopify userErrors instead of failing silently
- widget keeps a readable 760px width in full-width theme sections
- setup guide links to Shopify's pickup settings so checkout offers pickup
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- storefront applied maxLocations to the first locations by priority, even switched-off
ones, so a Starter shop whose enabled location wasn't first got no methods
- switching on a location beyond the plan limit now explains why instead of being ignored
- widget shows a message (en/fr) when no method is available and clears aria-busy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Prisma extension seals booking name/email/phone/address and waitlist contacts with
AES-256-GCM on write and opens them on read (incl. nested reads)
- keyed-hash columns for exact email/phone lookups (privacy webhooks, booking search,
waitlist de-duplication); migration 0002
- tests prove only ciphertext is stored; privacy/terms/SECURITY.md updated to match
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>