- New custom server.js (replaces react-router-serve): ISO timestamps on
all console.* output and on access logs, and skip successful /healthz
polls so real traffic stays visible.
- New ProcessedWebhook table + dedupe helper keyed on
X-Shopify-Webhook-Id; stops Shopify retries from triggering a second
invoice email when the original delivery exceeded the 5s ack timeout.
- orders/create + orders/fulfilled now respond 200 immediately and run
the PDF/email work in the background so we stay under that timeout.
- pickLanguage(): non-German locales (it, fr, es, ...) now default to
English instead of falling back to German. Empty/unknown still maps to
'de' so the per-shop defaultLanguage chain keeps working.
- Tests for pickLanguage and dedupe via node --test + tsx.
- Drop wireTransferGatewayNames from ShopSettings (new migration).
- Replace string-matching with a GraphQL query against
Order.transactions[].manualPaymentGateway, the first-class flag
Shopify exposes for any merchant-defined manual payment method.
- Both webhook handlers now fetch the order on the fly to classify it,
removing the configurable gateway-names field from settings.
- New ShopSettings fields: autoEmailOnWireTransferPlaced,
autoEmailOnFulfilledNonWireTransfer, wireTransferGatewayNames.
- New Automations section in settings with two toggles + gateway list.
- orders/create webhook now fires automation 1 (wire-transfer placed).
- New orders/fulfilled webhook fires automation 2 (non-wire-transfer fulfilled).
- Shared helper services/invoice/automations.server.ts handles classification
and idempotent generate+send (skips if already sent).
- Webhook subscription for orders/fulfilled added to all 3 app tomls.
This is the non-Plus fallback for Shopify Flow, whose custom-app actions
are gated to Plus stores only.