Skip to content

AlpineClubBookingsNZ v0.10.1

Choose a tag to compare

@thatskiff33 thatskiff33 released this 07 Jul 06:51
331cb7e

Tag: v0.10.1 · Previous: v0.10.0 (2026-07-07) · Merge commit: 331cb7e27.

What this release is

A patch release: four payment/booking-recovery hardening fixes and one operator
cleanup script on top of v0.10.0. No new features, and no behaviour changes
outside the raced/edge shapes the fixes close.

No database migrations, no schema changes, no post-upgrade actions.
docs/BLUE_GREEN_MIGRATION_SAFETY.tsv gains no rows and either app color can
serve throughout the deploy. The standard procedure still applies: back up the
database before deploying (docs/UPGRADING.md, "v0.10.0 → v0.10.1").

Changes

  • Quote re-send vs concurrent decline race closed — an admin re-sending a
    booking-request quote while the member declines can no longer resurrect a
    DECLINED/CANCELLED request or send its quote email; the losing re-send
    rolls back with a 409. (#1508, issue #1504)
  • Recovery replays converged with their inline Stripe bodies — the
    refund-request and booking-modification recovery replays previously sent a
    different reason under the same idempotency key, so Stripe rejected the
    replay with idempotency_error and recovery retried to exhaustion instead of
    converging (safe-failing; never a double refund). Shared per-path body
    builders now guarantee byte-identical replays. (#1509, issue #1507)
  • Refund-appeal allocation plan frozen — the approve route computes the
    per-transaction Stripe refund allocation once, uses it inline, and persists
    the same slices to the recovery operation on inline failure, so a replay
    re-requests exactly the original slices under the original idempotency keys.
    Supersedes the completed-refund remainder heuristic; in the exotic mixed
    Stripe + Internet-Banking appeal shape the route now refunds the plannable
    Stripe portion inline and logs any shortfall (net Stripe money unchanged; the
    IB portion still settles via credit note). (#1513, issue #1510)
  • Aggregate per-invoice cap on never-settled Internet-Banking credit mint
    multiple never-settled IB payments matched to a single invoice can no longer
    collectively mint account credit above that invoice's cash. No current app
    flow produces the aggregate shape, so real-flow mint amounts are unchanged.
    (#1512, issue #1505)
  • New operator script npm run payments:backfill-cancel-flattened — a
    one-off, idempotent, dry-run-by-default backfill restoring the stored
    Payment.status on rows the pre-#1489 cancel defect flattened to FAILED
    on cancelled bookings. The read path already compensates, so this is
    cosmetic-only for stored rows; it makes no Xero and no Stripe calls. See
    "Backfill cancel-flattened payment statuses" in docs/MAINTENANCE.md.
    (#1511, issue #1506)

Optional post-upgrade cleanup

If your fork ever ran a pre-v0.10.0 build, booking cancellations may have
flattened captured (PARTIALLY_)REFUNDED payments' stored status to
FAILED. You can restore the stored rows with
npm run payments:backfill-cancel-flattened — dry-run first, review the
report, then re-run with --apply. Detail in docs/MAINTENANCE.md.

Validation evidence

  • Release PR #1514 CI fully green at head f9c396c75 (tree identical to the
    merge commit): verify (lint, typecheck, tests, build), Playwright E2E,
    Migration drift check, Static analysis gate, CodeQL, dependency-review,
    gitleaks (full-repo + PR-diff), docker-image-security.
  • Local on the release branch: npm run lint 0 errors (5 pre-existing
    warnings, unchanged from the v0.10.0 cut); npm run typecheck pass (banner
    alpine-club-bookings-nz@0.10.1).
  • npm run db:check-drift not run — no schema change in this release
    (git diff v0.10.0..v0.10.1 -- prisma/ is empty).
  • An independent review agent verified changelog completeness (all 5
    first-parent merges since v0.10.0 covered, no direct commits), the
    no-migrations claim, the version bump, and the UPGRADING/MAINTENANCE
    cross-references before merge.

Images

Published by main CI for the merge commit:

  • ghcr.io/thatskiff33/alpineclubbookingsnz-app:331cb7e2784fedc862e6feca712d7ba3dcf13193
  • ghcr.io/thatskiff33/alpineclubbookingsnz-migrate:331cb7e2784fedc862e6feca712d7ba3dcf13193

Maintainability follow-ups (non-blocking)

Unchanged from v0.10.0 — the current known-hotspots list in
docs/MAINTENANCE.md (large-file split queue headed by
src/lib/xero-operation-outbox.ts, queued for PR-b of #1272's replay-stack
co-location).