fix(observability,webhooks,i18n): timestamped logs, dedupe webhook retries, default non-de locales to English
- 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.
This commit is contained in:
@@ -167,11 +167,19 @@ const en: InvoiceStrings = {
|
||||
paidStamp: "PAID",
|
||||
};
|
||||
|
||||
// Locale → invoice language. We only render in German (`de`) when the
|
||||
// caller is explicitly German-speaking (de, de-AT, de-DE, de_CH, …).
|
||||
// Everything else (it, fr, es, en, …) falls back to English so that
|
||||
// non-German-speaking customers don't receive a German invoice. Callers
|
||||
// that have a per-shop default fall back to it via
|
||||
// `pickLanguage(customerLocale ?? settings.defaultLanguage)`, which is why
|
||||
// `null`/`undefined` still maps to `de` (the legacy default for the
|
||||
// Austrian shops this app was built for).
|
||||
export function pickLanguage(input: string | null | undefined): InvoiceLanguage {
|
||||
if (!input) return "de";
|
||||
const v = input.toLowerCase();
|
||||
if (v.startsWith("en")) return "en";
|
||||
return "de";
|
||||
if (v.startsWith("de")) return "de";
|
||||
return "en";
|
||||
}
|
||||
|
||||
export function getStrings(language: InvoiceLanguage): InvoiceStrings {
|
||||
|
||||
Reference in New Issue
Block a user