# DeepSeek API Integration with PocketBase React Apps ## Pattern React frontend → nginx `/deepseek/` proxy → `https://api.deepseek.com/` with API key. ## Server Proxy (nginx) ```nginx location /deepseek/ { proxy_pass https://api.deepseek.com/; proxy_ssl_server_name on; proxy_ssl_name api.deepseek.com; proxy_http_version 1.1; proxy_set_header Host api.deepseek.com; proxy_set_header Authorization "Bearer sk-..."; proxy_set_header Content-Type "application/json"; proxy_buffering off; proxy_read_timeout 120s; } ``` ## Client Module (`src/lib/ai.ts`) Core fetch helper — all AI calls go through this: ```typescript async function callDeepSeek( systemPrompt: string, userContent: string, maxTokens = 500, temperature = 0, ): Promise { const res = await fetch('/deepseek/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'deepseek-v4-flash', messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userContent }, ], temperature, thinking: { type: 'disabled' as const }, max_tokens: maxTokens, }), }); if (!res.ok) return null; const data = await res.json(); return data?.choices?.[0]?.message?.content || null; } ``` **Critical:** Set `thinking: { type: 'disabled' }` — without it, `deepseek-v4-flash` spends all token budget on reasoning content and returns empty `content`. ## Three Functions We Built ### 1. AI Write Explanation — generates professional customer-facing service descriptions ```typescript export async function aiWriteExplanation( params: ExplanationParams, ): Promise ``` Takes `serviceName`, `recommendation`, optional `technicianNotes`, `vehicleInfo`, `mileage`, `maintenanceInterval`. Returns `{level: 'CRITICAL'|'RECOMMENDED'|'OPTIONAL'|'PREVENTIVE'|'MAINTENANCE', explanation: string}`. Parses `LEVEL:` and `EXPLANATION:` from the AI response. ### 2. Generate Priorities — ranks services by safety criticality ```typescript export async function getPriorityAnalysis( services: ServiceItem[], ): Promise ``` Returns `{name, rank, priority_reason}[]` sorted by rank. AI prompt forces safety-first ordering: CRITICAL_SAFETY > SAFETY_CONCERN > RECOMMENDED > MAINTENANCE > OPTIONAL. ### 3. AI Suggest Services — recommends services from catalog based on vehicle + mileage ```typescript export async function aiSuggestServices( vehicle: SuggestVehicle, selectedServices: string[], catalog: CatalogItem[], ): Promise ``` Only returns services that exist in the provided catalog (cross-references by name). Uses mileage-based maintenance intervals. ## Response Parsing Safety Always strip markdown code blocks before JSON parsing: ```typescript function stripCodeBlocks(text: string): string { return text.trim().replace(/```json\s*/gi, '').replace(/```\s*/g, '').trim(); } ``` All functions return `null` on failure (not throwing) so callers can handle gracefully with toast notifications. ## Fallback: Local Ollama If the DeepSeek API is unavailable, proxy to Ollama instead. Change the proxy URL and model name: ```nginx location /deepseek/ { proxy_pass http://127.0.0.1:11434/; ... } ``` ```typescript // In ai.ts model: 'qwen2.5:14b', // or llava:13b ``` ## UI Integration Add Sparkles/ListOrdered/Lightbulb buttons to the service management UI. Each button: 1. Sets loading state (disables button, shows spinner) 2. Calls the AI function 3. On success: updates the service/quote state, shows success toast 4. On failure: shows error toast, re-enables button 5. Always: re-enables button in finally block