# Automated API Client Generation System This document explains the automated TypeScript API client generation and update system for the AI Voicebot project. ## Overview The system automatically: 1. **Generates OpenAPI schema** from FastAPI server 2. **Creates TypeScript types** from the schema 3. **Updates API client** with missing endpoint implementations using dynamic paths 4. **Updates evolution checker** with current endpoint lists 5. **Validates TypeScript** compilation 6. **Runs evolution checks** to ensure completeness All generated API calls use the `PUBLIC_URL` environment variable to dynamically construct paths, making the system deployable to any base path without hardcoded `/ai-voicebot` prefixes. ## Files in the System ### Generated Files (Auto-updated) - `client/openapi-schema.json` - OpenAPI schema from server - `client/src/api-types.ts` - TypeScript type definitions - `client/src/api-client.ts` - API client (auto-sections updated) - `client/src/api-evolution-checker.ts` - Evolution checker (lists updated) ### Manual Files - `generate-ts-types.sh` - Main orchestration script - `client/update-api-client.js` - API client updater utility - `client/src/api-usage-examples.ts` - Usage examples and patterns ## Configuration ### Environment Variables The system uses environment variables for dynamic path configuration: - **`PUBLIC_URL`** - Base path for the application (e.g., `/ai-voicebot`, `/my-app`, etc.) - Used in: API paths, schema loading, asset paths - Default: `""` (empty string for root deployment) - Set in: Docker environment, build process, or runtime ### Dynamic Path Handling All API endpoints use dynamic path construction: ```typescript // Instead of hardcoded paths: // "/ai-voicebot/api/health" // The system uses: this.getApiPath("/ai-voicebot/api/health") // Which becomes: `${PUBLIC_URL}/api/health` ``` This allows deployment to different base paths without code changes. ## Usage ### Full Generation (Recommended) ```bash ./generate-ts-types.sh ``` This runs the complete pipeline and is the primary way to use the system. ### Individual Steps ```bash # Inside client container npm run generate-schema # Generate OpenAPI schema npm run generate-types # Generate TypeScript types npm run update-api-client # Update API client npm run check-api-evolution # Check for missing endpoints ``` ## How Auto-Updates Work ### API Client Updates The `update-api-client.js` script: 1. **Parses OpenAPI schema** to find all available endpoints 2. **Scans existing API client** to detect implemented methods 3. **Identifies missing endpoints** by comparing the two 4. **Generates method implementations** for missing endpoints 5. **Updates the client class** by inserting new methods in designated section 6. **Updates endpoint lists** used by evolution checking #### Auto-Generated Section ```typescript export class ApiClient { // ... manual methods ... /** * Construct API path using PUBLIC_URL environment variable * Replaces hardcoded /ai-voicebot prefix with dynamic base from environment */ private getApiPath(schemaPath: string): string { return schemaPath.replace('/ai-voicebot', base); } // Auto-generated endpoints will be added here by update-api-client.js // DO NOT MANUALLY EDIT BELOW THIS LINE // New endpoints automatically appear here using this.getApiPath() } ``` #### Method Generation - **Method names** derived from `operationId` or path/method combination - **Parameters** inferred from path parameters and request body - **Return types** use generic `Promise` (can be enhanced) - **Path handling** supports both static and parameterized paths using `PUBLIC_URL` - **Dynamic paths** automatically replace hardcoded prefixes with environment-based values ### Evolution Checker Updates The evolution checker tracks: - **Known schema endpoints** - updated from current OpenAPI schema - **Implemented endpoints** - updated from actual API client code - **Missing endpoints** - calculated difference for warnings ## Customization ### Adding Manual Endpoints For endpoints not in OpenAPI schema (e.g., external services), add them manually before the auto-generated section: ```typescript // Manual endpoints (these won't be auto-generated) async getCustomData(): Promise { return this.request("/custom/endpoint", { method: "GET" }); } // Auto-generated endpoints will be added here by update-api-client.js // DO NOT MANUALLY EDIT BELOW THIS LINE ``` ### Improving Generated Methods To enhance auto-generated methods: 1. **Better Type Inference**: Modify `generateMethodSignature()` in `update-api-client.js` to use specific types from schema 2. **Parameter Validation**: Add validation logic in method generation 3. **Error Handling**: Customize error handling patterns 4. **Documentation**: Add JSDoc generation from OpenAPI descriptions ### Schema Evolution Detection The system detects: - **New endpoints** added to OpenAPI schema - **Changed endpoints** (parameter or response changes) - **Deprecated endpoints** (with proper OpenAPI marking) ## Development Workflow 1. **Develop API endpoints** in FastAPI server with proper typing 2. **Run generation script** to update client: `./generate-ts-types.sh` 3. **Use generated types** in React components 4. **Manual customization** for complex endpoints if needed 5. **Commit all changes** including generated and updated files ## Best Practices ### Server Development - Use **Pydantic models** for all request/response types - Add **proper OpenAPI metadata** (summary, description, tags) - Use **consistent naming** for operation IDs - **Version your API** to handle breaking changes ### Client Development - **Import from api-client.ts** rather than making raw fetch calls - **Use generated types** for type safety - **Avoid editing auto-generated sections** - they will be overwritten - **Add custom endpoints manually** when needed ### Type Safety ```typescript // Good: Using generated types and client import { apiClient, type LobbyModel, type LobbyCreateRequest } from './api-client'; const createLobby = async (data: LobbyCreateRequest): Promise => { const response = await apiClient.createLobby(sessionId, data); return response.data; // Fully typed }; // Avoid: Direct fetch calls const createLobbyRaw = async () => { const response = await fetch('/api/lobby', { /* ... */ }); return response.json(); // No type safety }; ``` ## Troubleshooting ### Common Issues **"Could not find insertion marker"** - The API client file was manually edited and the auto-generation markers were removed - Restore the markers or regenerate the client file from template **"Missing endpoints detected"** - New endpoints were added to the server but the generation script wasn't run - Run `./generate-ts-types.sh` to update the client **"Type errors after generation"** - Schema changes may have affected existing manual code - Check the TypeScript compiler output and update affected code **"Duplicate method names"** - Manual methods conflict with auto-generated ones - Rename manual methods or adjust the operation ID generation logic ### Debug Mode Add debug logging by modifying `update-api-client.js`: ```javascript // Add after parsing console.log('Schema endpoints:', this.endpoints.map(e => `${e.method}:${e.path}`)); console.log('Implemented endpoints:', Array.from(this.implementedEndpoints)); ``` ## Future Enhancements - **Stronger type inference** from OpenAPI schema components - **Request/response validation** using schema definitions - **Mock data generation** for testing - **API versioning support** with backward compatibility - **Performance optimization** with request caching - **OpenAPI spec validation** before generation ## Integration with Build Process The system integrates with: - **Docker Compose** for cross-container coordination - **npm scripts** for frontend build pipeline - **TypeScript compilation** for type checking - **CI/CD workflows** for automated updates This ensures that API changes are automatically reflected in the frontend without manual intervention, reducing development friction and preventing API/client drift.