Change Log
Introduction
This documents aims to detail all the changes that have been made across the Arranmore Ferry platform.
Changes
App Session Fixes and 4.7.0 Release | 2026-08-13
App
API
- App:
- Fixed a dropped connection signing you out -
refreshTokenreturned an empty string on any error, and the wrapper every call goes through read that as "sign this user out", so one weak-signal request destroyed a valid session- It now signs out only when Firebase says the credential itself is dead, and no longer forces a round trip to Google on every authenticated request
- All 25 call sites behind it bail instead of sending an empty auth token, which the API rejects with a 403
- Fixed the name on accounts with both Apple and Google linked - the app took whichever provider Firebase listed first rather than the one being signed in with, and Apple only sends a name on the very first authorisation
- Fixed a connection blip mid sign-in creating an account whose name displayed as the literal word "displayName"
- Removed all 57 force-unwraps of the signed-in user - being signed out is an ordinary state, not an impossible one
- Two of them were more than mechanical: a settings screen could run against a dead widget, and a session ending mid-save crashed the purchase path
- Requests now carry an
X-App-Versionheader, so a request can be attributed to a build - the Dart HTTP client sends the same user agent for every release ever shipped - Google sign-in failing outside the Play Store is no longer reported as an error - a sideloaded build can't match a registered signing key, so that failure is correct. The same code from a Play install still reports
- Bumped to 4.7.0+470 and synced the Xcode project version to match - it still read 4.6.0/360 from the last iOS build, so the next archive would have stamped a version that didn't match what shipped
- 4.6.0+360 had already covered two different binaries, so events tagged with it can't be attributed to a build
- Verified with the full Maestro suite (18/18) on a Pixel 10 against the dev API
- Fixed a dropped connection signing you out -
- API:
- Admin and Firebase auth failures now log through winston with a route, reason and app version, instead of a bare console line behind a 403
Booking Health Check | 2026-08-11
Booking
- Added an
/api/healthendpoint for Coolify - liveness only, with no calls out to Directus or Firebase, so a slow upstream can't restart a healthy container
App Purchase Fixes | 2026-08-10
App
- Fixed a golden ticket win falling through into Stripe
- A win is already paid for, so the API answers with empty payment details, and the branch that shows the win had its
returncommented out - The customer who had just won a free ticket was shown a Stripe formatting error instead of their prize
- A win is already paid for, so the API answers with empty payment details, and the branch that shows the win had its
- Fixed a failed lucky ticket registration crashing on a null instead of showing "please try again", which also buried the real error
- Closed the remaining paths that could reach Stripe without a client secret, including a promo-won golden ticket
- Fixed admin tickets only being requested while offline - the connectivity check was missing its negation, so the list said "Could Not Find Tickets" whenever the device had a connection, and failed a host lookup whenever it didn't
API Logging and Promo Fixes | 2026-08-08
API
App
- API - fixed
DELETE /v2/admin/blocks/:idreporting a failure after a successful delete- Express 5 builds route params with no prototype, so the logger threw while converting them for Loki. This only started after the v5 upgrade
- The block really was deleted and the admin really got their 200 - the only casualty was the log line, which then threw and was reported as a failed delete
- Fixed at the logging transport as well as at the six controllers that logged params directly, so no future caller can take down a request by logging. The same latent crash was in the POS device update and remove routes
- App - fixed a rejected promo code labelling the full price "Promo Price" on the payment screen
- The caption was gated on "a code was checked" rather than "a code was applied"; every rejection path in the API returns -1 as the price, so expired codes, used codes and codes outside their price limits all hit it
- The four places that read this now share one condition so they can't drift apart again, and the Maestro promo flow checks both the accepted and the rejected case
App Test Coverage | 2026-08-05
App
- Added 13 Maestro flows, taking the suite from 5 to 18, run on both an iOS simulator and an Android emulator against the dev API
- The suite stopped at the front door - it never signed in, never built a ticket and never paid, so the only revenue path in the app had no automated cover
- New flows cover sign-in and its validation, settings toggles, the Changes tab, the all-year timetables, ticket shop validity errors, building a ticket end to end, editing an account, My Tickets, promo codes and a full Stripe purchase
- The purchase flow is excluded from the default run because it charges a test card and writes a ticket, and it asserts Stripe's "TEST" badge so it can never run against live keys
- The dev API address was stale, so dev builds were falling back silently to the bundled offline timetables - exactly the false pass these tests exist to catch
- The passenger +/- steppers had no labels, so they were silent to VoiceOver as well as unreachable by a test
- Two app bugs found while writing these are documented in the flows that hit them: switching to Gaeilge leaves the My Ferry page half translated until the tab is left and re-entered
App and API Error Fixes | 2026-08-03
App
API
- App - fixed the five root causes behind the 164 Bugsink events:
- Around 27 error handlers returned the wrong type, so Dart replaced the real error with an
ArgumentError- every network failure in the app collapsed into one meaningless issue and the actual cause was destroyed - Timeouts threw instead of falling back to cached data
- Opening ticket details while signed out crashed mid-purchase, on a screen that renders a sign-in prompt lower down for exactly that case
- The tickets tab fired its first request before anyone could have signed in - a genuine 403 is a sign-in problem, not a defect, so it no longer reports
- A mistyped password and a dismissed Stripe sheet are the app working, and are no longer reported as errors
- Tickets are now parsed one at a time - a single record with no payment object, or a phone number stored as a number, used to hide every other ticket and show as "It appears you're offline"
- A ticket reference shorter than six characters took the whole view down, including both admin ticket lists
- Around 27 error handlers returned the wrong type, so Dart replaced the real error with an
- API:
- Fixed the v1 web payment webhooks, which have been throwing since the Mongo driver dropped
Collection.update()- any Stripe traffic still pointed at those routes has not been activating tickets- Two further bugs sat behind it, masked by the first: the chain sent a second response, and three of the four error handlers referenced a variable that wasn't in scope
- Failures now answer 500 so Stripe retries, instead of claiming success while the ticket stayed inactive
- Fixed the v2 ticket endpoints crashing when a Firebase token is valid but has no account row - a sign-up that failed after Firebase created the user, or a deleted account whose tokens haven't expired
- The crash was caught and answered as an empty ticket list, so those users were shown no tickets, no error and no way to recover
- Fixed the v1 web payment webhooks, which have been throwing since the Mongo driver dropped
Email and Privacy Update | 2026-07-29
API
Booking
- Updated the header and the small print on the receipt and updated-receipt emails
- Added the privacy policy page to the booking site
Statistics Update | 2026-07-26
API
- Statistics can now be narrowed to a single sailing - all three endpoints take an optional journey and time, and the return leg matches the opposite sailing
- New totals endpoint returning tickets, passengers, vehicles and each vehicle class
- Nothing exposed vehicle counts before, as the passenger figures can't be reversed back into a vehicle total
- Soft-deleted tickets are now excluded from every statistics aggregation, as the dashboard already did - a single-sailing view would otherwise disagree with the dashboard for the same ferry. Whole-day totals may drop slightly as a result
- Checked against local data for one day - all seven figures match an independent count, and summing every sailing reconciles to the whole-day total apart from one return leg with no return time, which can't be attributed to a sailing
App Error Reporting and API Update | 2026-07-25
App
API
- App:
- Moved error reporting off GlitchTip onto Bugsink using
sentry_flutterpackage:sentryhad no Flutter bindings, so nothing was hookingFlutterError.onErroror the isolate handler - only explicit captures were being reportedrunAppwas running outside the error zone, so startup errors were missed- All 55 call sites now send the caught object and a stack trace with a context description, instead of an interpolated string
- Turned off print breadcrumbs so debug output can't ship secrets in release, and removed an auth token debug print
- Release and build number now come from
package_inforather than hand-maintained constants
- Added a Maestro end to end test suite (5 flows)
- Smoke navigation, dashboard live data, timetable date pick, My Ferry account options and a vehicle booking flow
- A shared
common_launchsubflow handles the notification alert and the first run intro carousel
- Fixed the prod version file drifting behind the shipped 4.5.5+350, which was making every store upload get rejected
- Moved error reporting off GlitchTip onto Bugsink using
- API:
- Stripe PaymentIntents are now tagged with the ticket id, ticket ref, user id and payment method
- Payments are traceable back to a ticket from the Stripe dashboard for every ticket, not just ones that complete payment
- Fixed admin authorisation 500ing when the uid maps to no account (a deleted admin, or a valid token with no account row) - now answers as unauthorised
- Admin authorisation now fails closed if the account lookup itself errors, rather than letting the error propagate and take down every admin route behind it
- Stripe PaymentIntents are now tagged with the ticket id, ticket ref, user id and payment method
API and Booking Fixes | 2026-07-24
API
Booking
- API - fixed three v2 crashes reported in Bugsink:
- Payments webhook: a Stripe webhook whose payment intent matched no ticket threw when logging the ticket id (10.7k events)
- Get ticket: a malformed ticket id threw and was re-reported on every call, now answered cleanly (1.6k events)
- Remove block:
findOneAndUpdateon the mongodb v7 driver returns the document, not a.resultwrapper - reading it on a stale block id threw and then tried to send a second response - Added a regression test for the malformed ticket id path
- Booking:
- Fixed foot passenger bookings being refused on sailings where the cars were full
- The availability API returns -1 as a sentinel for a car-full sailing, not a count, and checkout was treating it as capacity - a live scan found 10 of 159 sailings over 8 days refusing foot passengers this way
- The time picker hid the problem, so the sailing looked bookable right up until payment
- The time picker now adds up passenger capacity when two boats sail the same time, instead of taking the larger of the two
- Fixed foot passenger bookings being refused on sailings where the cars were full
Admin Check In Update | 2026-07-21
Admin
- Added a check in toggle to tickets (
ticket-checkin-toggle.tsx)- Not Checked In / Waiting / Checked In [Outward] / Checked In [Return]
- Updates optimistically and rolls back with a toast if the server rejects it
- A dashboard reload wins over the optimistic value
- Car Details panel on the dashboard now has a Check In column and reloads the dashboard after a change
- Passenger icons stacked vertically and rows aligned to the top
- Widened the panel
- Removed the unused
arranmore-timetables.pngand tidied the prettier config
Ticket Status Update | 2026-07-08
Booking
- Added a
redeemedticket status- Shows a purple badge with a check icon on the ticket
Checkout Update | 2026-07-07
Booking
- Replaced the plain phone input at checkout with a new
PhoneFieldcomponent- Country dial-code picker with search and flags, Ireland selected by default
- Ireland, UK and US pinned to the top of the list
- Emits the full international number, and stays empty until a number is entered so a bare dial code doesn't pass the required check
- Used in both the account and guest checkout flows
- Fixed the guest validation reading the wrong field for the phone number
App and Kiosk Update | 2026-07-04
Booking
- Booking:
- Ahead of the new website launch - mirrored the payments to https://live.thearranmoreferry.com
- Improved links to the booking page from the timetable with params
- Checked all existing flows (account v guest) for data leaks
- See admin messages from 4th July 2026
- Added test cases
- Deployed to coolify
- Added links to existing website
- Web & API:
- Added a guard to stop tickets being purchased without car details
- Checked at checkout (account, guest and reservation flows) and again in the payments API
- Added a guard to stop tickets being purchased without car details
API and Admin Update | 2026-06-13
Admin
API
Kiosk
- API:
- Fixed the kiosk date resolution
- Added test cases
- Improved the payments logging
- Updated the email strings
- Fixed the kiosk date resolution
- Admin:
- Ticket history now shows who made the change
- Fixed the ticket history sort order
Receipt Printer Update | 2026-06-04
API
- Added Receipt Printer routes and controllers to the API
- Tickets can now be printed from admin
Email Update | 2026-05-08
API
- Updated react-email to v6
- All email templates and components updated
App Update | 2026-05-01
App
- Updated to the latest stripe_flutter
- iOS entitlements and pods updated
App and Kiosk Update | 2026-04-29
App
Kiosk
- App:
- Updated Firebase Auth for reCAPTCHA 6.5.0
- Improved profile editing
- Kiosk:
- Updated to the latest Next.js version
Revenue Export | 2026-03-26
Admin
- Admin Ticket Buttons updated to show highlights
- Added ability to remove passengers from ticket from ticket sections
- Added better dark mode functionality
Revenue Export | 2026-03-22
Kiosk
- Kiosk software updated dependancies
- Stripe terminal JS updated
Revenue Export | 2026-01
Admin
- Updated ticket filtering
- Full date in the title (dashboard)
EEEE do MMMM yyyy
Revenue Export | 2025-12
Admin
- All dependancies updated - tailwind v4
- NextJS CVE Update closed
Revenue Export | 2025-10-07
App
- App Financial Features Declaration Completed
Revenue Export | 2025-09-27
Admin
- Script added to API repo for pulling data directly from the database.
- Sent the data onto padraic@thearranmoreferry.com
Revenue Export | 2025-08-27
Admin
- Updated admin definitions
Web Updates | 2025-07-27
Admin
- Fixed the incompatible time picker on admin
Web Updates | 2025-07-27
Admin
- Fixed the incompatible time picker on admin
Web Updates | 2025-07-30
Web
- Updated with Arranmore Blu page
Web Updates | 2025-07-04
Web
- Added an availability check before the user finally purchases a ticket, if there's no availabilty, the ticket is cancelled.
Web and Admin Updates | 2025-06-28
Admin
Web
- Changed the availability so that ferries can now carry 10 cars.
Web and Admin Updates | 2025-06-18
Admin
Web
API
Kiosk
- Server Updates:
- Moved servers from Heineken to Rex (Hetzner)
- Deployed using CI/CD pipeline
- Moved from bitbucket to GitHub
- POS Devices:
- Added login functionality to the POS devices
- Each device has a device_id registered in POS Devices tables
- Always included in the POS headers
- Improved the Revenue APIs
- POS devices can now print out the full data
- Added login functionality to the POS devices
- Admin Panel:
- Updated the admin panel update functionality
- Only makes changes to specific fields in the ticket
- Added the "Push To Device"
- Tickets can be push from admin
- Tickets can be picked up on the admin till
- Updated the admin panel update functionality
- Web:
- Translated website to Gaeilge
- Full translations can be accessed: Hexa Translations
- Kiosk Updates:
- Removed all references to snow in the kiosk
- Added a preferred payment method when selecting the payment device from Stripe
Web and Admin Updates | 2025-05-31
Website
App
- Website updated to use the DRDC logo.
- App updated to show a thank you page on the "MyFerry" screen.
Web and Admin Updates | 2024-12-20
Admin
Web
API
Admin
- Admin refreshes the dashboard data every 60 seconds.
Web
- Website redirect added for
/blog
API
- Device IDs added to the
Ticketobject- Device IDs added for the POS APIs request, in the headers.
- Device IDs added for the kiosk request.
- Device revenue created.
Web and Admin Updates | 2024-12-16
Admin
- Updated the admin app to accept non accounts to be added to the send notification list.
- Note: Admin can save accounts, without emails.
Web and Admin Updates | 2024-11-28
Admin
Web
Admin
- Admin Users can now log in / out on mobile
- Loading Spinner removed
- Database ready for new Contact import
Web
- New page names applied (
/about>/about-arranmore-ferry)- Updated the redirects in
next.config.js
- Updated the redirects in
- Updated JSON+LD for all pages
- Resubmitted to Google Search Console
App Update (4.0.3) | 2024-11-03
API
App
- Golden Tickets improvement to the API for better error handling.
- Share button on the Golden Tickets screen with an image.
- Red floating Snack bar for errors.
Website | 2024-10-24
Admin
API
App
Admin & API
- SMS can be sent directly to numbers now.
- Ticket View Panel now has an option for Editing Tickets Built In.
- Recurring Tickets (end date) and Editing are resolved.
- Regenerates tickets automatically
- Hidden refund button
- Redeemed Ticket Support
App (v4.0.2)
- Fixed the carousel clicking
- App Banner - now fixed
- Redeemed Ticket Status Button & Icon
TODO:
- Default ticket types for people
- Create an editable Custom Ticket Price
- Share Image From Golden Ticket Screen
Website | 2024-10-14
Web
- Updated team page
App Update (iOS 18 and Android 15) | 2024-10-09
App
- Support for iOS Dark and Tinted Icons and iOS 18.0
- Support for Themed Icons on Android
- Updated Apple Pay certificates
- All Flutter plugins up to date
Recurring Tickets | 2024-10-08
Admin
API
- Added recurring tickets to the admin panel - these are new and improved:
- Recurring Tickets can be added with improved selection
- Open Ended - tickets will be generated forever
- Fixed End Date - tickets won't be generated past this date
- Tickets are checked overnight and generate tickets 60 days in advance
- All "child" tickets can be viewed and edited
- Recurring Tickets can be added with improved selection
Promo Codes | 2024-09-17
Admin
API
App
Admin
- Updated the admin panel for promo tickets:
- Promos can have
- x% off a ticket
- €x off a ticket and;
- a fixed price for per ticket
- Promos can be limited by:
- Ticket type (discount is only applied to adults for example)
- Quantity (This is the total number of tickets that can use this code)
- Date and Time of Booking
- Price Limits (like Golden Tickets, minimum and maximum prices that can apply the code)
- Limit Per Customer (one customer can only buy 2 tickets for example)
- Admin can see which all the tickets that have used the code
- Viewing Tickets now shows if a promo code was applied
- Promos can have
| ❗️ | Note: Tickets cannot be edited to use a promo code. |
|---|
App
- The mobile app now accepts promo codes before buying the ticket:
- When applied the colour of the price turns pink
- Promo codes each have a message which will be displayed when applied.
- The "Can't Book Tickets?" button has been extended to clear old price and ticket formats.
- TikTok Link Included on the socials card!
- News / Update carousel updated to use native Flutter carousel - removed library.
- Updated to the latest Flutter Version 3.24.2
Video Guide
App (Name Collection) | 2024-08-18
App
- Corrected apps to always request names when they're not included in the User Account.
Admin (Return Tickets Keys) | 2024-07-27
Admin
API
- Corrected the admin panel to prevent the count of
returntickets for time keys on the dashboard.
Website | 2024-07-17
Website
- Updated the website to include a check for accounts to ensure their name and number are included, even if they have an account.
App, Admin & API | Up to 2024-07-10
Admin
App
API
POS
Chrome Extension
- Updated App
- Show names on Customer Tickets
- Updated styles for Stripe
- Target Android Version 34
- Configured a
devandprodapp - Improved Toggle Switches for Settings
- Updated POS Ticket / Machine
- Updated so that tickets with vehicles appear at the top
- Updated to use a new version of Shorebird
- Configured a
devandprodflavor - Updated to Flutter 3.22.0
- Chrome Extension
- Released the Chrome Extension
- Chrome Extension Link
- Blog Post Link
- Promo Materials
- Admin
- Added Promo Code Controls
- Tickets show vehicles at the top of the tables now
- Tables are not restricted to 20 rows for manual pagination tables.
- API
- Added Promo Codes
CRUD. Not implemented in API Calls. - Corrections for updating tickets using the new admin panel.
- Added Promo Codes
Admin Dashboard & API | 2024-06-20
Admin
- Updated the
/ticketspage to include a filter for name and email.
Admin Dashboard & API | 2024-06-11
Admin
API
A couple of corrections and quick updates were made:
- The SMS messages now have defaults, English, Gaeilge and Both
- The SMS messages correct numbers that start with 0044 and 00353
- Updated Car Printer Label to remove the icon.
- Corrected the emails - now sent to admin at all times too.
- Switched off the colours on the timekeys if the ferry has sailed
NEXT_PUBLIC_TIMEKEYS_GRAYOUT_PAST. - Updated the new ticket search to use old tickets information, see video
- Required an admin.accounts.controller API change
- Fixed typo on the cards
Admin Dashboard & API | 2024-06-10
Admin
API
This video is a quick summary of all the changes.
Admin Dashboard
- 🎟️ Tickets
- 🔍 Ticket Search Bar on all screens. Ticket ref or full ID.
- ⏱️Ticket History
- All changes made to new tickets are saved in ticket history, can be viewed for all tickets.
- 🔔 Notifications
- 📦 SMS Messages now work
- Search a user, select the account, confirm the number and click send.
- 📱 App Notifications send directly to the user's device
- 📦 SMS Messages now work
- Statistics - new stats
- Updated printer car label format
- Time picker is now hours and minutes
- ID's can be copied everywhere
- Faster account search
- Adding times is now faster
- New Ticket now has populates the date and time
- All tickets can now be checked in, if they're not checked in it doesn't show.
- Notes display across the entire dashboard
- Timekeys are now more compact
- Dark Theme and Light Theme
- Full rewrite using shadcn libraries
API
- Tickets updated with a
ticketRef - Ticket history added
- Emails updated for Cancellation Changes
- All API routes moved from v1 to v2