This document provides a comprehensive overview of all APIs used in the TourGuideAI application, including external APIs, internal architecture, and usage examples.
The OpenAI API is used for natural language processing and content generation tasks within TourGuideAI:
- Purpose: Generate travel itineraries, recognize travel intent from user queries, create travel recommendations
- API Version: GPT-4 / GPT-3.5-turbo
- Endpoints Used:
- Completions API - For general text generation
- Chat Completions API - For conversation-based interactions
- Configuration: Requires API key set in
.envfile asREACT_APP_OPENAI_API_KEY - Caching Strategy: Stale-while-revalidate with 24-hour TTL, LZ-string compression for responses
The Google Maps Platform provides a suite of APIs used for location-based features:
- Purpose: Display maps, search locations, calculate routes, find nearby attractions
- API Services Used:
- Maps JavaScript API - For map rendering and interaction
- Places API - For location search and points of interest
- Directions API - For route calculation
- Geocoding API - For converting addresses to coordinates
- Configuration: Requires API key set in
.envfile asREACT_APP_GOOGLE_MAPS_API_KEY
TourGuideAI uses a structured approach to API integration:
src/
├── core/
│ ├── api/
│ │ ├── googleMapsApi.js # Core Google Maps integration
│ │ ├── openaiApi.js # Core OpenAI integration
│ │ └── index.js # API exports
│ └── services/
│ └── apiClient.js # Common API client with caching
└── api/
├── googleMapsApi.js # Legacy (redirects to core)
└── openaiApi.js # Legacy (redirects to core)
- Core API Modules: Primary implementations with full functionality
- Legacy API Modules: Compatibility layer that re-exports from core modules
- Server Proxy: For secure API key management, requests can be proxied through backend
TourGuideAI's API modules are organized to prevent naming conflicts and ensure clean imports:
API modules use namespaced exports to avoid naming conflicts between different service integrations:
// core/api/index.js
import * as googleMapsApi from './googleMapsApi';
import * as openaiApi from './openaiApi';
import * as weatherApi from './weatherApi';
// Export all APIs as namespaces
export {
googleMapsApi,
openaiApi,
weatherApi
};
// Provide a default API client for simple HTTP requests
export { default } from '../services/apiClient';// Import specific API module with namespace
import { googleMapsApi } from '../core/api';
// Use the API with namespaced functions
googleMapsApi.geocodeAddress("Eiffel Tower, Paris");
googleMapsApi.displayRouteOnMap({ origin: "Paris", destination: "Nice" });
// Import multiple API modules
import { googleMapsApi, openaiApi } from '../core/api';
// Use different API modules without conflict
const location = await googleMapsApi.geocodeAddress("Eiffel Tower");
const description = await openaiApi.generateDescription(location);For external libraries that inject global variables, we use ESLint directives to prevent linting errors:
// In googleMapsApi.js
/* global google */
// This tells ESLint that 'google' is a global variable
function initializeMap(container, options) {
return new google.maps.Map(container, options);
}For simple HTTP requests without specific API requirements, a default API client is available:
// Import default API client
import apiClient from '../core/api';
// Use for generic HTTP requests
const data = await apiClient.get('/endpoint', { params });
const result = await apiClient.post('/endpoint', payload);- Intent Recognition: Extract travel preferences from natural language
- Route Generation: Create complete travel itineraries based on user input
- Accommodation Recommendations: Suggest lodging options based on preferences
- Travel Tips: Generate location-specific advice for travelers
import * as openaiApi from '../core/api/openaiApi';
// Initialize the API (only needed once, typically in app initialization)
openaiApi.setApiKey(process.env.REACT_APP_OPENAI_API_KEY);
openaiApi.setUseServerProxy(true); // Use server proxy for security
// Recognize travel intent from user query
const intent = await openaiApi.recognizeTextIntent(
"I want to visit Paris for 3 days next month and focus on art museums"
);
// Result: { arrival: "Paris", travel_duration: "3 days", ... }
// Generate a complete travel route
const route = await openaiApi.generateRoute(
"Plan a trip to Paris focusing on art museums",
intent
);
// Result: { route_name: "Paris Art Tour", destination: "Paris", ... }try {
const route = await openaiApi.generateRoute(userQuery, intent);
// Process successful response
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED') {
// Handle rate limiting
} else if (error.status === 401) {
// Handle authentication error
} else {
// Handle other errors
}
}- Map Rendering: Display interactive maps with custom markers and overlays
- Geocoding: Convert addresses to coordinates and vice versa
- Route Display: Visualize travel routes with directions
- Points of Interest: Find attractions near specified locations
- Place Details: Get comprehensive information about locations
import * as googleMapsApi from '../core/api/googleMapsApi';
// Initialize the API (only needed once, typically in app initialization)
googleMapsApi.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY);
googleMapsApi.setUseServerProxy(true); // Use server proxy for security
// Initialize a map in a container element
const mapContainer = document.getElementById('map-container');
const map = await googleMapsApi.initializeMap(mapContainer, {
center: { lat: 48.8566, lng: 2.3522 }, // Paris
zoom: 12
});
// Geocode an address to coordinates
const location = await googleMapsApi.geocodeAddress("Eiffel Tower, Paris");
// Result: { location: { lat: 48.8584, lng: 2.2945 }, ... }
// Find nearby attractions
const attractions = await googleMapsApi.getNearbyInterestPoints(
location.location,
2000, // radius in meters
'museum'
);
// Display a route on the map
const routeData = await googleMapsApi.displayRouteOnMap({
origin: "Louvre Museum, Paris",
destination: "Eiffel Tower, Paris",
travelMode: "WALKING"
});The API client service provides a unified interface for all API calls with advanced features:
- Caching: Automatically caches responses for improved performance
- Retry Logic: Automatically retries failed requests with exponential backoff
- Offline Support: Falls back to cached data when offline
- Error Handling: Consistent error formatting and logging
import { apiHelpers } from '../core/services/apiClient';
// Make GET request with automatic caching
const data = await apiHelpers.get('/maps/geocode', {
params: { address: 'Paris' }
});
// Make POST request
const result = await apiHelpers.post('/openai/generate-route', {
query: "Plan a trip to Paris",
preferences: { duration: "3 days" }
});
// Clear cache
await apiHelpers.clearCache();TourGuideAI implements several security measures for API usage:
- Server-Side Proxying: API keys are stored only on the server
- Key Rotation: Automatic monitoring of API key age with rotation reminders
- Rate Limiting: Prevents API quota exhaustion
- Request Validation: All inputs are validated before sending to external APIs
All API configuration is managed through environment variables:
# API Configuration
REACT_APP_OPENAI_API_KEY=your_openai_key_here
REACT_APP_GOOGLE_MAPS_API_KEY=your_google_maps_key_here
# API Settings
REACT_APP_USE_SERVER_PROXY=true
REACT_APP_API_URL=http://localhost:3000/api
# OpenAI Settings
REACT_APP_OPENAI_MODEL=gpt-4
REACT_APP_OPENAI_TEMPERATURE=0.7
# Caching Settings
REACT_APP_API_CACHE_DURATION=3600000
See .env.example for a complete list of configuration options.
If you're working with older code that imports APIs from the legacy paths, please update your imports to use the core implementations. See API_MIGRATION.md for detailed migration instructions.
TourGuideAI implements a comprehensive caching strategy to improve performance, reduce API costs, and enable offline capabilities:
The core caching mechanism is provided by CacheService in src/core/services/storage/CacheService.js:
- TTL-Based Caching: All API responses are cached with configurable Time-To-Live values
- Compression: LZ-string compression reduces storage size by approximately 70%
- Cache Invalidation: Automatic invalidation based on TTL with background cleanup
- Cache Prioritization: Size-based priority system auto-cleans older items when storage limit is reached
- API-Specific TTLs: Different cache expiration times based on data volatility:
- Travel routes: 7 days
- Points of interest: 30 days
- Location search: 60 days
- User preferences: 1 day
A service worker in public/service-worker.js provides browser-level API caching:
- Strategy: Network-first with cache fallback for API requests
- Offline Support: Cached API responses are available when offline
- Cache Control: Separate cache storage from application data
- Background Sync: Pending operations are queued for execution when online
For common API requests, TourGuideAI implements prefetching to improve perceived performance:
- Route Prefetching: Likely next routes are prefetched when users are browsing related routes
- Location Prefetching: Nearby location data is prefetched when viewing a destination
- Preload Strategy: Low-priority background fetching during idle periods
Phase 5 (completed March 23, 2023) introduced significant performance optimizations for API interactions:
Multiple related API requests are now batched to reduce network overhead:
// Instead of multiple separate calls
const batchedResults = await apiHelpers.batchRequests([
{ path: '/maps/geocode', params: { address: 'Paris' } },
{ path: '/maps/nearby', params: { location: 'Paris', type: 'museum' } },
{ path: '/maps/nearby', params: { location: 'Paris', type: 'restaurant' } }
]);Non-dependent requests are processed in parallel:
const [weatherData, attractionsData] = await Promise.all([
apiHelpers.get('/weather', { params: { location: 'Paris' } }),
apiHelpers.get('/attractions', { params: { location: 'Paris' } })
]);For large responses like route data, streaming is now supported:
const routeStream = apiHelpers.getStream('/routes/generate', {
params: { destination: 'Paris', duration: 7 }
});
routeStream.on('data', (chunk) => {
// Process partial route data as it arrives
updateRouteDisplay(chunk);
});All API responses now use enhanced compression techniques:
- Network Compression: gzip/brotli for transit compression
- Storage Compression: LZ-string for client-side storage
- Payload Optimization: Response filtering to remove unnecessary data
CPU-intensive processing of API data is offloaded to web workers:
const routeWorker = new Worker('/workers/route-processor.js');
routeWorker.onmessage = (event) => {
const { processedRoute } = event.data;
displayRoute(processedRoute);
};
routeWorker.postMessage({
action: 'processRouteData',
routeData: rawRouteData
});All API requests include robust error handling:
- Exponential Backoff: Automatic retry with increasing delays
- Circuit Breaking: Temporary disabling of failing endpoints
- Fallback Mechanism: Cached data served when APIs fail
- Graceful Degradation: Progressive reduction in functionality based on available data
- Centralized Logging: All API errors are logged to a central service
- User Feedback: Friendly error messages with actionable information
- Silent Recovery: Background retry attempts without disrupting user experience
The TourGuideAI API provides the following endpoints:
Authenticate a beta user and get a JWT token.
Request Body:
{
"email": "user@example.com",
"password": "password123"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "abc123",
"email": "user@example.com",
"name": "John Doe",
"role": "beta-tester"
}
}Register a new beta tester with an invitation code.
Request Body:
{
"email": "user@example.com",
"password": "password123",
"name": "John Doe",
"inviteCode": "BETA123"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "abc123",
"email": "user@example.com",
"name": "John Doe",
"role": "beta-tester",
"emailVerified": false
},
"message": "Registration successful. Please verify your email."
}Register a new user with admin privileges (requires admin access).
Headers:
Authorization: Bearer <admin-token>
Request Body:
{
"email": "admin@example.com",
"password": "password123",
"name": "Admin User",
"role": "admin"
}Response:
{
"user": {
"id": "xyz789",
"email": "admin@example.com",
"name": "Admin User",
"role": "admin",
"emailVerified": false
}
}Logout and invalidate the JWT token.
Headers:
Authorization: Bearer <token>
Response:
{
"message": "Logged out successfully"
}Get current authenticated user's information.
Headers:
Authorization: Bearer <token>
Response:
{
"user": {
"id": "abc123",
"email": "user@example.com",
"name": "John Doe",
"role": "beta-tester",
"emailVerified": true,
"permissions": ["read:feedback", "create:feedback", "read:routes"]
}
}Get current authenticated user's permissions and roles.
Headers:
Authorization: Bearer <token>
Response:
{
"permissions": ["read:feedback", "create:feedback", "read:routes"],
"role": "beta-tester"
}Verify a user's email address using the token sent to their email.
Response:
{
"message": "Email verified successfully",
"emailVerified": true
}Request a password reset email.
Request Body:
{
"email": "user@example.com"
}Response:
{
"message": "Password reset email sent"
}Reset password using the token sent to the user's email.
Request Body:
{
"password": "newpassword123"
}Response:
{
"message": "Password reset successfully"
}Generate a new invitation code (requires CREATE_INVITE permission).
Headers:
Authorization: Bearer <token>
Request Body:
{
"maxUses": 10,
"expiresAt": "2023-12-31T23:59:59Z"
}Response:
{
"code": "BETA123",
"maxUses": 10,
"expiresAt": "2023-12-31T23:59:59Z",
"usedCount": 0,
"active": true,
"createdBy": "abc123"
}List all invitation codes (requires READ_INVITE permission).
Headers:
Authorization: Bearer <token>
Response:
{
"inviteCodes": [
{
"code": "BETA123",
"maxUses": 10,
"expiresAt": "2023-12-31T23:59:59Z",
"usedCount": 2,
"active": true,
"createdBy": "abc123",
"createdAt": "2023-06-01T12:00:00Z"
},
// More invite codes...
]
}Invalidate an invitation code (requires UPDATE_INVITE permission).
Headers:
Authorization: Bearer <token>
Response:
{
"code": "BETA123",
"active": false,
"message": "Invite code invalidated successfully"
}Send a welcome email to a user (automatic on registration).
Headers:
Authorization: Bearer <admin-token>
Request Body:
{
"email": "user@example.com",
"name": "John Doe"
}Response:
{
"message": "Welcome email sent successfully"
}Send or resend a verification email.
Headers:
Authorization: Bearer <token>(optional - for resending)
Request Body:
{
"email": "user@example.com"
}Response:
{
"message": "Verification email sent successfully"
}Send a password reset email.
Request Body:
{
"email": "user@example.com"
}Response:
{
"message": "Password reset email sent successfully"
}// ... existing code ...
The following APIs are used specifically for the Beta Program features:
- Purpose: Handle user authentication, registration, and profile management for beta testers
- Base Endpoint:
/api/auth - Endpoints:
POST /api/auth/login- Authenticate user and return JWT tokenPOST /api/auth/register- Register new beta tester with invite codePOST /api/auth/verify-email- Verify user email with tokenPOST /api/auth/reset-password- Request password resetPOST /api/auth/reset-password/confirm- Confirm password reset with tokenGET /api/auth/profile- Get current user profilePUT /api/auth/profile- Update user profileGET /api/auth/permissions- Get user permissions based on role
- Purpose: Manage the onboarding process for new beta testers
- Base Endpoint:
/api/onboarding - Endpoints:
POST /api/onboarding/verify-code- Verify beta invite codePOST /api/onboarding/profile- Save user profile informationPOST /api/onboarding/preferences- Save user preferencesGET /api/onboarding/status- Get current onboarding statusPOST /api/onboarding/complete- Mark onboarding as complete
- Purpose: Create, manage, and respond to surveys
- Base Endpoint:
/api/surveys - Endpoints:
GET /api/surveys- List all surveys (with filtering options)POST /api/surveys- Create new surveyGET /api/surveys/:id- Get survey by IDPUT /api/surveys/:id- Update surveyDELETE /api/surveys/:id- Delete surveyPOST /api/surveys/:id/publish- Publish survey (change status to active)POST /api/surveys/:id/responses- Submit survey responseGET /api/surveys/:id/responses- Get all responses for surveyGET /api/surveys/:id/analytics- Get survey response analytics
- Purpose: Provide analytics data for admin users
- Base Endpoint:
/api/analytics - Endpoints:
GET /api/analytics/users- Get user activity metricsGET /api/analytics/feedback- Get feedback analysisGET /api/analytics/features- Get feature usage statisticsGET /api/analytics/surveys- Get survey participation metricsGET /api/analytics/demographics- Get user demographic dataGET /api/analytics/export- Export analytics data (CSV/JSON)GET /api/analytics/realtime- Get real-time user activity
- Purpose: Collect and categorize user feedback
- Base Endpoint:
/api/feedback - Endpoints:
POST /api/feedback- Submit new feedbackGET /api/feedback- List all feedback (admin only)GET /api/feedback/categories- Get feedback categoriesPUT /api/feedback/:id/status- Update feedback statusPOST /api/feedback/:id/screenshot- Upload feedback screenshot