A client messages: "Remind me when I'm booked and for what?" The administrator opens the CRM, finds the card, retypes the date and service into the messenger. A week later another client asks the same thing. The client cabinet removes that exchange: one link where the person sees their own bookings - both upcoming and past.
Where it is in the CRM
- Issuing the link: Clients → client, the "Cabinet link" button in the card header, next to "Edit". The button's tooltip: "Copy the client's personal link to their history and upcoming visits".
- What the client opens: the "My cabinet" page - a separate public page, not the staff cabinet.
How the link is issued
Clicking the button does two things: the server issues a cabinet token for this client, and the browser builds an address from it and copies it to the clipboard. A "Cabinet link copied" message appears - from there you paste the address wherever is convenient: a messenger, an SMS, an email.
The token is issued lazily: if it doesn't exist yet, it's created on the first click and stored on the card; later clicks return the same one. That means the client has one link, forever, and clicking again doesn't invalidate the old one.
There is no automatic sending of the link. It's never mentioned in reminders or emails - the salon hands out the address deliberately, to a specific person. It's the same logic as consents and review requests.
What the client sees
The page fits one phone screen and has three parts.
At the top: the salon's name, a greeting by first name, and the salon's phone number, which is clickable - tapping it on a phone calls the salon directly.
Next, "Upcoming visits": the date with the day of the week, start time, service, specialist, status, and price. Each upcoming visit has a "Manage appointment" link that leads to the appointment's own page, where it can be rescheduled or cancelled. Managing the appointment doesn't live in the cabinet - it lives there, and works with that appointment's own token: the cabinet only points to it.
Below is "Visit history" - the same thing, but without the manage button. A visit counts as upcoming if its time hasn't come yet and its status isn't closed; cancelled visits, no-shows, and completed ones go to history regardless of date. The client's last two hundred visits are returned - in salon practice that's the whole history, but formally there is a limit.
What the cabinet does not have: packages, gift certificates, deposit balance, before/after photos, color formulas, chats. All of that stays inside the CRM. There's also no phone number or email for the client themselves - the page doesn't show a person their own contact details, so a link that ends up in the wrong hands doesn't leak personal data along with it.
Why it's a separate domain
Pages a salon's client opens - the booking page, a review, a consent, the cabinet - are built as a separate application and live on their own domain. The reason isn't organizational, it's security: sharing a domain with the staff cabinet would mean sharing browser storage with access tokens.
The cabinet sits at the root - /client/<token> - without the /book prefix the booking page has. One place on the frontend and one on the backend build the address, by the same rule: until the separate domain is set up, the link points to the CRM's domain and works the same way.
A public request by token needs no authorization at all and is limited to thirty requests a minute per address - the same protection as on the other public pages.
Link security
The token is the key. It's random, 48 characters long, and stored on the client card with a unique index. It can't be brute-forced, but it can easily be forwarded, so it should be treated as a personal link, not a public address.
The link has no expiration date, so the only way to revoke one that went to the wrong place is to reissue it: next to "Cabinet link" there's a reissue button with a confirmation. The old link stops working the same instant, the new one is copied to the clipboard right away - all that's left is to send it to the client.
Merging cards was handled separately: if a link was sent to a client before their duplicate card was merged into the main one, the old token opens the main card's history. Otherwise a person would see an empty cabinet at exactly the moment you cleaned up the database.
If the token isn't found, the page says "Cabinet not found or the link is invalid" - and nothing else: the response can't be used to find out whether such a client exists.
What to do
Send the link in a private conversation, not a shared chat. Regular clients only need it once - it doesn't change, and they can bookmark it. And don't use the cabinet as a substitute for a reminder: it answers "when am I booked" when the client thinks to ask, while a reminder arrives when they don't.
Comments
No comments yet. Ask your question — we answer within a day.