Skip to main content
Kin Conecta’s compatibility matching system uses detailed questionnaires and profile data to connect tourists with guides who match their preferences and travel style.

Overview

The matching system consists of three main components:

Compatibility Profiles

Detailed profiles capturing preferences for matching

Answer Storage

Flexible storage for questionnaire responses

Favorites System

Save preferred guides and tours for later

Compatibility Profiles

Compatibility profiles store structured data used for matching algorithms.

Data Model

// Model: CompatibilityProfile.java
package org.generation.socialNetwork.matching.model;

@Entity
@Table(name = "compatibility_profiles")
public class CompatibilityProfile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long compatibilityProfileId;
    
    private Long userId;
    
    @Enumerated(EnumType.STRING)
    private CompatibilityProfileRole role; // TOURIST or GUIDE
    
    private String name;
    private String imgUrl;
    private String description;
    private String email;
    private LocalDate dateOfBirth;
    
    // Phone fields
    private String phoneCountryCode;
    private String phoneNumber;
    private String phoneE164;
    
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

Key Features

  • Role-Based: Separate profiles for TOURIST and GUIDE roles
  • User Linkage: Connected to user accounts via user_id
  • Contact Info: Email and international phone number support (E.164 format)
  • Timestamps: Tracks creation and updates for data freshness
Users can have multiple compatibility profiles for different contexts (e.g., solo travel vs. family trips).

Compatibility Answers

The answer system provides flexible storage for questionnaire responses.

Data Structure

// Model: CompatibilityAnswer.java
@Entity
@Table(name = "compatibility_answers")
public class CompatibilityAnswer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long answerId;
    
    private Long compatibilityProfileId;
    private String questionKey;  // Identifies the question
    
    // Flexible value storage
    private String valueText;    // For text answers
    private BigDecimal valueNumber; // For numeric answers
    private String valueJson;    // For complex/array answers
    
    private LocalDateTime createdAt;
}

Answer Storage Strategy

The system supports three value types:
Used for:
  • Short text responses
  • Single-choice selections
  • Simple string values
Example: "adventure", "moderate", "group"
Used for:
  • Rating scales (1-5, 1-10)
  • Budget ranges
  • Age or duration values
Example: 4.5, 1000, 7
Used for:
  • Multiple selections
  • Complex nested data
  • Array of preferences
Example: ["hiking", "photography", "food"]

Question Keys

Questions are identified by keys like:
  • travel_style
  • activity_level
  • budget_range
  • interests
  • group_size_preference
  • pace_preference
  • accommodation_style
The question key system allows adding new questions without schema changes. New questions can be added dynamically.

Matching Algorithm Factors

While the exact matching algorithm is implemented client-side or in a separate service, the data structure supports matching on:

Tourist-Guide Compatibility

Travel Style Alignment

Matching tourist preferences with guide specialties

Activity Level Match

Pairing tourists with guides offering appropriate intensity

Interest Overlap

Finding guides with expertise in tourist interests

Communication

Matching based on shared languages

Scoring Factors

Compatibility scores can be calculated based on:
  1. Profile Data: From TouristProfile and GuideProfile models
  2. Compatibility Answers: From the questionnaire responses
  3. Interest Overlap: Matching TouristProfileInterest with GuideProfileExpertise
  4. Language Match: Common languages between tourist and guide
  5. Availability: Guide calendar availability matching tourist dates
  6. Ratings: Guide rating average and review count
  7. Location: Geographic proximity or location preferences

Favorites System

Users can save guides and tours they’re interested in.

Favorite Guides

// Model: FavoriteGuide.java
@Entity
@Table(name = "favorite_guides")
public class FavoriteGuide {
    @EmbeddedId
    private FavoriteGuideId id; // Composite: touristId + guideId
    
    private LocalDateTime createdAt;
}
Endpoints:
POST   /api/v1/favorite-guides
GET    /api/v1/favorite-guides
DELETE /api/v1/favorite-guides/{touristId}/{guideId}

Favorite Tours

// Model: FavoriteTour.java
@Entity
@Table(name = "favorite_tours")
public class FavoriteTour {
    @EmbeddedId
    private FavoriteTourId id; // Composite: touristId + tourId
    
    private LocalDateTime createdAt;
}
Endpoints:
POST   /api/v1/favorite-tours
GET    /api/v1/favorite-tours
DELETE /api/v1/favorite-tours/{touristId}/{tourId}
Favorites use composite keys to ensure a tourist can only favorite a guide or tour once, preventing duplicates.

API Reference

Compatibility Profiles

GET    /api/v1/compatibility-profiles/{id}
GET    /api/v1/compatibility-profiles?userId={userId}
POST   /api/v1/compatibility-profiles
PUT    /api/v1/compatibility-profiles/{id}
DELETE /api/v1/compatibility-profiles/{id}

Compatibility Answers

GET    /api/v1/compatibility-answers/{id}
GET    /api/v1/compatibility-answers?profileId={profileId}
POST   /api/v1/compatibility-answers
PUT    /api/v1/compatibility-answers/{id}
DELETE /api/v1/compatibility-answers/{id}

Implementation Examples

Creating a Compatibility Profile

POST /api/v1/compatibility-profiles
{
  "userId": 123,
  "role": "TOURIST",
  "name": "Jane Smith",
  "description": "Adventure seeker looking for cultural experiences",
  "email": "jane@example.com",
  "dateOfBirth": "1990-05-15",
  "phoneCountryCode": "+1",
  "phoneNumber": "5551234567",
  "phoneE164": "+15551234567"
}

Storing Questionnaire Answers

POST /api/v1/compatibility-answers
[
  {
    "compatibilityProfileId": 456,
    "questionKey": "travel_style",
    "valueText": "adventure"
  },
  {
    "compatibilityProfileId": 456,
    "questionKey": "activity_level",
    "valueNumber": 4
  },
  {
    "compatibilityProfileId": 456,
    "questionKey": "interests",
    "valueJson": "[\"hiking\", \"photography\", \"local_food\"]"
  }
]
The core matching logic compares compatibility answers, profile preferences, and other factors to generate compatibility scores. The backend provides the data; scoring algorithms can be implemented in the application layer or a dedicated matching service.
Yes, the compatibility score can be calculated client-side using the profile data and answers, then displayed to tourists when browsing guides.
Matched guides are algorithmically suggested based on compatibility. Favorite guides are manually saved by tourists for quick access, regardless of compatibility score.

User Profiles

Learn about tourist and guide profile features

Bookings

See how matches lead to bookings

Build docs developers (and LLMs) love