5.1 KiB
5.1 KiB
Frontend API Client
API client layer for Resume Matcher frontend.
Base Client (lib/api/client.ts)
export const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
export const API_BASE = `${API_URL}/api/v1`;
export async function apiFetch(endpoint: string, options?: RequestInit);
export async function apiPost<T>(endpoint: string, body: T);
export async function apiPatch<T>(endpoint: string, body: T);
export async function apiPut<T>(endpoint: string, body: T);
export async function apiDelete(endpoint: string);
export function getUploadUrl(): string;
Resume Operations (lib/api/resume.ts)
// Job descriptions
uploadJobDescriptions(descriptions: string[], resumeId: string) → job_id
// Resume improvement
improveResume(resumeId: string, jobId: string) → ImprovedResult
// CRUD
fetchResume(resumeId: string) → ResumeResponse['data']
fetchResumeList(includeMaster?: boolean) → ResumeListItem[]
updateResume(resumeId: string, data: ResumeData) → ResumeResponse['data']
deleteResume(resumeId: string) → void
// PDF
downloadResumePdf(resumeId: string, settings?: TemplateSettings) → Blob
downloadCoverLetterPdf(resumeId: string, pageSize?: string) → Blob
// Content updates
updateCoverLetter(resumeId: string, content: string) → void
updateOutreachMessage(resumeId: string, content: string) → void
// On-demand generated content
generateInterviewPrep(resumeId: string) → InterviewPrepData
Resume Wizard (lib/api/resume-wizard.ts)
postResumeWizardTurn(payload: ResumeWizardTurnRequest) → ResumeWizardTurnResponse
finalizeResumeWizard(state: ResumeWizardState) → ResumeWizardFinalizeResponse
createInitialResumeWizardState() → ResumeWizardState
Backend endpoints:
POST /api/v1/resume-wizard/turn— one adaptive turn.actionisstart | answer | skip | back | review.answer/skiprun one AI call that updatesresume_data, returns the nextcurrent_question,inferred_skills, and anis_completeflag;back/review/startare deterministic (no LLM). The fullResumeWizardStateround-trips in the request and response.POST /api/v1/resume-wizard/finalize— creates the single master resume from the draft (processing_status: "ready"), or409if a master already exists.
The wizard is an AI-led, one-question-at-a-time flow that builds a general master resume; it does not require a job description and does not replace the upload parser. Question and content text are produced in the configured content language; static UI chrome uses the resumeWizard.* i18n keys.
Application Tracker (lib/api/tracker.ts)
// Kanban board (7 status columns: saved | applied | no_response |
// response | interview | accepted | rejected)
listApplications() → ApplicationListResponse // { columns: Record<status, Application[]> }
createApplication(payload: ManualApplicationCreate) → Application // manual add from a pasted JD
getApplicationDetail(id: string) → ApplicationDetail // embedded JD + applied resume (resume null if deleted)
updateApplication(id: string, payload: ApplicationUpdate) → Application // status/position/notes/company/role/applied_at
// Bulk
bulkUpdateStatus(applicationIds: string[], status: ApplicationStatus) → ApplicationActionResponse
deleteApplication(id: string) → void
bulkDeleteApplications(applicationIds: string[]) → ApplicationActionResponse
Config Operations (lib/api/config.ts)
fetchLlmConfig() → LLMConfig
updateLlmConfig(config: LLMConfigUpdate) → LLMConfig
testLlmConnection() → LLMHealthCheck
fetchSystemStatus() → SystemStatus
// Per-provider API keys (encrypted server-side; switching the active
// provider no longer wipes another provider's key — responses always masked)
fetchApiKeyStatus() → ApiKeyStatusResponse // { providers: [{ provider, configured, masked_key }] }
updateApiKeys(keys: ApiKeysUpdateRequest) → ApiKeysUpdateResponse
deleteApiKey(provider: ApiKeyProvider) → void
clearAllApiKeys() → void
// Feature flags
fetchFeatureConfig() → FeatureConfig
updateFeatureConfig(config: FeatureConfigUpdate) → FeatureConfig
// Language
fetchLanguageConfig() → LanguageConfig
updateLanguageConfig(language: string) → LanguageConfig
updateLlmApiKey(PUT /config/llm-api-key) no longer persists a key — keys are managed per-provider via the encrypted/config/api-keysendpoints above.
Provider Info
export const PROVIDER_INFO = {
openai: { name: 'OpenAI', defaultModel: 'gpt-5-nano-2025-08-07', requiresKey: true },
anthropic: { name: 'Anthropic', defaultModel: 'claude-haiku-4-5-20251001', requiresKey: true },
openrouter: { name: 'OpenRouter', defaultModel: 'deepseek/deepseek-chat', requiresKey: true },
gemini: { name: 'Google Gemini', defaultModel: 'gemini-3-flash-preview', requiresKey: true },
deepseek: { name: 'DeepSeek', defaultModel: 'deepseek-chat', requiresKey: true },
ollama: { name: 'Ollama (Local)', defaultModel: 'gemma3:4b', requiresKey: false },
};
Usage
import { fetchResume, API_BASE, PROVIDER_INFO } from '@/lib/api';