TidyLinker.com
TypeScript
Pull Request Opened
PR #146 opened: fix: hold direct bookings until email verified + admin booking ops
Summary
Yesterday Donna registered, opened Betty's profile, filled in the booking form, hit submit — and nothing happened. The verified middleware redirected her POST to /email/verify and silently dropped the payload. No JobPosting, no quote, no message thread, no notification to Betty. Donna thought she'd booked.
This PR fixes that and gives the founder eyes on bookings + a way to talk to people from the admin panel.
Booking lifecycle (the actual bug fix)
- The direct-booking POST is no longer wrapped in the
verifiedmiddleware group. - Unverified clients persist a
JobPostingwith a newheld_for_verification_attimestamp; cleaner notification +DirectBookingRequestedevent are deferred. ReleaseHeldBookingsOnVerifiedlistener fires onIlluminate\Auth\Events\Verified, releases held bookings, notifies the cleaner, dispatches the event.VerifyEmailResponseredirects the client straight to the released booking thread (with a flash) rather than dumping them on the dashboard./email/verifypage surfaces the "we've saved your booking" message so the user knows where they are.- Inline notice in the booking dialog when the user isn't verified yet.
Admin visibility
/admin/jobsgets a source filter (All / Posted / Direct) and a "Held — awaiting verification" pill on rows + the show page./admin/jobs/{job}now renders the actual messages in each thread, not just counts. Includes admin reply form per thread./admin/jobs/{job}/threads/{thread}/messageslets admin post into a job thread; rendered as "TidyLinker Support" via a newis_admincolumn on messages. Visible to both client and cleaner with a distinct amber-bubble style./admin/support/{request}supports admin replies (newsupport_request_repliestable +SupportReplyNotificationemail to the requester)./admin/users/{user}surfaces an activity timeline (latest 50 events caused by or targeting the user) using the existing Spatie Activitylog install. Future "phantom booking" mysteries should be solvable in seconds instead of grepping nginx logs.
Out of scope (deliberately deferred)
- Stripe-Connect gate on bookings. 12 of 19 cleaners on prod don't have active Connect — a hard gate would silently nuke 63% of bookability. Needs its own UX pass (soft warn? prompt cleaner on accept? hide from search?) — own PR.
last_login_atnot set on auto-login after registration. Noticed during the investigation; separate fix.
Test plan
- Pest: 1139 passed, 3 skipped, 0 failed (excluded browser group locally)
- Pint, Prettier, ESLint, tsc — all clean
- Smoke: register a fresh client, browse to a cleaner, submit booking before verifying email — booking shows in admin as "Held"
- Smoke: click verify link in email — land on the booking thread, cleaner gets the notification
- Smoke: admin replies on a support ticket — requester gets the email
- Smoke: admin posts in a job thread — both client and cleaner see it as "TidyLinker Support"
- Smoke: open
/admin/users/{donna}— see activity timeline including the registration / verify / booking-held / booking-released events
+1410
additions
-92
deletions
37
files changed