Document: "Identity, Profiles & Authentication — Final System Design" Date: 2026-03-25
Today, every guest in MyMate is a single record: one person, one email, one profile. Simple.
The spec proposes splitting this into two concepts:
- Accounts — for guests who register and log in
- Saved Profiles — companion data (spouse, kids, colleagues) saved by the person who created the booking, reusable across future stays
This also introduces:
- Guests can share access to a stay via a temporary link (no login needed)
- Smarter detection when a companion already has their own MyMate account
- Multiple ways to access a booking (not just email + code)
This is not adding a feature to the app. It changes how the app knows who a guest is — and almost every feature depends on that.
| Feature | Why it's affected |
|---|---|
| Bookings | The way guests are linked to bookings changes completely. Every booking in the system is affected. |
| Booking creation (admin) | Admins currently pick from a global guest pool. That pool and selection logic changes — profiles become private to accounts. |
| Check-in | New steps: detect if companion has an account, send them an invitation, handle their response. Check-in becomes a per-guest workflow (verify each guest individually) instead of a single booking-level action. |
| Guest access (OTP) | Today: enter email, get a code. New: enter booking reference + email, or room number + email. Different flows. |
| Find Booking | The guest-side "find my booking" entry point changes — needs booking reference + email instead of just email. |
| Reviews | A guest leaves a review. But now — is this an account holder or a companion profile? Can companions leave reviews? |
| Room service & orders | Same question — can a companion without an account place orders? |
| Restaurant & activity bookings | Same question — who can book? |
| Requests | Same — who can submit requests to the hotel? |
| Rewards & loyalty | Today all guests in a booking earn points. Companions without accounts can't have reward balances. Do they earn points or not? |
| Referrals & birthday rewards | Referral rewards trigger on account verification — do companion profiles count? Birthday point queries currently include all guests — must exclude companions without accounts. |
| Guest preferences | Preferences (room, dining, experiences) are tied to the guest. Do companions have their own preferences? Who owns them — the companion or the account that created the profile? |
| Guest recommendations | Booking recommendations are tied to the guest. Same ownership question as preferences. |
| Guest profiles | Profiles become private to whoever created them. The same person might appear as different profiles under different accounts. |
| Guest avatars on bookings | Booking cards show guest faces. Need to visually distinguish account holders from companion profiles. |
| Admin guest search & filters | Currently searches all guests globally. Search scope and behavior change if profiles are private to accounts. |
| Document verifications | ID documents are tied to the guest entity. Must work with both accounts and profiles in the new model. |
| Chat / AI concierge | The AI identifies guests by their JWT, fetches bookings via the central security filter, and places orders on their behalf. All of this depends on the guest having an account. Companions without accounts cannot use the AI concierge — and if accessing via a temporary link, they have no identity for the chat system. |
| Password reset | Doesn't exist today. Required for the account login method to be complete. |
| JWT & session management | Currently 2 token types (partial/full). Adds a third (secure access link tokens). Multiple concurrent sessions possible — account login + access link for different stays. Token revocation needed when a guest is removed from a booking. |
| Feature | What it means |
|---|---|
| Saved companions | Guests manage a list of people they travel with. Re-use their info in 1 click for future bookings. |
| Smart account linking | When adding a companion whose email matches an existing account: detect it, notify them, let them accept or ignore. |
| Temporary access links | Any guest in a stay can generate a link to share with others. Link expires in 2 hours. No login needed. |
| Room-based access | Guest enters their room number + email to access their stay (only works during active stays). |
| Profile claiming | When someone creates an account, show them: "We found stays that might be yours" — let them claim past data. |
| Notification infrastructure | No email/push notification system exists today (only OTP codes). Smart linking, invitations, and access link delivery all require a notification service to be built first. |
These are not technical details — they are product decisions that change what we build.
1. Can companions do things, or only view? If someone is added to a booking as a companion (no account), can they:
- Order room service?
- Book a restaurant or activity?
- Leave a review?
- Submit a request to the hotel?
Or are these actions reserved for guests with accounts? This answer changes the scope by 30-40%.
2. Do companions earn loyalty points? Today, every guest in a booking earns points (check-in, nights stayed, etc.). If companions don't have accounts, they can't have point balances. Do we:
- Skip them entirely?
- Hold points and credit them if they later create an account?
- Only award points to account holders?
3. Who creates companion profiles? Today, only hotel admins create and assign guests. Does this spec mean guests can now manage their own companion list? That's a new user-facing feature to design, build, and support.
4. Can companions use the AI concierge? The chat system requires a guest identity to track who is sending messages. If a companion has no account (or is accessing via a temporary link), can they chat? If yes — who are they in the conversation?
5. What can a temporary link holder do? Someone receives a shared access link. Can they:
- Only view the stay details? (read-only)
- Place orders and make requests? (full access)
6. Room-based access — when exactly? The spec says "during the stay and in specific cases." Which cases? Only from the hotel's generic page? Only after check-in? What if checkout happened but the guest is still on-site?
7. What happens to existing guests? We have real guests in the system today — some registered, some not. How do we handle them?
- Registered guests (have passwords) become Accounts — straightforward.
- Unregistered guests (added by admins, no password) — do they become orphaned profiles? Under whose account?
- Guests currently in active bookings — migration must not break their access mid-stay.
8. What if profile data conflicts? Person A creates a profile for Person B with phone number X. But B has their own account with phone number Y. When B accepts the link to the booking, which phone number shows up? Who can edit it?
9. Can guests claim past stays? When someone creates an account and we find matching past profiles — if they claim them, do they get:
- Just the profile data (name, documents)?
- The full stay history?
- Retroactive reward points?
10. How precise is soft matching? When matching profiles on account creation — exact email match? Fuzzy name match? How do we handle common names?
11. Right to erasure for profiles? If person B requests deletion of their data, do we delete profiles that other accounts (A) created containing B's information? Or only B's own account? What's the legal basis for keeping B's data under A's account without B's consent?
12. Data retention for unlinked profiles? How long do we keep companion profile data if the companion never creates an account? Indefinitely (for reuse)? Or with an expiry?
13. PMS / external bookings? When a booking comes from a Property Management System, does it create an Account or a Profile? What if the PMS sends an email that matches an existing account — does smart linking trigger automatically?
14. API versioning or breaking release? The API response shapes change (booking guests become a mix of accounts and profiles). Is there a plan for API versioning, or is this a coordinated breaking release across backend and frontend?
While the identity foundation is being rebuilt, these are at risk:
- Any feature touching guests, bookings, or the guest app
- Reward system enhancements
- New guest-facing flows
- Review management (in progress — uses the guest model)
- Request management (in progress — uses the guest model)
- Chat / AI concierge (depends on guest identity)
| Phase | What | Effort | Risk |
|---|---|---|---|
| Phase 0 | Build notification infrastructure (email service) | Medium | Required before Phase 3 can work |
| Phase 1 | Rebuild the guest-booking foundation (backend + frontend) | Large | High — everything depends on this. Regression risk on all guest features. |
| Phase 2 | Companion management | Medium | Moderate |
| Phase 3 | Smart account linking + notifications | Medium | Moderate — depends on Phase 0 |
| Phase 4 | New login methods (booking ref, room number) | Medium | Moderate |
| Phase 5 | Temporary access links | Medium | Moderate |
| Phase 6 | Verification restructuring | Small | Low |
| Phase 7 | Profile claiming on registration | Small | Low |
Phase 1 alone requires changes across the entire backend and frontend. Phases 2-7 build cleanly on top once Phase 1 is solid.
The spec describes an elegant, flexible identity system. But before committing:
- Is the current model actually causing problems? Are guests complaining about companion management? Are hotels asking for this?
- How often do guests travel with companions who also have MyMate accounts? If rarely, Smart Account Linking solves a theoretical problem.
- How often do guests re-book with the same companions? If rarely, Saved Companions adds complexity for little gain.
- Could we achieve 80% of the value with 20% of the effort? For example: add companion reuse and temporary access links without splitting the identity model entirely.
The cost of this change is high — not just in build time, but in regression risk to every guest-facing feature that works today. The benefit should be validated against real usage before we commit.
- Answer the 14 product decisions — engineering cannot plan without them
- Validate with data — are the problems this solves actually happening?
- Consider an incremental path — can we deliver the highest-value pieces without the full identity split?
- If proceeding — Phase 1 needs a detailed technical spec and a data migration strategy before any code is written
For engineering reference — detailed system impact.
| Component | Role | Impact |
|---|---|---|
Guest entity |
Currently serves as identity + profile + auth user + reward holder, all in one. Implements UserInterface (it IS the JWT bearer). |
Must be split or extended. Auth identity needs to separate from profile data. |
booking_guest join table |
Simple ManyToMany linking guests to bookings. Foundation of the entire system. | Must become a proper BookingGuest entity with: account reference, profile reference, stay-level verification status. |
GuestExtension |
Central security filter — controls what every guest sees in the API. Uses MEMBER OF booking.guests. Runs on every API request. |
Complete rewrite. The ManyToMany query pattern no longer works. Performance-critical — must be properly indexed. |
HotelExtension |
Admin-side filtering of guests by hotel. Same join pattern. | Same rewrite needed. |
GuestAccessVoter |
Security check: "can this guest see data from another guest in the same booking?" | Double-join query must be redesigned. |
BookingGuestCountValidator |
Validates guest count matches numberOfGuests field. |
Must understand account guests vs profile companions. |
| OTP authentication | Lookup: findOneBy(['email' => $email]) — works because email is unique. |
Breaks when email uniqueness is removed. Needs booking-reference or room-number scoping. |
| Reward listeners | BookingRewardListener, AwardNightStayedPointsHandler, ReviewRewardListener, RoomServiceRewardListener — all iterate booking.getGuests(). |
Must filter to account-linked guests only. |
AwardBirthdayPointsHandler |
Queries all guests with matching birthdate. | Must exclude companion profiles without accounts. |
GuestRewardListener (referrals) |
Triggers referral rewards on account verification. | Must clarify: do companion profiles trigger referrals? |
| Chat / AI Agent | Resolves guest from JWT, fetches bookings via GuestExtension, places orders via HasGuestInterface. |
Breaks for companions without accounts and temporary link holders. |
8 entities with ManyToOne Guest |
RestaurantBooking, ActivityBooking, RoomServiceOrder, ServiceOrder, Request, Review, GuestPreference, BookingRecommendation |
All use GuestAssignerSubscriber. Must understand account vs profile. |
| JWT management | 2 scopes (partial/full) + JwtBlocklist. |
Adds third token type (secure access links). Concurrent sessions, per-booking revocation needed. |
| Test suite | 30+ test cases in BookingsTest alone. |
All need updating for new entity relationships. |
| Component | Purpose |
|---|---|
GuestProfile entity |
Companion profile data, owned by an account. Private, reusable, not globally unique. |
BookingGuest entity |
Replaces join table. Links a booking to either an account or a profile, with stay-level verification. |
PendingAccountLink entity |
Tracks pending booking-to-account links awaiting confirmation. |
SecureAccessLink entity |
Token-based temporary access. Generated by authenticated guest, expires in 2h. |
| New authenticator | Security firewall entry for secure access links. |
| Notification service | Email infrastructure for OTP, invitations, link delivery. Only OTP exists today. |
| Soft matching endpoint | Query by email + name + DOB for profile matching during registration. |
| Password reset flow | Required for account login to be complete. Does not exist today. |
| Area | Impact |
|---|---|
GuestInfo type |
Shape changes — ripples through every component that renders guest data (list items, cards, avatars, badges). |
| Check-in stepper | Email lookup against existing accounts, "this guest has an account" warning, per-guest verification workflow, pending link creation. |
| Auth drawer | New tab for room-based auth, conditional OTP (skip when booking is account-linked). |
| Guest space | Saved companions management, pending link accept/reject UI, secure link generation + sharing. |
| Find Booking flow | Needs booking reference + email instead of just email. |
| Registration flow | Soft matching UI — "we found profiles that may belong to you" with accept/ignore. |
| Booking cards | Guest avatars need to distinguish account holders from companion profiles. |
| Admin guest pages | Search scope changes, profile ownership display, global vs private filtering. |
| Guest preferences UI | Ownership model — companion preferences vs account preferences. |
| Chat / AI concierge UI | Must handle companions and link holders who have no chat identity. |
| All guest hooks | use-guests, use-guest-auth, use-guest-otp-* — all need updates for new entity model and auth flows. |
The existing booking_guest ManyToMany data must be migrated to the new BookingGuest entity without breaking access for guests currently in active bookings. This requires:
- Mapping existing guest records to accounts vs profiles
- Preserving all booking relationships
- Running migration during low-traffic window
- Rollback plan if migration fails