Skip to main content

EP-004: Guest Management

Business Objective​

Guest data is the most valuable asset in hospitality after the physical property. A 360-degree guest profile enables personalized service (remembering a returning guest's pillow preference), targeted marketing (birthday offers), and revenue optimization (understanding lifetime guest value). In the Indian regulatory context, hotels must handle Aadhaar data under DPDP Act 2023 compliance, manage foreign guest C-Form submissions to FRRO, and support GDPR for international guests. Guest deduplication prevents fragmented profiles that degrade service quality. This epic ensures that every guest interaction across reservations, front desk, F&B, and spa contributes to a unified guest record.

Audience​

  • Primary: Front Desk Agent (guest registration, ID capture), Reservations Agent (guest lookup, profile creation)
  • Secondary: CRM Manager (guest segmentation, campaigns), Manager (VIP handling, spend analysis)
  • Tertiary: Compliance Officer (GDPR/DPDP requests), Guest (data portability rights)

Scope​

In Scope​

  • Guest profile CRUD (title, name, email, phone, DOB, anniversary, gender, nationality, language, guest type)
  • 360-degree guest view (profile + stay history + spend + preferences + communications)
  • Identity document management (6 types: Passport, Aadhaar, Driving License, Voter ID, PAN Card, National ID) with verification status, issue/expiry dates, document URL
  • Guest addresses (home, work, billing -- multiple per guest with primary flag)
  • Preference management across 5 categories (ROOM, FOOD, SERVICE, COMMUNICATION, ACCESSIBILITY) with key-value pairs, bulk update, common preference catalog
  • VIP level classification (0=None, 1=VIP, 2=VVIP, 3=Celebrity)
  • Guest search with filters (name, email, phone, property, fuzzy matching)
  • Guest profile merge/deduplication (merge duplicate profiles into primary, reassign linked records)
  • Stay history and spend tracking (totalStays, totalNights, totalRevenue, lastStayDate on guest record)
  • Communication log (email, SMS, WhatsApp, push -- with status tracking: sent, delivered, opened, clicked)
  • Guest type segmentation (INDIVIDUAL, CORPORATE, TRAVEL_AGENT, GOVERNMENT, AIRLINE_CREW)
  • Company/corporate guest linking (companyId FK)
  • Loyalty member linking (loyaltyMemberId FK)
  • GDPR Article 17: Right to Erasure (anonymize PII)
  • GDPR Article 20: Right to Data Portability (export all guest data as JSON)
  • DPDP Act 2023 compliance: Data principal rights requests (create, list, get, update status), DPA template generation
  • Consent management: Record grant/revoke consent actions, view consent history per guest
  • Document upload via S3 pre-signed URLs for ID scans
  • Guest alerts (important notes shown to staff at check-in)

Out of Scope​

  • Loyalty program management (point accrual, redemption, tiers) -- covered in EP-011
  • Marketing campaigns and segmentation -- covered in EP-011
  • Guest-facing mobile app self-service -- covered in EP-010

Current Implementation Status​

  • Backend (guest-service): Fully built. GuestsController with CRUD, search, merge, 360 view, history, identity management, address management. PreferencesController with CRUD, bulk update, category filtering, common preference catalog. GdprController with erasure and export. DpdpController with request workflow (create, list, get, update status, DPA template). ConsentController with record and history. UploadsController with S3 pre-signed URL generation. All write operations have @Audit decorator.
  • Dashboard: CRM > Guests page with 360-degree view, search, guest list. Guest detail page with tabs: Profile, Stays, Preferences, Identity Documents, Communications.
  • Prisma Models: Guest (with totalStays/totalNights/totalRevenue/lastStayDate), GuestIdentity (6 ID types), GuestAddress (4 address types), GuestPreference (5 categories), GuestCommunication (4 channels with full status tracking).

Gap Analysis​

  • Guest Document Upload -- Encryption at Rest: UploadsController generates S3 pre-signed URLs and GuestIdentity.documentUrl stores the path. However, S3 bucket encryption configuration (SSE-S3 or SSE-KMS) is not verified. Aadhaar scans require AES-256 encryption at rest per UIDAI guidelines. Impact: High -- compliance risk.
  • Automated Dedup Suggestions: POST /guests/merge exists for manual merge (operator selects primary and secondary profiles). No automated duplicate detection (fuzzy matching on name + phone + email to surface probable duplicates). Impact: Medium -- hotels with 10,000+ guest records will accumulate duplicates over time.
  • Communication Log Aggregation: GuestCommunication model exists with full status tracking. However, communications from different services (notification-service emails, WhatsApp messages, POS receipts) are not aggregated into this model. The 360 view's communications tab may be incomplete. Impact: Medium -- CRM managers can't see the full communication picture.
  • Guest Spend Analysis Dashboard: Guest model tracks totalRevenue and totalStays. However, a breakdown by department (room revenue vs. F&B vs. spa vs. minibar) is not available. Revenue manager needs this for identifying high-value guests. Impact: Medium.
  • Aadhaar Masking: When displaying Aadhaar numbers in the UI or exports, only the last 4 digits should be visible (UIDAI regulation). This masking is not enforced at the API level. Impact: High -- compliance risk for Indian properties.
  • Guest Photo: No guest photo field on the profile. Some luxury hotels photograph guests at check-in for recognition. Impact: Low -- not a priority for most segments.

User Stories​

Story IDTitlePriorityPointsStatusSprint
US-004-001Guest Profile CRUDP05Built2
US-004-002Guest Search (Name, Phone, Email)P05Built2
US-004-003360-Degree Guest ViewP08Built3
US-004-004Identity Document ManagementP05Built3
US-004-005Guest Preference ManagementP05Built3
US-004-006VIP Level ClassificationP02Built2
US-004-007Guest Address ManagementP13Built3
US-004-008Guest Profile Merge (Deduplication)P18Built4
US-004-009Guest Stay History & Spend TrackingP15Built4
US-004-010GDPR Right to ErasureP15Built5
US-004-011GDPR Data Portability ExportP13Built5
US-004-012DPDP Act Compliance (Data Principal Requests)P18Built5
US-004-013Consent ManagementP15Built5
US-004-014Automated Duplicate Detection & SuggestionsP28Not Started10
US-004-015Guest Spend Analysis by DepartmentP25Not Started10
US-004-016Aadhaar Number Masking & Encryption VerificationP25Partial8

Dependencies​

  • EP-001 (Auth): Guest operations require authenticated users with appropriate roles (FRONT_DESK, RESERVATIONS for create/update; ADMIN for merge/GDPR).
  • EP-002 (Property): Guests are scoped to properties (propertyId FK).
  • EP-003 (Reservation): Reservations link to guest profiles. Guest history depends on reservation data.
  • EP-005 (Front Desk): Check-in captures ID documents and updates guest profile.
  • EP-011 (CRM & Loyalty): Loyalty member linking, campaigns depend on guest profiles.

Acceptance Criteria (Epic Level)​

  • Guest profiles can be created with Indian-specific fields (Aadhaar, PAN, GSTIN for corporate guests)
  • 360-degree view aggregates profile, stays, spend, preferences, communications in one endpoint
  • 6 identity document types can be stored with verification status and document URL
  • Preferences across 5 categories can be set, updated, and retrieved per guest
  • Duplicate profiles can be merged with all linked records (reservations, folios) reassigned
  • GDPR erasure anonymizes all PII fields irreversibly
  • GDPR export returns complete guest data in portable JSON format
  • DPDP requests are tracked through a workflow (submitted -> in-progress -> completed)
  • Consent grant/revoke actions are logged with timestamps for audit

KPIs / Success Metrics​

  • Guest profile completeness: > 80% have email + phone + at least 1 ID document
  • Duplicate rate: < 2% of total guest records (after automated dedup)
  • GDPR/DPDP request response time: < 72 hours (regulatory requirement: 30 days)
  • Guest search latency: < 300ms for fuzzy name search across 50,000 records
  • 360-view load time: < 1 second for complete guest profile aggregation
  • VIP identification at check-in: 100% (VIP flag visible on arrivals board)

Detailed User Stories​

US-004-001: Guest Profile CRUD​

As a front desk agent, I want to create and update guest profiles with complete demographic information, So that the hotel has accurate guest records for personalized service and regulatory compliance.

Priority: P0 | Points: 5 | Sprint: 2 | Status: Built

Implementation Status​

  • Backend: GuestsController -- POST /guests (SUPER_ADMIN, ADMIN, MANAGER, FRONT_DESK, RESERVATIONS), GET /properties/:propertyId/guests (paginated), GET /guests/:id, PUT /guests/:id, DELETE /guests/:id (SUPER_ADMIN, ADMIN, MANAGER -- soft delete). @Audit on all write operations. Guest model: title, firstName, lastName, email (unique per property), phone (indexed), secondaryPhone, dateOfBirth, anniversary, gender, nationality, language, vipLevel, guestType, companyId, loyaltyMemberId, notes, alerts, marketingConsent, dataConsent.
  • Frontend: Guest form with all fields, auto-save on tab-out.

Acceptance Criteria​

Scenario: Create a guest profile during reservation
Given the reservations agent is creating a booking and the guest is new
When they create a guest with title "Mr", firstName "Vikram", lastName "Reddy",
email "vikram.reddy@email.com", phone "+91-9876543210", nationality "Indian",
language "en", guestType INDIVIDUAL, marketingConsent true
Then the guest profile is created with a UUID
And totalStays, totalNights, totalRevenue are initialized to 0
And the guest can be linked to the reservation

Scenario: Update guest profile with anniversary date
Given guest "Vikram Reddy" already exists
When the front desk agent adds anniversary date "2018-02-14"
Then the profile is updated and the change is audit-logged
And the CRM can trigger an anniversary greeting on February 14

Scenario: Prevent duplicate email within same property
Given guest "vikram.reddy@email.com" exists for the property
When another agent attempts to create a guest with the same email for the same property
Then the system returns 409 with message "A guest with this email already exists"
And suggests the existing profile for linking

US-004-002: Guest Search (Name, Phone, Email)​

As a front desk agent, I want to search for guests by name, phone number, or email, So that I can quickly find returning guests without creating duplicates.

Priority: P0 | Points: 5 | Sprint: 2 | Status: Built

Implementation Status​

  • Backend: POST /guests/search with SearchGuestsDto. Supports: name (fuzzy, searches firstName + lastName), email (exact or partial), phone (exact or partial), property filter. Pagination. Database indexes on [propertyId, phone] and [propertyId, lastName, firstName].
  • Frontend: Search-as-you-type field in reservation form and guest list page.

Acceptance Criteria​

Scenario: Search by partial phone number
Given 3 guests have phone numbers starting with "+91-98765"
When the agent searches with phone "98765"
Then 3 matching guests are returned with name, email, phone, VIP level, last stay date
And results are ordered by last stay date (most recent first)

Scenario: Fuzzy search by guest name
Given a guest "Vikram Reddy" exists
When the agent searches "vikram" or "reddy" or "vikram reddy"
Then the guest profile is found in all three search variations
And the search handles case-insensitive matching

Scenario: Search across property for chain-level lookup
Given the agent has MANAGER role with access to multiple properties
When they search without propertyId filter
Then guests from all accessible properties are returned
And the property name is included in results for disambiguation

US-004-003: 360-Degree Guest View​

As a front desk agent or CRM manager, I want to see a comprehensive 360-degree view of a guest including their stay history, total spend, preferences, and communications, So that I can provide personalized service and understand the guest's value to the hotel.

Priority: P0 | Points: 8 | Sprint: 3 | Status: Built

Implementation Status​

  • Backend: GET /guests/:id/360 returns aggregated data: profile (all fields), identities (all documents), addresses, preferences (all categories), stay history (past reservations with room types, dates, amounts), communications (recent interactions), loyalty membership details, total spend breakdown.
  • Frontend: Guest detail page with tabbed interface showing all 360-view sections.

Acceptance Criteria​

Scenario: View 360-degree profile for a returning VIP guest
Given guest "Priya Kapoor" has VIP level 2 (VVIP), 12 stays, INR 4,50,000 lifetime spend
When the front desk agent opens the 360 view for this guest
Then the view displays:
- Profile: name, contact, VIP badge (VVIP), nationality, language
- Stay Summary: 12 stays, 28 total nights, INR 4,50,000 revenue, last stay Dec 2025
- Preferences: Room (high floor, king bed, extra pillows), Food (vegetarian, no onion),
Service (late checkout preferred), Accessibility (none)
- Recent Stays: last 5 reservations with dates, room type, rate, and satisfaction score
- Communications: last 10 messages (confirmation emails, feedback requests)
- Loyalty: Gold tier member, 15,000 points balance

Scenario: 360 view loads within 1 second
Given the guest has 20+ stay records and 50+ communication entries
When the agent opens the 360 view
Then all data loads within 1 second (API response < 800ms)
And lazy loading is used for communication history beyond the first 10 entries

US-004-004: Identity Document Management​

As a front desk agent during check-in, I want to record guest identity documents (Aadhaar, Passport, PAN, etc.) with verification status, So that the hotel meets regulatory requirements for guest identification and foreign guest reporting.

Priority: P0 | Points: 5 | Sprint: 3 | Status: Built

Implementation Status​

  • Backend: POST /guests/:id/identities with AddIdentityDto (idType, idNumber, issueDate, expiryDate, issueCountry, documentUrl, isVerified, isPrimary). Roles: SUPER_ADMIN, ADMIN, MANAGER, FRONT_DESK. @Audit logged. 6 ID types: PASSPORT, AADHAAR, DRIVING_LICENSE, VOTER_ID, PAN_CARD, NATIONAL_ID.
  • Frontend: Identity documents tab on guest profile with add/edit forms, document scan upload.

Acceptance Criteria​

Scenario: Record Aadhaar during check-in for Indian guest
Given an Indian guest is checking in without an existing ID on file
When the front desk agent adds identity: type AADHAAR, number "XXXX XXXX 1234",
isPrimary true, isVerified true
Then the identity record is created and linked to the guest
And the Aadhaar number is stored (but should be masked in display as "XXXX XXXX 1234")
And the identity appears in the guest's 360 view

Scenario: Record Passport for foreign guest with expiry tracking
Given a foreign guest presents their passport
When the agent adds identity: type PASSPORT, number "A12345678",
issueCountry "United Kingdom", issueDate "2020-05-15", expiryDate "2030-05-14",
isVerified true, isPrimary true
Then the passport details are stored with expiry date for C-Form compliance
And the guest is flagged as a foreign national for FRRO reporting

Scenario: Upload ID scan document
Given the agent wants to upload a scanned copy of the Aadhaar card
When they request a pre-signed URL via POST /uploads/presigned-url
with fileName "aadhaar-scan.jpg", contentType "image/jpeg", folder "guest-documents"
Then a pre-signed S3 URL is returned for direct browser upload
And after upload, the documentUrl is saved on the GuestIdentity record

US-004-005: Guest Preference Management​

As a front desk agent or concierge, I want to record and retrieve guest preferences across 5 categories, So that returning guests receive personalized service without having to repeat their requests.

Priority: P0 | Points: 5 | Sprint: 3 | Status: Built

Implementation Status​

  • Backend: PreferencesController -- GET /guests/:guestId/preferences (all), GET /guests/:guestId/preferences/:category (by category), POST /guests/:guestId/preferences (create/update single), PUT /guests/:guestId/preferences (bulk update), DELETE /guests/:guestId/preferences/:category/:key. 5 categories: ROOM, FOOD, SERVICE, COMMUNICATION, ACCESSIBILITY. GET /preferences/common returns catalog of common preference keys and suggested values.
  • Frontend: Preferences tab on guest detail page with category tabs and key-value editor.

Acceptance Criteria​

Scenario: Record room and food preferences for a VIP guest
Given guest "Priya Kapoor" is checking in and mentions preferences
When the agent records:
- ROOM: pillow_type = "Memory Foam", floor_preference = "High Floor", bed_type = "King"
- FOOD: dietary = "Vegetarian", allergies = "Tree Nuts", favorite_drink = "Masala Chai"
- SERVICE: newspaper = "Times of India", wake_up_call = "6:30 AM"
Then 8 preference records are created (or updated if they existed)
And the preferences are visible on the 360-degree view and check-in screen

Scenario: Bulk update preferences
Given the guest has 5 existing preferences
When the agent bulk updates all preferences with 3 modified values
Then the modified preferences are updated and unmentioned preferences are preserved
And each change is audit-logged

Scenario: Retrieve common preference catalog
Given the hotel wants to standardize preference capture
When the agent calls GET /preferences/common
Then a catalog is returned with suggested keys per category:
- ROOM: pillow_type, floor_preference, bed_type, view_preference, temperature
- FOOD: dietary, allergies, cuisine_preference, favorite_drink
- SERVICE: newspaper, wake_up_call, housekeeping_time, turndown_service
- COMMUNICATION: preferred_channel, language
- ACCESSIBILITY: wheelchair, hearing_aid, visual_assistance

US-004-006: VIP Level Classification​

As a hotel manager, I want to assign VIP levels to guests (None, VIP, VVIP, Celebrity), So that the front desk and housekeeping provide appropriate attention to high-value guests.

Priority: P0 | Points: 2 | Sprint: 2 | Status: Built

Implementation Status​

  • Backend: Guest.vipLevel field: 0 (None), 1 (VIP), 2 (VVIP), 3 (Celebrity). Updated via PUT /guests/:id.
  • Frontend: VIP badge on guest cards in arrivals board, check-in screen, guest list.

Acceptance Criteria​

Scenario: Set VIP level for a high-value corporate guest
Given guest "Rajesh Malhotra" has 20+ stays and INR 8,00,000 lifetime spend
When the manager sets vipLevel to 2 (VVIP)
Then the guest profile shows a VVIP badge
And arrivals board highlights VVIP arrivals with a gold indicator
And housekeeping receives automatic VIP room preparation instructions

Scenario: VIP alert shown at check-in
Given guest "Rajesh Malhotra" with VIP level 2 and alert "Prefers room 502, complimentary fruit basket"
When the front desk agent opens the check-in screen for this guest
Then the VIP badge and alert text are prominently displayed
And the agent is reminded to arrange the fruit basket before room assignment

US-004-007: Guest Address Management​

As a front desk agent, I want to store multiple addresses for a guest (home, work, billing), So that invoices can be addressed correctly and marketing mail reaches the guest.

Priority: P1 | Points: 3 | Sprint: 3 | Status: Built

Implementation Status​

  • Backend: POST /guests/:id/addresses with AddAddressDto (addressType: HOME/WORK/BILLING/OTHER, line1, line2, city, state, country, postalCode, isPrimary). Multiple addresses per guest. @Audit logged.
  • Frontend: Address section on guest profile with add/edit capability.

Acceptance Criteria​

Scenario: Add corporate billing address for GST invoicing
Given a corporate guest needs invoices addressed to their company
When the agent adds address: type BILLING, line1 "TechCorp Pvt Ltd, Tower A",
city "Gurugram", state "Haryana", postalCode "122001", isPrimary true
Then the billing address is stored and used as the default for invoice generation
And the GST invoice includes this address with the company GSTIN

Scenario: Store home address for a regular guest
Given guest "Vikram Reddy" provides his home address
When the agent adds address: type HOME, line1 "42, MG Road", city "Bengaluru",
state "Karnataka", country "India", postalCode "560001"
Then the address is stored and available for correspondence

US-004-008: Guest Profile Merge (Deduplication)​

As a hotel manager, I want to merge duplicate guest profiles into a single primary profile, So that the guest's complete history and preferences are consolidated and service quality improves.

Priority: P1 | Points: 8 | Sprint: 4 | Status: Built

Implementation Status​

  • Backend: POST /guests/merge with MergeGuestsDto (primaryGuestId, secondaryGuestIds array). Reassigns all linked records (reservations, identities, addresses, preferences, communications) from secondary profiles to primary. Deactivates secondary profiles. @Audit logged. Roles: SUPER_ADMIN, ADMIN, MANAGER.
  • Gap: No automated duplicate detection. Merge is manual -- operator must identify duplicates and select primary.

Acceptance Criteria​

Scenario: Merge two profiles for the same guest
Given "Vikram Reddy" has two profiles:
- Profile A: created during phone booking (email + phone, 3 stays)
- Profile B: created during walk-in (phone only, 2 stays)
When the manager merges Profile B into Profile A (primary)
Then Profile A now shows 5 total stays with combined revenue
And Profile B's reservations are reassigned to Profile A
And Profile B's identity documents and preferences are merged into Profile A
And Profile B is deactivated (soft-deleted)

Scenario: Merge preserves the most complete data
Given Profile A has email but no DOB, Profile B has DOB but no email
When merged into Profile A as primary
Then Profile A retains its email and gains the DOB from Profile B
And a merge audit record is created showing which fields came from which profile

US-004-009: Guest Stay History & Spend Tracking​

As a CRM manager, I want to view a guest's complete stay history and cumulative spend, So that I can segment guests by value and reward loyal customers.

Priority: P1 | Points: 5 | Sprint: 4 | Status: Built

Implementation Status​

  • Backend: GET /guests/:id/history returns past reservations with dates, room type, rate, amount. Guest model fields: totalStays, totalNights, totalRevenue, lastStayDate -- updated on check-out. Included in 360 view.
  • Gap: No department-level spend breakdown (room vs. F&B vs. spa).

Acceptance Criteria​

Scenario: View stay history for a returning guest
Given guest "Priya Kapoor" has stayed 12 times over 3 years
When the CRM manager views the guest's stay history
Then 12 stay records are shown with: check-in/out dates, room type, room number,
rate plan, total amount, and source (direct/OTA)
And a summary shows: 12 stays, 28 nights, INR 4,50,000 lifetime revenue

Scenario: Guest spend updates after checkout
Given guest "Vikram Reddy" has totalRevenue INR 1,00,000 and checks out with folio total INR 25,000
When checkout is processed
Then totalRevenue updates to INR 1,25,000
And totalStays increments by 1
And lastStayDate is set to today

US-004-010: GDPR Right to Erasure​

As a hotel admin handling a GDPR erasure request, I want to anonymize all personally identifiable information for a guest, So that the hotel complies with GDPR Article 17 (Right to be Forgotten).

Priority: P1 | Points: 5 | Sprint: 5 | Status: Built

Implementation Status​

  • Backend: DELETE /gdpr/guests/:id/erasure with x-tenant-id header. GdprService.eraseGuestData() anonymizes: firstName -> "REDACTED", lastName -> "REDACTED", email -> null, phone -> "REDACTED", dateOfBirth -> null, all identity documents removed, all addresses removed. Preserves non-PII for financial records (reservation amounts, dates). @Audit logged. Roles: SUPER_ADMIN, ADMIN.
  • Frontend: "Erase Guest Data" button on guest profile (with confirmation dialog explaining irreversibility).

Acceptance Criteria​

Scenario: Erase guest data per GDPR request
Given a European guest requests data erasure via email
When the admin processes the erasure via DELETE /gdpr/guests/:id/erasure
Then the guest profile is anonymized:
- firstName: "REDACTED", lastName: "REDACTED"
- email, phone, dateOfBirth, anniversary: nullified
- All identity documents: deleted
- All addresses: deleted
- Preferences: deleted
And financial records (reservation amounts, folio transactions) are preserved
And an audit log records who performed the erasure and when

Scenario: Erasure is irreversible
Given a guest's data has been erased
When any user attempts to view the guest profile
Then the profile shows "REDACTED" for all PII fields
And there is no mechanism to restore the original data

US-004-011: GDPR Data Portability Export​

As a hotel admin handling a GDPR portability request, I want to export all data held about a guest in a machine-readable format, So that the guest can transfer their data to another provider per GDPR Article 20.

Priority: P1 | Points: 3 | Sprint: 5 | Status: Built

Implementation Status​

  • Backend: GET /gdpr/guests/:id/export returns comprehensive JSON with: profile, identities, addresses, preferences, stay history (reservations with dates and amounts), communications, loyalty membership. Roles: SUPER_ADMIN, ADMIN.

Acceptance Criteria​

Scenario: Export complete guest data
Given guest "Hans Mueller" (German national) requests his data
When the admin calls GET /gdpr/guests/:id/export
Then a JSON document is returned containing:
- Personal details (name, email, phone, DOB, nationality)
- Identity documents (passport details)
- Addresses (home, billing)
- Preferences (all categories)
- Stay history (dates, room types, amounts for all visits)
- Communications (emails sent, dates, subjects)
And the export is delivered to the guest within the 30-day regulatory window

Scenario: Export excludes internal-only fields
Given the guest record has internal notes and VIP level
When the export is generated
Then internalNotes and vipLevel are excluded from the export
And only guest-facing data is included

US-004-012: DPDP Act Compliance (Data Principal Requests)​

As a hotel admin in India, I want to process data principal rights requests under the DPDP Act 2023, So that the hotel complies with Indian data protection law for guest data handling.

Priority: P1 | Points: 8 | Sprint: 5 | Status: Built

Implementation Status​

  • Backend: DpdpController -- POST /dpdp/requests (create request with x-tenant-id), GET /dpdp/requests (list, filter by guestId, ADMIN only), GET /dpdp/requests/:id, PATCH /dpdp/requests/:id/status (workflow advancement, ADMIN only). GET /dpdp/dpa-template generates Data Processing Agreement template. CreateDpdpRequestDto and UpdateDpdpStatusDto.
  • Frontend: DPDP request management under Settings > Compliance.

Acceptance Criteria​

Scenario: Submit a DPDP data access request
Given an Indian guest requests access to their data under DPDP Act Section 11
When the agent submits a DPDP request with type "DATA_ACCESS", guestId, and details
Then a request record is created with status "SUBMITTED"
And the admin dashboard shows the request in the compliance queue

Scenario: Process a DPDP request through workflow
Given a DPDP request is in "SUBMITTED" status
When the admin updates status to "IN_PROGRESS" with notes "Compiling guest data"
Then the status is updated and the change is audit-logged
And when completed, the admin sets status to "COMPLETED" with the response data
And the total processing time is tracked for regulatory compliance

Scenario: Generate Data Processing Agreement template
Given the hotel needs a DPDP-compliant DPA for a third-party data processor
When the admin calls GET /dpdp/dpa-template
Then a DPA template is returned with clauses aligned to DPDP Act 2023
And placeholders for hotel name, processor name, data categories, and retention periods

As a front desk agent, I want to record whether a guest has granted or revoked consent for marketing and data processing, So that the hotel only contacts guests who have opted in, meeting DPDP Act requirements.

Priority: P1 | Points: 5 | Sprint: 5 | Status: Built

Implementation Status​

  • Backend: ConsentController -- POST /consent with RecordConsentDto (records grant or revoke action). GET /consent/:guestId returns consent history with timestamps. Guest model has marketingConsent and dataConsent boolean fields. @Audit logged.
  • Frontend: Consent checkboxes on guest registration form and profile page.

Acceptance Criteria​

Scenario: Record marketing consent during check-in
Given a guest is checking in and verbally consents to marketing emails
When the agent records consent: type "MARKETING", action "GRANT",
channel "VERBAL", source "CHECK_IN"
Then a consent log entry is created with timestamp
And the guest's marketingConsent field is set to true
And the guest becomes eligible for marketing campaigns

Scenario: Guest revokes data processing consent
Given a guest previously granted data processing consent
When the guest requests consent revocation
Then the agent records: type "DATA_PROCESSING", action "REVOKE"
And the guest's dataConsent field is set to false
And the consent history shows both the original grant and the revocation with dates

US-004-014: Automated Duplicate Detection & Suggestions​

As a front desk agent creating a guest profile, I want the system to automatically detect potential duplicates based on name, phone, and email, So that I can link to an existing profile instead of creating a duplicate.

Priority: P2 | Points: 8 | Sprint: 10 | Status: Not Started

Implementation Status​

  • Backend: Not implemented. No fuzzy matching or phonetic comparison (Soundex/Metaphone) for duplicate detection.
  • Frontend: Not implemented. No duplicate warning during guest creation.

Acceptance Criteria​

Scenario: Detect potential duplicate during guest creation
Given a guest "Vikram Reddy" with phone "+91-9876543210" exists
When an agent creates a new guest with name "Vikram Reddi" (slight spelling variation)
and phone "+91-9876543210" (exact match)
Then the system shows a warning: "Potential duplicate found: Vikram Reddy (phone match)"
And the agent can choose to link to the existing profile or create a new one

Scenario: Weekly duplicate report for admin review
Given the property has 15,000 guest records
When the automated dedup job runs (weekly batch)
Then a report is generated with probable duplicate pairs scored by confidence:
- High confidence (same phone + similar name): 12 pairs
- Medium confidence (same email, different name): 5 pairs
And the admin can review and merge from the report

US-004-015: Guest Spend Analysis by Department​

As a CRM manager, I want to see a guest's spend broken down by department (room, F&B, spa, minibar, laundry), So that I can identify high-value F&B guests for dining loyalty programs or spa promotion targets.

Priority: P2 | Points: 5 | Sprint: 10 | Status: Not Started

Implementation Status​

  • Backend: Guest.totalRevenue exists as a single aggregate. Folio transactions have transactionCode (Room, FnB, Laundry, etc.) but no API aggregates spend by department per guest.
  • Frontend: Not implemented.

Acceptance Criteria​

Scenario: View departmental spend breakdown
Given guest "Priya Kapoor" has INR 4,50,000 lifetime spend
When the CRM manager views the spend analysis
Then the breakdown shows:
- Room Revenue: INR 3,20,000 (71%)
- F&B: INR 85,000 (19%)
- Spa: INR 25,000 (6%)
- Minibar: INR 12,000 (3%)
- Laundry: INR 8,000 (2%)
And a trend chart shows spend per department over the last 12 months

US-004-016: Aadhaar Number Masking & Encryption Verification​

As a compliance officer, I want Aadhaar numbers to be masked in all displays and API responses (showing only last 4 digits), So that the hotel complies with UIDAI guidelines for Aadhaar data handling.

Priority: P2 | Points: 5 | Sprint: 8 | Status: Partial

Implementation Status​

  • Backend: Aadhaar numbers are stored in GuestIdentity.idNumber. No masking applied at the API response level. S3 bucket for document uploads exists but encryption-at-rest (SSE-KMS) not verified.
  • Gap: API returns full Aadhaar number. No masking middleware for AADHAAR type identities. Encryption verification needed.

Acceptance Criteria​

Scenario: Mask Aadhaar in API responses
Given a guest has Aadhaar number "1234 5678 9012" stored
When any API returns this guest's identity documents
Then the Aadhaar number is displayed as "XXXX XXXX 9012" (last 4 digits only)
And only SUPER_ADMIN role can access the full Aadhaar number

Scenario: Verify encryption at rest for document storage
Given guest identity documents (Aadhaar scans) are stored in S3
When the compliance officer audits the storage configuration
Then S3 bucket has SSE-KMS encryption enabled with a managed key
And CloudTrail logs all access to the guest-documents bucket