Surface silent store failures to the user and validate API responses in dev

Reservation toggle, todo/packing toggle and budget reorder were swallowing API errors after rolling back, so the user saw the change silently snap back with no explanation. Route those failures through the existing toast channel (new store/notify.ts bridges to window.__addToast, the same channel SystemNoticeBanner uses); the reservation toggle re-throws so ReservationsPanel's own translated toast finally fires. Also wire the existing parseInDev/checkInDev response validation into the maps and notification-test endpoints to catch contract drift in dev.
This commit is contained in:
Maurice
2026-05-31 17:15:53 +02:00
parent 177be53e64
commit 43173e2b33
7 changed files with 73 additions and 18 deletions
@@ -123,7 +123,7 @@ describe('reservationsSlice', () => {
expect(useTripStore.getState().reservations[0].status).toBe('confirmed');
});
it('FE-RESERV-007: toggleReservationStatus rolls back on API failure (silent)', async () => {
it('FE-RESERV-007: toggleReservationStatus rolls back and surfaces the error on API failure', async () => {
const reservation = buildReservation({ id: 10, trip_id: 1, status: 'confirmed' });
seedStore(useTripStore, { reservations: [reservation] });
@@ -133,8 +133,9 @@ describe('reservationsSlice', () => {
),
);
// Does NOT throw (silent rollback)
await useTripStore.getState().toggleReservationStatus(1, 10);
// Rolls back the optimistic toggle AND rejects, so the caller's catch can
// show a toast (previously the failure was swallowed and the toast never fired).
await expect(useTripStore.getState().toggleReservationStatus(1, 10)).rejects.toThrow();
expect(useTripStore.getState().reservations[0].status).toBe('confirmed');
});