184 lines
6.3 KiB
Markdown
184 lines
6.3 KiB
Markdown
# AI Recommendation Type Fix
|
|
|
|
## Problem Statement
|
|
|
|
The AI recommendation system was hardcoding `recommended_type: 'daily_tour'` for all recommendations, regardless of the actual service being matched. This caused inconsistencies where:
|
|
- A `private_guide` service would be recommended but labeled as `daily_tour`
|
|
- The UI couldn't properly distinguish between different service types
|
|
- The system couldn't recommend `driver_car` or `activity_bundle` services
|
|
|
|
## Solution Overview
|
|
|
|
The fix implements **dynamic type derivation** from the matched service slug, ensuring that:
|
|
1. `recommended_type` is always derived from the actual service slug
|
|
2. All three service types (`private_guide`, `driver_car`, `daily_tour`) are valid outputs
|
|
3. The UI renders recommendations strictly based on AI output without assumptions
|
|
|
|
## Changes Made
|
|
|
|
### 1. Edge Function: `analyze-trip/index.ts`
|
|
|
|
#### Rule-Based Matching (Lines 475-530)
|
|
```typescript
|
|
// CRITICAL: Derive recommended_type from matched service slug
|
|
let recommendedType: 'daily_tour' | 'private_guide' | 'driver_car' | 'activity_bundle' = 'daily_tour';
|
|
|
|
if (matchedDailyTour.slug === 'private_guide') {
|
|
recommendedType = 'private_guide';
|
|
} else if (matchedDailyTour.slug === 'driver_car') {
|
|
recommendedType = 'driver_car';
|
|
} else if (matchedDailyTour.slug === 'activity_bundle') {
|
|
recommendedType = 'activity_bundle';
|
|
} else {
|
|
// All other slugs (red_tour, green_tour, blue_tour, balloon_day, etc.) are daily tours
|
|
recommendedType = 'daily_tour';
|
|
}
|
|
```
|
|
|
|
**Logic:**
|
|
- If slug is `private_guide` → type is `private_guide`
|
|
- If slug is `driver_car` → type is `driver_car`
|
|
- If slug is `activity_bundle` → type is `activity_bundle`
|
|
- If slug is any tour (red_tour, green_tour, etc.) → type is `daily_tour`
|
|
|
|
#### AI Response Validation (Lines 756-778)
|
|
```typescript
|
|
// CRITICAL: Validate and derive recommended_type from daily_tour_slug
|
|
if (analysis.daily_tour_slug) {
|
|
if (analysis.daily_tour_slug === 'private_guide') {
|
|
analysis.recommended_type = 'private_guide';
|
|
} else if (analysis.daily_tour_slug === 'driver_car') {
|
|
analysis.recommended_type = 'driver_car';
|
|
} else if (analysis.daily_tour_slug === 'activity_bundle') {
|
|
analysis.recommended_type = 'activity_bundle';
|
|
} else if (['red_tour', 'green_tour', 'blue_tour', 'balloon_day', 'mixed_custom'].includes(analysis.daily_tour_slug)) {
|
|
analysis.recommended_type = 'daily_tour';
|
|
}
|
|
}
|
|
```
|
|
|
|
**Purpose:** Ensures AI responses are validated and corrected if the AI returns inconsistent type/slug combinations.
|
|
|
|
#### Updated AI Prompt (Lines 673-698)
|
|
Added clear instructions to the AI:
|
|
```
|
|
ÖNEMLİ KURAL:
|
|
- recommended_type ve daily_tour_slug UYUMLU OLMALI!
|
|
- Eğer daily_tour_slug = "private_guide" ise, recommended_type = "private_guide"
|
|
- Eğer daily_tour_slug = "driver_car" ise, recommended_type = "driver_car"
|
|
- Eğer daily_tour_slug = "red_tour/green_tour/blue_tour/balloon_day/mixed_custom" ise, recommended_type = "daily_tour"
|
|
```
|
|
|
|
### 2. Database: Added Missing Service Types
|
|
|
|
**Migration:** `add_driver_car_and_activity_bundle_services_fixed`
|
|
|
|
Added two new service types to `daily_tours` table:
|
|
|
|
```sql
|
|
INSERT INTO daily_tours (slug, title, description, ...) VALUES
|
|
('driver_car', 'Şoförlü Araç Hizmeti', '...'),
|
|
('activity_bundle', 'Aktivite Paketi', '...');
|
|
```
|
|
|
|
**Current Service Types:**
|
|
- `red_tour` → daily_tour
|
|
- `green_tour` → daily_tour
|
|
- `blue_tour` → daily_tour
|
|
- `balloon_day` → daily_tour
|
|
- `private_guide` → private_guide
|
|
- `driver_car` → driver_car
|
|
- `activity_bundle` → activity_bundle
|
|
|
|
### 3. UI Components
|
|
|
|
#### TourModal.tsx
|
|
Added type labels for better UX:
|
|
```typescript
|
|
const typeLabels: Record<string, string> = {
|
|
daily_tour: 'Günlük Tur',
|
|
private_guide: 'Özel Rehber',
|
|
driver_car: 'Şoförlü Araç',
|
|
activity_bundle: 'Aktivite Paketi',
|
|
};
|
|
```
|
|
|
|
Updated dialog description to show Turkish labels:
|
|
```typescript
|
|
{typeLabels[analysis.recommended_type] || analysis.recommended_type}
|
|
```
|
|
|
|
#### AITourRecommendation.tsx
|
|
Already had proper type labels and renders based on `analysis.recommended_type` without assumptions.
|
|
|
|
## Type Mapping Rules
|
|
|
|
| Service Slug | Recommended Type | Description |
|
|
|-------------|------------------|-------------|
|
|
| `red_tour` | `daily_tour` | Full-day Red Tour |
|
|
| `green_tour` | `daily_tour` | Full-day Green Tour |
|
|
| `blue_tour` | `daily_tour` | Full-day Blue Tour |
|
|
| `balloon_day` | `daily_tour` | Balloon + Light Tour |
|
|
| `mixed_custom` | `daily_tour` | Custom Mixed Tour |
|
|
| `private_guide` | `private_guide` | Private Guide Service |
|
|
| `driver_car` | `driver_car` | Driver with Car Service |
|
|
| `activity_bundle` | `activity_bundle` | Activity Package |
|
|
|
|
## Validation Flow
|
|
|
|
```
|
|
1. AI/Rule-Based Matching
|
|
↓
|
|
2. Match Service Slug (e.g., "private_guide")
|
|
↓
|
|
3. Derive Type from Slug
|
|
↓
|
|
4. Return Response with:
|
|
- recommended_type: "private_guide"
|
|
- daily_tour_slug: "private_guide"
|
|
↓
|
|
5. UI Renders Based on Type
|
|
- Shows "Özel Rehber" label
|
|
- Filters providers with private_guide service
|
|
```
|
|
|
|
## Testing Checklist
|
|
|
|
- [x] Rule-based matching derives correct type
|
|
- [x] AI response validation corrects inconsistencies
|
|
- [x] All service types (daily_tour, private_guide, driver_car, activity_bundle) can be recommended
|
|
- [x] UI displays correct Turkish labels
|
|
- [x] search-tours edge function filters by daily_tour_slug
|
|
- [x] Database has all service types
|
|
- [x] Lint passes without errors
|
|
|
|
## Debug Information
|
|
|
|
The system now includes detailed debug info in responses:
|
|
```json
|
|
{
|
|
"debug_info": {
|
|
"recommendation_reasoning": "Matched service 'private_guide' (type: private_guide) with 75% confidence. ..."
|
|
}
|
|
}
|
|
```
|
|
|
|
This helps track:
|
|
- Which service was matched
|
|
- What type was derived
|
|
- Why the recommendation was made
|
|
|
|
## Benefits
|
|
|
|
1. **Consistency:** Type always matches the actual service being recommended
|
|
2. **Flexibility:** All service types can be recommended based on trip characteristics
|
|
3. **Transparency:** Debug info shows exactly how the type was derived
|
|
4. **Maintainability:** Single source of truth for type derivation logic
|
|
5. **User Experience:** Proper Turkish labels for all service types
|
|
|
|
## Future Enhancements
|
|
|
|
- Add more service types as needed (e.g., `photography_tour`, `culinary_tour`)
|
|
- Implement confidence-based type selection (e.g., if confidence < 0.7, suggest driver_car instead of full tour)
|
|
- Add A/B testing to compare recommendation accuracy
|