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>
107 lines
4.5 KiB
TOML
107 lines
4.5 KiB
TOML
# Learn more about configuring your app at https://shopify.dev/docs/apps/tools/cli/configuration
|
|
|
|
client_id = "890f611da9f31c1a8e3183b5300b2f53"
|
|
name = "Metatron-delivery"
|
|
application_url = "https://shopify.dev/apps/default-app-home"
|
|
embedded = true
|
|
|
|
[access_scopes]
|
|
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
|
|
# read_customers deliberately omitted: no feature currently calls the
|
|
# Customers API (Booking.customerEmail/customerPhone come straight off the
|
|
# orders/create webhook payload, covered by read_orders) — requesting it
|
|
# unused would also gate this app behind Shopify's Protected Customer Data
|
|
# Access approval for no reason. Add it back only when a feature (e.g. the
|
|
# "recognize returning customers" parity item) actually needs it, and
|
|
# expect to need that approval granted at that point.
|
|
scopes = "read_locales,read_locations,read_markets,read_metaobjects,read_orders,read_products,write_cart_transforms,write_delivery_customizations,write_metaobjects,write_orders,write_payment_customizations"
|
|
|
|
[auth]
|
|
redirect_urls = [ "https://shopify.dev/apps/default-app-home/api/auth" ]
|
|
|
|
[webhooks]
|
|
api_version = "2025-01"
|
|
|
|
# Handled by: app/routes/webhooks.app.uninstalled.tsx
|
|
[[webhooks.subscriptions]]
|
|
uri = "/webhooks/app/uninstalled"
|
|
topics = ["app/uninstalled"]
|
|
|
|
# Handled by: app/routes/webhooks.app.scopes_update.tsx
|
|
[[webhooks.subscriptions]]
|
|
uri = "/webhooks/app/scopes_update"
|
|
topics = ["app/scopes_update"]
|
|
|
|
# Handled by: app/routes/webhooks.orders.create.tsx
|
|
[[webhooks.subscriptions]]
|
|
uri = "/webhooks/orders/create"
|
|
topics = ["orders/create"]
|
|
|
|
# Handled by: app/routes/webhooks.orders.updated.tsx
|
|
[[webhooks.subscriptions]]
|
|
uri = "/webhooks/orders/updated"
|
|
topics = ["orders/updated"]
|
|
|
|
# Handled by: app/routes/webhooks.orders.cancelled.tsx
|
|
[[webhooks.subscriptions]]
|
|
uri = "/webhooks/orders/cancelled"
|
|
topics = ["orders/cancelled"]
|
|
|
|
# Mandatory GDPR compliance topics — required for Built-for-Shopify /
|
|
# public app review. TEMPORARILY DISABLED: `shopify app dev`/`deploy`
|
|
# refuses to push these until the org has requested and been granted
|
|
# "Protected customer data access" in the Partner Dashboard (Apps ->
|
|
# this app -> API access -> Protected customer data) — that's a manual
|
|
# questionnaire/approval step, not something the CLI or config can
|
|
# bypass. RE-ENABLE these three blocks (handlers already exist and are
|
|
# wired: app/routes/webhooks.customers.data_request.tsx,
|
|
# webhooks.customers.redact.tsx, webhooks.shop.redact.tsx) once that
|
|
# access is granted, and before any public launch/BfS submission.
|
|
|
|
# [[webhooks.subscriptions]]
|
|
# uri = "/webhooks/customers/data_request"
|
|
# compliance_topics = ["customers/data_request"]
|
|
|
|
# [[webhooks.subscriptions]]
|
|
# uri = "/webhooks/customers/redact"
|
|
# compliance_topics = ["customers/redact"]
|
|
|
|
# [[webhooks.subscriptions]]
|
|
# uri = "/webhooks/shop/redact"
|
|
# compliance_topics = ["shop/redact"]
|
|
|
|
# This org appears enrolled in Shopify's "Next Generation Events" developer
|
|
# preview (https://shopify.dev/changelog/next-generation-events-now-available-in-developer-preview),
|
|
# a separate, optional delivery mechanism from classic [webhooks] above
|
|
# (GraphQL-style resource topics + create/update/delete actions, api_version
|
|
# pinned to "unstable" while in preview). The CLI now treats [events] as a
|
|
# REQUIRED section for this app/org even though our app doesn't use it —
|
|
# everything real is handled via [webhooks]. This subscription is a
|
|
# functionally-inert placeholder that exists solely to satisfy that schema
|
|
# gate (app/routes/webhooks.events.placeholder.tsx just logs and returns
|
|
# 200) — it is not part of this app's actual feature set.
|
|
[events]
|
|
api_version = "unstable"
|
|
|
|
[[events.subscription]]
|
|
handle = "unused-events-preview-placeholder"
|
|
topic = "Product"
|
|
actions = ["create"]
|
|
uri = "/webhooks/events/placeholder"
|
|
|
|
# App proxy so the storefront Theme App Extension can call our backend
|
|
# without CORS issues (see IMPLEMENTATION_PLAN.md §5.3). `shopify app dev`
|
|
# points this at your dev tunnel automatically when
|
|
# automatically_update_urls_on_dev is true (see [build] below); if it
|
|
# doesn't, set it manually to `<your-tunnel-url>/apps/scheduling` — the
|
|
# Remix routes it forwards to (apps.scheduling.*.tsx) assume that exact
|
|
# prefix.
|
|
[app_proxy]
|
|
url = "https://replace-with-your-tunnel-url.example.com/apps/scheduling"
|
|
subpath = "scheduling"
|
|
prefix = "apps"
|
|
|
|
[build]
|
|
include_config_on_deploy = true
|
|
automatically_update_urls_on_dev = true
|