All deployments

Peter Theill
Peter Theill 
deployed a styling change 1 day ago
Support
Support 
deployed a feature 1 day ago
1 day ago
✨ Add finish messages for media generation ✨ Enhance image selection and download functionality ✨ Enhance image thumbnail interaction ✨ Enhance zoom functionality in video preview ✨ Introduce image preview URL handling ✨ Introduce video patch builder and improve UI ✨ Introduce video review sections and editable notes ✨ Update image and video animation messages
Peter Theill
Peter Theill 
deployed a feature 3 days ago
3 days ago
✨ MCP endpoint for importing donations from Facebook groups (#24)
Adds an MCP server at POST /mcp so an AI agent can turn posts from a public
Facebook group into donations on Forward.
The server never touches Facebook. The agent does the reading, with its own
browser session and its own membership of the groups; the endpoint only turns
"here is a post" into a record. That keeps scraping out of the application and
leaves the MCP surface small enough to stay stable.
Three properties are enforced structurally rather than by convention:

  • Imports are drafts. A new `draft` state is invisible everywhere, because


every listing already goes through `active`, and the direct URL 404s for
anybody but its owner. Watch alerts are held back until `publish!`.

  • Imports are credited to the original poster. `user_id` stays the importing


account - a row needs an owner, and that is who to ask about it - while the
donation is attributed to `source_author_name` and links to `source_url`.
Imports are not requestable, because the importer does not have the item;
visitors are sent to the original post instead. `create_donation` requires
both fields, so there is no way to use this endpoint to post something as
your own.

  • Re-scanning a group is safe. `source_url` is unique at the database, and is


normalised to drop fbclid, mibextid and friends first, so the second import
of a post is refused rather than duplicated.
Two changes fall out of the ownership split. The donor-currency check is
skipped for imports, since `user` is the importer and their region says nothing
about the market the donation belongs to - somebody in Copenhagen curating a
Stockholm group is importing SEK donations, and that is correct. To keep the
invariant that check was protecting, `User#update_stats!` now counts only
donations the user posted themselves, so a curator is neither credited for
items they never had nor able to mix currencies into their totals. The region
and charity checks are untouched.
`list_charities` takes a region and returns only charities whose currency
matches it. The currency rule is the constraint an agent would otherwise trip
over on most calls, and answering it in the tool signature beats answering it
in an error message.
Image URLs arrive from a page an agent was told to go and read, so they are
attacker-influenced in the ordinary case. `RemoteImageFetcher` is https-only,
resolves the host and checks every address it resolves to, pins the connection
to the address it checked, and re-runs all of that per redirect hop.
Authentication is a bearer token rather than the session cookie, because the
caller is not a browser. Tokens are stored as HMAC digests, shown once, can be
named and renamed, and are rate limited per token.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
⬆️ Upgrade libraries
💸 Scope donation currency to the market (#23)
Currency becomes a property of the region a donation happens in rather than
something the donor picks per item.

  • a region owns the currency; a charity accepts exactly one, which keeps its


total raised a single figure

  • a donation copies its region's currency and validates it against the region,


the charity and the donor's own region

  • the locale decides only how an amount is punctuated, never which currency

  • the currency picker is gone from the donation form; `market_controller` keeps


the symbol and charity list in step with the selected region

  • `currency_symbol` columns are dropped for a new `Currency` model, following


`Locale` as the single source of truth

  • the admin dashboard's cross-market total is grouped by currency, not summed


Also makes `regions.donations_count` a true counter cache. An active-only
counter cannot work, since claiming or deleting a donation is an update and
never fires the create/destroy callbacks that maintain it. The regions index,
which labelled that number "available items", now queries for the active count.
Peter Theill
Peter Theill 
deployed a configuration change 3 days ago
3 days ago
🌐 Multi-language support: Danish, Swedish, Norwegian, German, French and Spanish (#22)

  • 🌐 Add multi-language support (da, sv, no, de, fr, es)


Localises the site into Danish, Swedish, Norwegian, German, French and
Spanish alongside English, using Rails' own i18n rather than a gem.
URLs
English keeps its existing unprefixed paths, so no URL moves and no
redirects are needed. The other languages are served from a `/da/...`
prefix via `scope "(:locale)"`. Admin, the API and sitemaps opt out.
Locale resolution
URL > signed-in user's profile > cookie > Accept-Language > English.
The URL always wins so a shared or crawled link renders the language it
was shared in. Visitors who prefer another language are redirected once
from an unprefixed path, keeping one canonical URL per language.
Routes without a `(:locale)` segment never redirect. This matters for
the OmniAuth callbacks, which live on fixed paths: redirecting them
discards the auth hash and breaks sign-in.
SEO
`<html lang>`, canonical, hreflang for all seven languages plus
x-default, og:locale and its alternates, and translated titles and
descriptions. The sitemap emits per-entry alternates rather than
duplicating rows per language.
Language selector
Footer dropdown reusing the existing dropdown controller. Saves to the
user's profile when signed in and to a cookie otherwise. Language is
also editable on the profile form.
Content
Navigation, forms, flash messages, emails and meta tags, plus the home,
search, about, press, help, FAQ and MobilePay pages. Emails render in
the recipient's saved language, including their links. Region names and
descriptions are translatable per locale from the admin.
Terms and privacy stay English-only for now and reach other locales
through the fallback; they are keyed and ready for a reviewed
translation.
Fixes found along the way

  • charities#show declared format.rss with no template, so the request


500'd. Added the feed.

  • `xml.language I18n.locale` passed a Symbol, which Builder reads as a


namespace prefix and emitted `<language:en/>`.

  • FAQ answers moved into locale data still contained ERB, which


rendered as literal text. Links now use placeholders resolved in a
helper so they stay locale-correct.
Query efficiency
Fixed N+1s on donation cards (donor avatars, charity logos, regions),
charity logos on the home/MobilePay/country/region pages, comment
authors, leaderboard donors, and notifications in both the navbar and
the notifications page. The sitemap no longer loads each user's
donations separately. Covered by tests that fail if the count grows
with the number of records.
Adds one gem, rails-i18n, for Rails' own date, number and validation
strings in the new languages.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

  • 💚 Fix CI: trailing newline and HTTP verb confusion


Both failures predate this branch and reproduce on develop, but they make
the build red, so they are fixed here.
Rubocop flagged a trailing blank line in admin/users_controller_test.rb.
Autocorrected; the file is otherwise untouched.
Brakeman flagged `request.get?` in Authentication#store_location: HEAD is
routed like GET, so a HEAD request skipped storing the return path.
It now treats the two alike.
The locale redirect had the same divergence, without being flagged. A
crawler checking an unprefixed URL with HEAD would have seen a different
answer than the GET that followed, so it redirects on HEAD as well.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
⬆️ Update version
Support
Support 
deployed a feature 4 days ago
4 days ago
✨ Introduce AI badge for generated media ✨ Introduce video overview preview component
Peter Theill
Peter Theill 
deployed a dependency update 5 days ago
Support
Support 
deployed a feature 9 days ago
Support
Support 
deployed a feature 9 days ago
Support
Support 
deployed a feature 9 days ago
Support
Support 
deployed a feature 9 days ago
9 days ago
✨ Add labels feature to video form ✨ Add new messages and update translations
Support
Support 
deployed a feature 11 days ago
11 days ago
✨ Add conversations data and improve video status handling ✨ Add library upload variant to MediaElementUploadField ✨ Add max duration to SecondsDurationInput ✨ Add new audio and video upload options ✨ Enhance video generation duration menu ✨ Introduce conversation ID and message in video regeneration ✨ Introduce entity chat status handling ✨ Introduce media generation mode in video form ✨ Introduce text effect presets and animations ✨ Introduce video agent response toast component ✨ Introduce video generation duration menu ✨ Update audio version metadata handling
Support
Support 
deployed a bug fix 14 days ago
14 days ago
🐛 Fix partner typecheck issues (#2125) 🐛 Fix sticky table columns (#2126) 🐛 Format video GraphQL queries (#2129) 🐛 Revert templ8-ui declaration path (#2128) ✨ Add image role support and improve image handling ✨ Add text and map effects to video elements ✨ Introduce label types management features ✨ Refactor video generation status handling
Support
Support 
deployed a feature 16 days ago
16 days ago
✨ Add element type messages for localization ✨ Enhance localization and sync features ✨ Introduce audio element features ✨ Introduce automation search functionality ✨ Introduce localized title support for events and places ✨ Introduce video generation status bar and refetch logic ✨ Introduce video timeline sorting and grouping keys ✨ Normalize line breaks in dynamic text elements ✨ Update content identifier in menu
Support
Support 
deployed a feature 16 days ago
16 days ago
🐛 Fix old bug on place form when opening drawer ✨ Add address fields to event and place forms ✨ Introduce agent type color and icon helpers ✨ Introduce bulk delete functionality for elements ✨ Introduce media handling and transition features ✨ Update magic wand references to AI suggestions
Support
Support 
deployed a feature 18 days ago
18 days ago
✨ Add allowedAudioKeys to DynamicRenderContext ✨ Add automation name, description, icon, and color ✨ Add fileId and agentId to video elements ✨ Add hasApplication field to Partner type ✨ Add media asset generation functionality ✨ Add reasoningEffort and model to agents table ✨ Add supplier icon and color customization ✨ Add video theme and storyboard paths ✨ Enhance product and supplier photo queries ✨ Enhance regeneration functionality ✨ Introduce audio completion sound feature ✨ Introduce audio element limit in video scenes ✨ Introduce audio generation features ✨ Introduce audio handling and improve UI elements ✨ Introduce new creative direction features ✨ Update automation and supplier features
Support
Support 
deployed a feature 21 days ago
21 days ago
✨ Add preview URLs for cover photos ✨ Add updater for automation queries
Support
Support 
deployed a feature 21 days ago
21 days ago
🐛 Update OpenAI API key input styling to not use a password type ✨ Introduce element management mutations ✨ Introduce video aspect ratio selection ✨ Introduce video shots feature
Support
Support 
deployed a feature 22 days ago
22 days ago
🐛 Fix issue with user authentication flow 🐛 fix booker field supplier options (#2119) 🐛 remove stale photo schema fields (#2120) ✨ Add icon and color support for suppliers and tools ✨ Add icon field to scene and related inputs ✨ Add previewable shot elements functionality ✨ Add supplier information to event details ✨ Add supplier information to events table ✨ Add supplier place selection and media library updates ✨ Add video preferences component and routes ✨ Add video width and height customization ✨ Enhance alert dialog functionality ✨ Enhance color picker functionality ✨ Enhance event and video generation features ✨ Enhance map marker functionality ✨ Enhance routing and add photo management features ✨ Enhance supplier and place event features ✨ Enhance video scene handling and UI ✨ Introduce JWT handling for supplier authentication ✨ Introduce agent deletion feature in AgentDrawer ✨ Introduce back navigation support in drawers ✨ Introduce benefits feature in supplier overview ✨ Introduce delete tool functionality ✨ Introduce dynamic mimeType handling ✨ Introduce editPreviewUrl for photo components ✨ Introduce form responses feature ✨ Introduce marker label collision handling ✨ Introduce new properties to video schemas ✨ Introduce response management features ✨ Introduce responses feature in Trip and Form renderers ✨ Introduce spam conversation feature ✨ Introduce supplier photo sources feature ✨ Refactor feedback form handling in trip members ✨ Refactor video scene handling and add dynamic shots ✨ Update heading text for consistency ✨ add event type input support (#2121) ✨ add video type to video form (#2122)
Support
Support 
deployed a bug fix about 1 month ago
about 1 month ago
🐛 fix Events and Media card alignment in public supplier dashboard (#2107) 🐛 fix photoSource type mismatch in EditPhotoModal (#2100) 🐛 fix spurious entity updates when opening drawers (#2095) 🐛 fix tab panel misalignment in public supplier dashboard (#2106) 🐛 hide Places card when supplier has no places (#2097) 🐛 suppress price groups deleted toast on supplier event public page (#2082) 🐛 use align-left icon for snippet field in DynamicEventForm and DynamicPlaceForm (#2103) ✨ restrict media-only suppliers to media tab in public supplier dashboard (#2104) ✨ split media sharing into placePhotos and eventPhotos arrays (#2098)
Peter Theill
Peter Theill 
deployed a feature about 1 month ago
about 1 month ago
✨ implement poll finalization, email reminders, ICS export, and time slot support with updated dependencies.