10 Commits

Author SHA1 Message Date
metatroncubeswdev
38561e9dfe fix: add missing react-reconciler peer dependency for checkout-datetime
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
@shopify/ui-extensions-react's internal @remote-ui/react dependency
requires react-reconciler as a peer dependency, which npm doesn't
auto-install — esbuild failed bundling checkout-datetime with "Could not
resolve react-reconciler" since nothing in the workspace declared it.
Added explicitly to checkout-datetime's package.json at a version
satisfying @remote-ui/react's peer range (>=0.26.0 <0.30.0); npm
workspaces hoists it to the shared root node_modules automatically,
which is where @remote-ui/react's own import resolution needs it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 23:48:42 -04:00
metatroncubeswdev
c1494cfa52 fix: real checkout-datetime version/capability fix + payment-customization schema
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
checkout-datetime (re-enabled, no longer excluded):
- api_version was declared as "2025-10" but @shopify/ui-extensions-react
  has no release for that channel at all (jumps 2025.7.4 -> 2026.0.0
  directly) — downgraded to "2025-07" to match what's actually installed
  and what the code was written/typed against. Verified all three targets
  (purchase.checkout.block.render, purchase.thank-you.block.render,
  customer-account.order-status.block.render) exist in that package
  version before making the change.
- [extensions.capabilities] network_access was missing entirely (dropped
  during the multi-pin-pickup rewrite) despite Checkout.jsx's authedFetch()
  genuinely needing it — the checkout sandbox would have silently blocked
  every fetch() call at runtime even though it deployed fine.
- OrderStatus.jsx imported reactExtension/BlockStack/Heading/Text/
  useTranslate from the *checkout* surface behind a "might not be in the
  type definition" @ts-ignore, for a *customer-account* target. Verified
  @shopify/ui-extensions-react/customer-account re-exports the same
  component names for real and switched the import, removing the
  @ts-ignore entirely — it now typechecks for real instead of being
  suppressed.
- lib.js's shared useConfirmationText() hardcoded useTranslate/
  useAttributes from the checkout surface, but was called from both
  ThankYou.jsx (checkout) and OrderStatus.jsx (customer-account) — hooks
  are bound to their surface's React context, so calling checkout-bound
  hooks from a customer-account extension would break at runtime even
  though nothing caught it statically. Changed it to a plain function
  (confirmationText) taking translate/attributes as parameters; each
  caller now calls its own surface's hooks and passes the results in.

payment-customization: schema.graphql never existed (not gitignored,
just never fetched/committed when this extension was added — HANDOVER.md's
note that this was "by design" was wrong). Fetched via
`shopify app function schema` and committed, matching the pattern already
used by validation-slot/delivery-customization.

Together these three issues were silently failing every single
`shopify app deploy` for the whole app, which is why shopify.app.toml's
App Proxy URL fix never actually reached Shopify's servers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 23:44:37 -04:00
metatroncubeswdev
aa14f34e36 chore: temporarily exclude checkout-datetime from shopify app deploy
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
Its @shopify/ui-extensions-react dependency has no release matching the
declared api_version = "2025-10" (the package jumps straight from 2025.7.4
to 2026.0.0, skipping 2025.10.x entirely) — a real migration, not a quick
version bump, and already tracked as HANDOVER.md's open item B4 ("not yet
reconciled against live checkout types").

This extension has never successfully deployed even once, so nothing
currently live regresses by excluding it — but its build failure was
aborting deploy for every OTHER extension too (esbuild fails the whole
`shopify app deploy` when any one extension can't bundle), which meant
shopify.app.toml's App Proxy URL fix never actually reached Shopify's
servers despite being correct in the repo. Renaming its config file
(shopify.extension.toml -> .disabled) excludes it from discovery without
touching its source; re-enable once B4's version migration is done by
renaming it back.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 23:34:31 -04:00
metatroncubeswdev
b29962bf9c feat: finish multi-pin pickup end-to-end; fix checkout-datetime followups
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
Multi-pin pickup selection (study §3.4) — previously a standalone unused
endpoint + TODO comments:
- app/services/pickup-locations.server.ts: pure filterPickupLocationIds +
  I/O resolvePickupLocations (active + has a PICKUP slot template +
  ProductRule allowedLocationIds + inventory exclusion).
- resolveAvailabilityRequest returns pickupLocations[] on method=PICKUP and
  defaults the active location to the first eligible pickup point.
- apps.scheduling.locations.tsx refactored onto the shared resolver
  (was a second copy of the logic).
- Storefront widget: pickup-location chooser (name + address, optional
  multi-pin Google map) when >1 eligible point and none block-configured;
  picking one re-requests availability for that location. New styles +
  widget.choose_pickup_location locale (en + fr).
- Checkout extension Checkout.jsx: same chooser before the date list.
- tests/unit/pickup-locations.test.ts (5 cases); suite 161 green.

checkout-datetime follow-up fixes from the 808a3b7 review:
- typescript devDep ^7.0.2 -> ^5.6.3 (there is no typescript@7 on npm).
- Deleted dead shopify.d.ts (Preact-global shim, unused after the React
  rewrite) and dropped it from tsconfig include.

Also stages the CLI-written `uid` lines in the checkout-datetime and
payment-customization extension tomls.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 16:47:59 -04:00
808a3b7001 changes - UI Functionality
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
2026-09-08 19:53:02 +05:30
metatroncubeswdev
a2c78d703f feat: close DS study coverage gaps (inventory exclusion, live checkout re-validation, per-day cap, payment fn, checkout ext)
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
Audited the implementation against DS_Delivery_Date_Time_App_Study.docx and
closed the actionable gaps (see IMPLEMENTATION_REVIEW_2026-09-04.md).

Core (code + unit tests, 156 green):
- Wire excludeLocationsWithoutStock into resolveAvailabilityRequest; widget
  now sends variantIds so inventory-based location exclusion actually runs.
- Live slot re-validation at checkout: new checkout-snapshot.server.ts writes
  a shop-metafield capacity snapshot; validation-slot's evaluateCheckout
  rejects a complete selection that has since filled / blacked out / closed /
  hit the daily cap / left the schedule. Refreshed on order webhooks and
  slot/blackout/location/enforcement edits.
- Scopable checkout enforcement: Shop.enforcementMode (all|tagged|off) +
  enforcementTag, new app.settings.tsx admin page, honoured via the snapshot.
- Per-day order cap: Location.dailyOrderCap threaded through getAvailability
  (dailyCap + consumedPerDate); admin field on the location screen.
- Product-rule slot blocking: ProductRule.blockedStartMins, unioned in
  resolveProductRuleConstraints, enforced in the engine and resolveHoldRequest;
  admin field on the product rules screen.
- Product-page placement: product-availability.liquid block + widget
  data-mode="preview" (read-only earliest-date line).
- Second locale: datetime-widget fr.json / fr.schema.json.
- Migration 20260904120000_review_gaps (apply with prisma migrate deploy).

New Functions (source + unit tests; need `shopify app deploy` to ship):
- extensions/payment-customization: cart.payment-methods.transform.run — hides
  cash-on-delivery / pay-in-store gateways on SHIPPING orders.
- extensions/checkout-datetime/src: restored from a gitignored dist-only state
  — Plus native picker + Thank you / Order status confirmation blocks, all
  calling the existing checkout.scheduling.* routes (one capacity pool).
  tsconfig ships checkJs:false pending reconciliation with live checkout types.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 01:31:02 -04:00
03574a4914 feat: product rules, driving-distance zones, and shipping date ranges
Closes remaining DS-parity gaps from the feature audit:

- ProductRule model (product/collection/vendor/type/tag scoping) with
  real server-side enforcement in hold-request.server.ts, plus shaped
  availability in availability-request.server.ts. Covers per-product
  prep time, cart-content-based slot blocking, and product-restricted
  locations in one mechanism. New /app/rules admin page (Growth+).
- Driving-distance delivery zones via Google's Distance Matrix API,
  cached like existing geocoding results.
- SHIPPING-only estimated arrival range (transitMinDays/transitMaxDays
  on SlotTemplate) — widget shows "Arrives Thu-Sat" instead of a
  meaningless ship-out time slot; carried through to the order
  metafield write-back.

Storefront widget and POS extension now send cart contents (vendor/
type from cart.js, product ids for Admin-API-resolved collection/tag
rules) to both availability and hold endpoints.

checkout-datetime remains excluded from this deploy pending Shopify's
Network Access approval (unrelated to this work) — re-add from
../checkout-datetime-disabled and redeploy once granted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 00:28:45 +05:30
metatroncubeswdev
4a1d4e323f fix: add missing shopify.web.toml — root cause of dev preview never loading
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
shopify.web.toml never existed at the repo root. Without it, `shopify app
dev` runs the theme/UI-extension/Function dev servers fine but never
starts the actual Remix app, and has no local dev-server port to build a
tunnel URL from for the embedded admin app — so Admin always showed the
generic "Find this app in the pages where you work" fallback, regardless
of which app record was linked, cache state, or CLI version. Root-caused
via `shopify app dev --verbose`, which showed the CLI's own reverse proxy
had a route for /extensions but none for /.

Also updates shopify.app.toml's client_id to a freshly linked app (the
previous one, and two accidental duplicates created while chasing this
bug via `dev --reset`/`config link`, were deleted from the Dev Dashboard),
resets application_url/redirect_urls to placeholders now that dev's
auto-update actually works, restores checkout-datetime's network_access
capability (briefly disabled to test an unrelated theory — confirmed not
the real cause), and widens the dev-log gitignore pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 02:15:50 -04:00
metatroncubeswdev
3f77c658d3 fix: populate empty checkout-datetime locale file
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
extensions/checkout-datetime/locales/en.default.json was an empty {}
(unlike pos-datetime and datetime-widget, which both have real content) —
shopify app dev's checkout preview refuses to start with "Locale data for
`en` is empty." Checkout.jsx/ThankYou.jsx don't call useTranslate yet (all
strings are hardcoded inline), so this just satisfies the non-empty
requirement and mirrors the extension's visible strings for when it is
wired up to i18n.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 15:13:50 -04:00
metatroncubeswdev
5b2207a397 feat: Phase 7 — POS + Checkout UI extensions
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
Also fixes the [events] gate that was blocking ALL extension generation
(discovered while starting this phase).

- shopify.app.toml: this org appears enrolled in Shopify's "Next
  Generation Events" developer preview, which the CLI now treats as a
  REQUIRED top-level [events] section even though nothing in this app
  actually uses it (real webhook handling is entirely classic [webhooks],
  unaffected). Iteratively discovered the required shape from the CLI's
  own field-by-field validation errors, then found the real docs (Events
  is optional/developer-preview, api_version pinned to "unstable") to
  confirm rather than keep guessing. Added a functionally-inert
  [[events.subscription]] placeholder + a stub handler
  (webhooks.events.placeholder.tsx) solely to satisfy the gate.

- app/services/availability-request.server.ts +
  app/services/hold-request.server.ts: extracted the resolution logic that
  used to live directly in apps.scheduling.availability.tsx/hold.tsx into
  shared functions. This is what actually makes "same capacity pool feeds
  every surface" (CLAUDE.md) true by construction rather than by
  convention — the storefront, POS, and checkout routes now call the exact
  same code, not three copies that could quietly drift apart.

- extensions/pos-datetime (generated via `shopify app generate extension
  --template=pos_smart_grid` — pos_action's flavor requirement contradicted
  the CLI's own global --flavor validator, so smart_grid was used instead):
  a home-screen tile opening a modal where staff pick method -> date -> time
  against the same availability/hold endpoints (pos.scheduling.*.tsx,
  session-token authenticated), writing the same dd_* cart properties via
  CartApi.addCartProperties — booking.server.ts needed zero changes to
  handle POS-originated orders. Several API-shape guesses (toast isError
  option, ChoiceList's `value`/`label` props, a nonexistent
  action.dismissModal(), shopify.cart.cart.current) were wrong and caught
  by typechecking directly against @shopify/ui-extensions' own bundled
  .d.ts files (`npm run typecheck:pos`, now also in CI) — none of this was
  verified against a live POS session, which isn't possible in this
  environment.

- extensions/checkout-datetime (generated via `--template=checkout_ui`):
  the Plus-only native picker in checkout itself
  (purchase.checkout.block.render) plus a Thank You confirmation block
  (purchase.thank-you.block.render). Went looking for an order-status
  target too ("all plans show confirmed slot on thank-you/order-status" is
  the Phase 7 accept criterion) and confirmed via the installed package's
  own type definitions that purchase.order-status.block.render does not
  exist in this API version — checkout UI extensions' thank-you/order-status
  surfaces are Plus-only regardless. The actual "all plans" mechanism is
  extensions/datetime-widget/blocks/order-confirmation.liquid — a new Theme
  App Extension block reading order.note_attributes, which works on every
  plan since it's plain Liquid, not checkout extensibility.

Both new UI extensions share one real unverified assumption, called out in
code comments: process.env.APP_URL is expected to be substituted at build
time by the Shopify CLI to the app's backend origin, since these run in a
different origin than the app and need an absolute URL, unlike the
storefront widget's relative /apps/scheduling/* path. Needs confirming
against a live dev session.

Verified: lint, typecheck (root + both new extensions'
`npm run typecheck:pos`/`typecheck:checkout`, all now in CI), 102 unit +
18 integration tests (unchanged — this phase didn't touch pure business
logic, only added thin auth wrappers around already-tested services), both
admin/widget builds.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 09:11:34 -04:00