30 Commits

Author SHA1 Message Date
metatroncubeswdev
3f1a07382b fix(billing): open Shopify's plan approval page instead of showing 401
billing.request throws a 401 with the approval URL in X-Shopify-API-Request-Failure-Reauthorize-Url for App Bridge to follow, but a React Router form submission rendered it as an error page. The action now returns the URL and the page opens it at the top level. Invalid-session retries are still rethrown for App Bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:14:37 -04:00
metatroncubeswdev
6061877ca1 fix(review): no shop-domain form on /auth/login; test charges on dev stores
- /auth/login no longer asks for a myshopify domain (App Store 2.3.1). With
  ?shop= it still hands off to OAuth; otherwise it points to Shopify.
- Billing API charges are test charges outside production and on partner
  development stores (shop.plan.partnerDevelopment), so reviewers can pick a
  paid plan. Real shops are charged as before.
- SCREENCAST.md matches the recording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:07:22 -04:00
metatroncubeswdev
a5941a5149 fix(locations): drop Shopify's literal "null" city from imported addresses
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 07:17:43 -04:00
metatroncubeswdev
0a979becc3 feat: restore checkout functions after reinstall; sync listing copy
Shopify deletes an app's validation and delivery/payment customizations on
uninstall. Datewise now remembers which ones were on (settings.checkoutFunctions,
kept in sync with Shopify whenever Settings loads) and switches them back on
when a shop reinstalls.

LISTING.md and alt text updated to what the listing form accepted (5 features,
20-char search terms, 64-char alt text, no "plan" outside pricing).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 06:50:55 -04:00
metatroncubeswdev
b7ef11f31e docs: session handoff for finishing the App Store submission
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:33:35 -04:00
metatroncubeswdev
49dab343ed docs(listing): screencast scene plan, captions and YouTube copy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:25:12 -04:00
metatroncubeswdev
21f16a6eeb feat(listing): all six screenshots; setup guide notes Shopify's pickup estimate
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:02:33 -04:00
metatroncubeswdev
244de30d34 feat(listing): screenshots, framing script, listing copy; bookings list polish
- brand/make_screenshots.py frames raw shots at 1600x900 with captions + alt text
- brand/LISTING.md: introduction, details, features, search terms, testing steps
- bookings filters no longer overflow; footer reads '1 booking'; no empty pager

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:26:26 -04:00
metatroncubeswdev
3798d2365f fix(widget): selected day/slot text stays visible under theme button styles
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:20:06 -04:00
metatroncubeswdev
c102594ca5 feat(security): log staff access to customers' personal data
DataAccessLog records bookings list/view/export and run-sheet views (actor, action,
target, time); pruned after 12 months by the worker; migration 0003.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:18:44 -04:00
metatroncubeswdev
ee8056efc2 fix: install race, silent Admin API errors, widget width; pickup setup hint
- 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>
2026-10-15 13:15:36 -04:00
metatroncubeswdev
aacd9a8e06 fix: plan location limit counts switched-on locations; widget empty state
- 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>
2026-10-15 05:26:03 -04:00
metatroncubeswdev
38e82f791e fix: allow form actions from the app domain behind the HTTPS proxy
React Router's CSRF check compared https Origin with the http URL seen behind Nginx,
rejecting every admin form save with 400.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:06:05 -04:00
metatroncubeswdev
23f259fcc8 fix(admin): create or revive the shop record on first admin load instead of 404
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:01:59 -04:00
metatroncubeswdev
59de2b9d34 chore(config): link to the new 'Datewise: Delivery & Pickup' app (client_id 7e7c4baa…)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 04:44:32 -04:00
metatroncubeswdev
40d1752739 chore(config): app handle datewise-delivery ('datewise' is taken on Shopify)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:03:55 -04:00
metatroncubeswdev
467347e902 fix(deploy): worker builds the image too instead of pulling 'datewise' from Docker Hub
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 01:14:51 -04:00
metatroncubeswdev
db85f3263d fix(build): make every extension build for shopify app deploy
- functions: add codegen config and the downloaded schema.graphql (generated/ ignored)
- order-reschedule: add the @preact/signals peer dependency
- widget: source moved to widget-src/, minified build in assets (npm run build:widget,
  also run by predeploy); e2e passes on the minified file

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 00:47:08 -04:00
metatroncubeswdev
3ca60ef174 chore(config): link to the Datewise app on Shopify (client_id)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 00:41:54 -04:00
metatroncubeswdev
4aadc4b85a fix(order-reschedule): point the extension at the production app URL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:04:17 -04:00
metatroncubeswdev
5995fd42ec docs(deploy): real clone URL in the server runbook
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:28:24 -04:00
metatroncubeswdev
1d2d943d54 feat(security): encrypt customer personal data at rest
- 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>
2026-10-14 18:56:05 -04:00
metatroncubeswdev
1e19b773cd chore: make backup.sh executable
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:53:30 -04:00
metatroncubeswdev
bd2e3906df chore(deploy): Docker stack for the VPS (db, app, worker; Caddy or existing Nginx)
- multi-stage Dockerfile; worker bundled to build/worker.mjs (no tsx at runtime)
- docker-compose.yml + docker-compose.nginx.yml (127.0.0.1:3320), Nginx site, encrypted backups
- production URLs (datewise.metatronlabz.com) in shopify.app.toml; URL auto-update off
- verified locally: healthz/landing/privacy/terms 200, unsigned proxy/webhook 400, worker starts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:53:08 -04:00
metatroncubeswdev
f96ab10634 feat(brand): brand assets at Shopify sizes; public landing, privacy and terms
- brand/: 1200x1200 full-bleed app icon, 1600x900 feature image, transparent logos,
  favicons, guidelines (palette, type, usage) and the build script
- / is now a branded landing page with no shop-domain form (App Store 2.3.1)
- /privacy and /terms describe Datewise's actual data handling and sub-processors

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:26:12 -04:00
metatroncubeswdev
893b0f6ada fix(admin): theme editor deep links use block file handles
activateAppId pointed at a non-existent 'datewise-embed' handle; the embed is 'embed'.
Adds an addAppBlockId link that places the scheduler block on the cart template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:23:21 -04:00
metatroncubeswdev
85ed1a8f0e feat: delivery-label and payment-rules checkout functions with Settings toggles
- delivery-label renames only options matching the chosen method (en/fr dates)
- payment-rules hides COD / pay-in-store for shipped orders
- functions matched by handle (fixes guard lookup matching any 'datewise' title)
- scopes: write_delivery_customizations, write_payment_customizations

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:21:55 -04:00
metatroncubeswdev
67b86cf411 feat(admin): setup guide on Today page with live step status
Shared checkout-guard lookup moved to app/lib/guard.server.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:18:42 -04:00
metatroncubeswdev
123ca71d42 feat(widget): restyle storefront scheduler; booking stub with hold countdown
- segmented method control with line icons
- round calendar days with availability dots and scarcity badges
- pill time chips; confirmation stub shows method, place, date, time, fee
- colours derive from theme text colour + one merchant accent (light/dark safe)
- rename leftover ss- internals to dw-

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:17:09 -04:00
metatroncubeswdev
e56182e0e3 chore: initial Datewise app (rebranded from SlotSure prototype)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:06:49 -04:00