- send through the sendgrid v3 json api via direct fetch with a
manually cleared abort timeout; mailhog stays for development
- drop nodemailer-mailgun-transport and its types
- swap MAILGUN_* runtime config and env example for SENDGRID_API_KEY
and optional SENDGRID_HOST
Formatting splits a sentence across text nodes mid-phrase, and no model
reliably reproduces a fragment's leading or trailing whitespace — a dropped
edge space glues two words together once the fragments are concatenated
back into the document. The source fragment now decides the edges.
- translateText/translateTexts call OpenRouter chat-completions; glossary
terms are prompt-injected from config/glossaries.ts, generated from the
translation repo's TSVs by scripts/build-glossaries.ts
- model resolution: per-language override in config/languages.ts →
translation.model site setting (new admin field) → TRANSLATION_MODEL env
→ anthropic/claude-opus-5, at low reasoning effort
- blank fragments are held back from the model, which drops them and breaks
the one-translation-per-fragment count the caller maps results back on
- OpenRouter failures map to a typed error with a human-readable message;
an unrecoverable one (no credits, bad key, rejected model) stops the run
instead of repeating the same call for every remaining locale
- machine translations record source 'auto-translate'; 'deepl' stays
readable for snapshots written before the switch
* replace country pages with region dashboards
- move /countries to /regions, with 301 redirects from the old URLs in
every locale
- add a region dashboard: a map of the region's countries with pins
coloured by prayer coverage, headline figures, and prayer, adoption and
engagement progress against the DOXA goals, plus a per-country table
- roll up progress stats per country and region in the shared summary
and serve them from /api/regions
- frame region maps with antimeridian-aware bounds
- add Regions to the hamburger menu and translate the new strings in all
eight locales
* put each region on the regions index in a card with a header band
The region name links to its dashboard with the site's chevron icon, and
the people-group and country counts sit centred beside it on a brand-green
header; the country list is the padded white card body.
add /countries index grouped by WAGF region and /countries/[country] pages
derive countries from prayer API (slug, count, map center/zoom) via config/countries-meta and /api/countries
prerender country routes for all locales via modules/country-routes
add CountryMap component: highlight focus country, brand-green in-country pins, muted border pins, popups
show bold green note above the map stating people-group count
lock UupgsList to a country and link card country names to country pages
add i18n keys for the new strings
add framework-agnostic vimeo tiptap node (id-only src, renders player iframe)
register vimeo in shared extension set for editor and server renderer
replace youtube prompt with generic insert-video modal (detects platform)
allowlist vimeo in validator with digits-only src check
track vimeo as a lossy node for markdown round-trip detection