Files
karibeo_api/src/modules/ai-guide/ai-guide.controller.ts
2025-10-10 21:47:56 -04:00

163 lines
5.3 KiB
TypeScript

import {
Controller, Get, Post, Body, Patch, Param, Query, UseGuards, Request
} from '@nestjs/common';
import {
ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, ApiParam
} from '@nestjs/swagger';
import { AIGuideService } from './ai-guide.service';
import { AIQueryDto } from './dto/ai-query.dto';
import { ARContentQueryDto } from './dto/ar-content-query.dto';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { RolesGuard } from '../../common/guards/roles.guard';
import { Roles } from '../../common/decorators/roles.decorator';
import { AIGuideInteraction } from '../../entities/ai-guide-interaction.entity';
import { ARContent } from '../../entities/ar-content.entity';
@ApiTags('AI Guide')
@Controller('ai-guide')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth('JWT-auth')
export class AIGuideController {
constructor(private readonly aiGuideService: AIGuideService) {}
@Post('query')
@ApiOperation({ summary: 'Ask AI guide a question' })
@ApiResponse({
status: 201,
description: 'AI response generated successfully',
schema: {
type: 'object',
properties: {
response: { type: 'string' },
suggestions: { type: 'array', items: { type: 'string' } },
arContent: { type: 'array' },
nearbyPlaces: { type: 'array' },
audioGuideUrl: { type: 'string' },
sessionId: { type: 'string' }
}
}
})
async queryAIGuide(@Body() queryDto: AIQueryDto, @Request() req) {
return this.aiGuideService.processAIQuery(queryDto, req.user.id);
}
@Post('ar-content/nearby')
@ApiOperation({ summary: 'Get nearby AR content' })
@ApiResponse({ status: 200, type: [ARContent] })
async getNearbyARContent(@Body() queryDto: ARContentQueryDto) {
return this.aiGuideService.getNearbyARContent(queryDto);
}
@Patch('ar-content/:id/view')
@ApiOperation({ summary: 'Increment AR content view count' })
@ApiParam({ name: 'id', type: 'string' })
async incrementARView(@Param('id') id: string) {
await this.aiGuideService.incrementARViewCount(id);
return { success: true, message: 'View count incremented' };
}
@Post('interactions/:id/rate')
@ApiOperation({ summary: 'Rate AI interaction' })
@ApiParam({ name: 'id', type: 'string' })
async rateInteraction(
@Param('id') id: string,
@Body() body: { rating: number },
@Request() req
) {
// TODO: Implement rating functionality
return { success: true, message: 'Rating saved' };
}
@Get('stats')
@UseGuards(RolesGuard)
@Roles('admin')
@ApiOperation({ summary: 'Get AI usage statistics (Admin only)' })
getAIUsageStats() {
return this.aiGuideService.getAIUsageStats();
}
// SMART RECOMMENDATIONS
@Get('recommendations/personalized')
@ApiOperation({ summary: 'Get personalized recommendations' })
@ApiQuery({ name: 'latitude', required: false, type: Number })
@ApiQuery({ name: 'longitude', required: false, type: Number })
@ApiQuery({ name: 'category', required: false, type: String })
async getPersonalizedRecommendations(
@Request() req,
@Query('latitude') latitude?: number,
@Query('longitude') longitude?: number,
@Query('category') category?: string,
) {
const queryDto: AIQueryDto = {
query: 'Show me personalized recommendations',
interactionType: 'recommendations' as any,
latitude,
longitude,
metadata: { category }
};
return this.aiGuideService.processAIQuery(queryDto, req.user.id);
}
// MONUMENT RECOGNITION
@Post('recognize-monument')
@ApiOperation({ summary: 'Recognize monument from image or location' })
async recognizeMonument(@Body() body: {
imageUrl?: string;
latitude?: number;
longitude?: number;
}, @Request() req) {
const queryDto: AIQueryDto = {
query: 'What is this monument?',
interactionType: 'monument-recognition' as any,
imageUrl: body.imageUrl,
latitude: body.latitude,
longitude: body.longitude,
};
return this.aiGuideService.processAIQuery(queryDto, req.user.id);
}
// AUDIO GUIDES
@Post('audio-guide')
@ApiOperation({ summary: 'Generate audio guide for location' })
async generateAudioGuide(@Body() body: {
placeId?: string;
latitude?: number;
longitude?: number;
language?: string;
}, @Request() req) {
const queryDto: AIQueryDto = {
query: 'Generate audio guide for this location',
interactionType: 'audio-guide' as any,
placeId: body.placeId,
latitude: body.latitude,
longitude: body.longitude,
language: body.language,
};
return this.aiGuideService.processAIQuery(queryDto, req.user.id);
}
// SMART DIRECTIONS
@Post('directions')
@ApiOperation({ summary: 'Get smart directions with points of interest' })
async getSmartDirections(@Body() body: {
destinationPlaceId?: string;
latitude?: number;
longitude?: number;
travelMode?: string;
}, @Request() req) {
const queryDto: AIQueryDto = {
query: `Get directions to ${body.destinationPlaceId || 'destination'}`,
interactionType: 'directions' as any,
placeId: body.destinationPlaceId,
latitude: body.latitude,
longitude: body.longitude,
metadata: { travelMode: body.travelMode || 'walking' }
};
return this.aiGuideService.processAIQuery(queryDto, req.user.id);
}
}