GRO-1248: Path references incorrectly used apps/groombook/ prefix
instead of apps/ for overlay and base kustomization paths.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Conflicts:
- apps/api/src/routes/invoices.ts — kept uat's stripeRefundId field (GRO-818)
- packages/db/src/seed.ts — kept main's deterministic stripePaymentIntentId
population (GRO-890); removed duplicate uat declaration that survived auto-merge
Brings GRO-609 (refund/stats fixes), GRO-890 (seed stripe pi), GRO-898 (CI dev
branch) and prior GRO-865 logo proxy promote from main into uat so the
uat → main promote (GRO-958) becomes mergeable.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Update the Update Infra Image Tags job condition to also trigger
on pushes to the dev branch, not just main.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
All paid invoices created by the seed script now get a deterministic
stripePaymentIntentId of the form pi_test_seed_NNNNNN, unblocking the
refund button conditional in Invoices.tsx:514 during UAT.
Pending/draft invoices retain null as before.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Fetch /api/invoices/stats/summary on mount and display Revenue/Outstanding/Refunds
summary cards above the calendar view on /admin
- Mirrors the same stats section already on /admin/invoices
- Gracefully handles errors via try/catch on the stats endpoint
Parent: GRO-882
Grandparent: GRO-816
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add stripePaymentIntentId to the GET /invoices list query so the refund button
renders when seed data includes a payment intent ID
- Wrap /api/invoices/stats/summary in try/catch so errors return 200 with zero
defaults instead of 5xx, preventing the Invoices page from crashing on
mount for groomer-role sessions
Parent: GRO-882
Grandparent: GRO-816
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* feat(GRO-785): validate tip split totals before marking invoice paid
- PATCH /invoices/:id returns 400 when tipCents > 0 but no tip splits
exist or splits don't sum to 100%
- POST /invoices/:id/tip-splits now returns 400 (not 422) on validation
failure via router-level ZodError handler
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* feat(GRO-786): add ARIA label attributes to Modal dialog component
- Update Modal component to accept title and titleStyle props
- Add role="dialog", aria-modal="true", and aria-labelledby attributes
- Use useId() to generate stable ID for title heading association
- Update all 4 Modal call sites (New/Edit Client, Add/Edit Pet,
Log Grooming Visit, Permanently Delete Client) with title props
- Delete modal passes titleStyle for red color on warning
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* fix(GRO-786): remove duplicate dialog role and restore focus trap
- Remove role="dialog" and aria-modal="true" from outer backdrop div
- Keep ARIA attributes only on inner dialog div (the actual modal)
- Restore useEffect focus management: auto-focus first element,
Tab cycle wrapping, Escape key handler, focus restore on close
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* fix(GRO-785): restore atomic tip split save in PATCH and fix error message
- When body.tipSplits is provided in PATCH /invoices/:id, validate sum
first then atomically replace existing splits (delete + insert)
- When no incoming splits, validate existing DB splits with corrected
message: "Tip splits are required when tip amount is greater than zero"
(previously misleading "must sum to 100%" when no splits existed)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* fix(GRO-785): address invoice tip split regression
- Use body.tipCents ?? current.tipCents for validation condition
so that simultaneous status=paid + tipCents=0 skip split validation
- Use body.tipCents (now aliased as tipCents) instead of current.tipCents
inside the atomic transaction for shareCents calculation
- Add explicit check for empty tipSplits array with appropriate error
message ("Tip splits are required when tip amount is greater than zero")
before the sum-to-100% check
- Destructure tipSplits out of body before spreading into update object
to prevent it from leaking into the invoices table SET clause
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* fix(GRO-785): wrap tip split save + invoice update in single transaction
Both tip split persistence (delete + insert) and the invoice PATCH update
are now inside one db.transaction() block. If the invoice update fails
after splits are written, the entire operation rolls back.
Also removed unnecessary eslint-disable comment on _tipSplits.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* fix(GRO-785): restore eslint-disable for intentionally unused _tipSplits var
Co-Authored-By: Paperclip <noreply@paperclip.ing>
---------
Co-authored-by: Flea Flicker <fleaflicker@groombook.farh.net>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: the-dogfather-cto[bot] <269737991+the-dogfather-cto[bot]@users.noreply.github.com>
2026-04-17 22:58:00 +00:00
4 changed files with 18 additions and 12 deletions
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.