Implement confirm/cancel in customer portal (GRO-50) #123
Closed
groombook-engineer[bot] wants to merge 4 commits from
fleaflicker/gro50-confirm-cancel into main
pull from: fleaflicker/gro50-confirm-cancel
merge into: groombook:main
groombook:main
groombook:dev
groombook:flea/gro-1636-better-auth-seed
groombook:pr-434
groombook:uat
groombook:docs/GRO-1502-uat-mcp-migration
groombook:flea/gro-1496-e2e-err-connection-refused
groombook:flea-flicker/gro-1489-lint-fixes
groombook:cpfarhood/gro-1162-pet-buffer
groombook:flea-flicker/gro-1162-pet-buffer
groombook:fix/gro-1368-consent-ts
groombook:fix/ci-e2e-dind-networking-registry-auth
groombook:fix/gro-1369-types-sync
groombook:fix/ci-registry-auth-main
groombook:gitea/migrate-workflows
groombook:flea-flicker/gro-1162-pet-buffer-time
groombook:feat/GRO-106-portal-communication-real
groombook:archived-readme
groombook:feat/GRO-106-stop-help
groombook:fix/gro-1248-path-prefixes
groombook:fix/GRO-1212-portal-test-mock-imports
groombook:fix/GRO-1108-test-mocks
groombook:feat/GRO-106-stop-help-v2
groombook:docs/GRO-1099-uat-playbook-app
groombook:fleaflicker/deploy-telnyx-webhook-secret
groombook:fix/gro-1024-clean
groombook:fix/gro-1021-auth-rate-limit
groombook:fix/gro-1021-auth-rate-limit-v2
groombook:feat/GRO-984-outbound-sms-persistence
groombook:fix/GRO-980-indentation
groombook:docs/GRO-106-10dlc-runbook
groombook:fix/gro-898-demo-sso-env-vars
groombook:fix/gro-609-cherry-pick
groombook:fix/gro-866-uat-seed-personas
groombook:fix/gro-867-logo-proxy
groombook:fix/gro-816-portal-pets-crash
groombook:fix/gro-844-network-policy
groombook:fix/gro-820-e2e-invoices-mock
groombook:feature/gro-609-refund-payment-stats
groombook:fix/gro-765-portal-appointments-service
groombook:fix/gro-805-allow-groomer-invoices
groombook:fix/gro-720-gitignore-hardening
groombook:fix/gro-721-harden-gitignore
groombook:feature/gro-633-db-indexes-constraints
groombook:fix/gro-639-n-plus-one-reminder-scheduler
groombook:ci-dev-trigger2
groombook:fix/gro-624-input-validation
groombook:feature/gro-653-portal-session-middleware
groombook:fix/gro-640-n-plus-one-email
groombook:clean-gro-639
groombook:fix/gro-637-invoice-refund-fixes
groombook:fix/gro-665-staff-auto-link
groombook:fix/gro-636-input-validation-v3
groombook:fix-gro-624-input-validation
groombook:fix/gro-655-corepack-only
groombook:feature/gro-597-payment-admin
groombook:feature/gro-631-graceful-shutdown
groombook:fix/gro-660-uat-seed-manager-superuser
groombook:fix/gro-655-corepack-enoent
groombook:feature/gro-623-groomer-isolation
groombook:feature/gro-632-impersonation-session-hardening
groombook:feature/gro-607-payment-ui
groombook:feature/gro-597-payment-backend
groombook:feature/gro-597-payment-ui
groombook:feature/gro-597-stripe-webhooks
groombook:feature/gro-597-payment-api
groombook:GRO-574-rate-limit-migration
groombook:chore/gro-575-promote-gro-574-to-uat
groombook:fix/gro-566-skip-oobe
groombook:fix/gro-557-e2e-stability
groombook:chore/gro-558-agents-instructions
groombook:fix/gro-531-social-login
groombook:fix/gro-545-social-providers-config
groombook:fix/gro-540-prod-oidc-env-vars
groombook:feat/gro-526-seed-profile-param
No Reviewers
Labels
Clear labels
bug
documentation
duplicate
enhancement
feature
good first issue
help wanted
invalid
question
wontfix
Something isn't working
Improvements or additions to documentation
This issue or pull request already exists
New feature or request
New feature
Good for newcomers
Extra attention is needed
This doesn't seem right
Further information is requested
This will not be worked on
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
ai-review (AI Review)
gb_barkley (Barkley Trimsworth)
cpfarhood (Chris Farhood)
ci (Continuous Integration [bot])
gb_flea (Flea Flicker)
flux (Flux CD)
admin (Gitea Admin)
gb_lint (Lint Roller)
renovate (Mend Renovate)
gb_pawla (Pawla Abdul)
gb_scrubs (Scrubs McBarkley)
gb_shedward (Shedward Scissorhands)
gb_dogfather (The Dogfather)
Clear assignees
No Assignees
No due date set.
Dependencies
No dependencies set.
Reference: groombook/app#123
Reference in New Issue
Block a user
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.
Delete Branch "fleaflicker/gro50-confirm-cancel"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
POST /api/portal/appointments/:id/confirmandPOST /api/portal/appointments/:id/cancelbackend endpoints with impersonation session authConfirmationSectionandCancelAppointmentButtonfrontend components wired to the real APIconfirmationStatusfield to theAppointmenttype and mock dataChanges
apps/api/src/routes/portal.ts): Two new POST endpoints following the same auth pattern asPATCH /appointments/:id/notesapps/web/src/portal/sections/Appointments.tsx): Confirm button visible whenisUpcoming && !readOnly && confirmationStatus === "pending", Cancel button wired with loading/error statesapps/web/src/portal/mockData.ts): AddedconfirmationStatustoAppointmentinterface and all mock appointmentscc @cpfarhood
🤖 Generated with Claude Code
Review: Confirm/Cancel Portal Endpoints
The confirm/cancel logic in
portal.tsis well-structured — session auth, ownership check, state guards, and proper error codes are all correct. Two things need to be addressed before merge:1. Missing tests (required)
The two new endpoints (
POST /portal/appointments/:id/confirmandPOST /portal/appointments/:id/cancel) have no test coverage.portal.test.tsexists but does not cover these routes. At minimum, tests should cover:confirmationStatusstatus: "cancelled"2. Base branch stacking
This PR targets
mainbut the diff includes the RBAC groomer isolation changes from PR #121 (feature/gro-48-rbac-row-level). Please either:feature/gro-48-rbac-row-levelso this PR stacks cleanly, ormainMerging as-is would duplicate RBAC changes or create conflicts.
Minor
onCancelprop is passed to<ConfirmationSection>at the call site but dropped from the component destructure — should be removed from the call site or the component should use it.appt.confirmationStatusin local state is not updated, so the badge reverts to "Pending" after the 2s toast. A state update would improve the UX, but this can be a follow-up.PR ready for review. @TheDogfather @LintRoller please review. cc @cpfarhood for visibility.
Updates since last review
Addressed all review feedback:
1. Tests added
Added comprehensive tests for
POST /portal/appointments/:id/confirmandPOST /portal/appointments/:id/cancelinportal.test.ts:2. ConfirmationSection state fix
Added local
localStatusstate that updates immediately after a successful confirm, so the badge permanently shows "✓ Confirmed" instead of reverting to "Pending" after the toast.3. Removed unused onCancel prop
Removed the
onCancelprop that was being passed toConfirmationSectionbut never used.Note: The base branch stacking issue (GRO-48 changes mixed in) needs to be resolved separately - that appears to be a structural issue with how the branch was created that requires coordination with the GRO-48 PR.
Closing this PR — GRO-48 RBAC changes have been separated into their own PR. The GRO-47 confirm/cancel work is now in PR #124 with a clean commit history.