fix: survey store quality issues — loading in fetchFor, source guard, saveResponse failure test

This commit is contained in:
pyr0ball 2026-03-21 00:21:21 -07:00
parent ac8f949a19
commit 7b634cb46a
2 changed files with 57 additions and 13 deletions

View file

@ -119,6 +119,38 @@ describe('useSurveyStore', () => {
expect(store.saving).toBe(false)
})
it('saveResponse sets error and preserves analysis on POST failure', async () => {
const mockApiFetch = vi.mocked(useApiFetch)
// Setup: fetchFor
mockApiFetch
.mockResolvedValueOnce({ data: [], error: null })
.mockResolvedValueOnce({ data: { available: true }, error: null })
const store = useSurveyStore()
await store.fetchFor(1)
// Set analysis state manually
store.analysis = {
output: '1. B — reason',
source: 'text_paste',
mode: 'quick',
rawInput: 'Q1: test',
}
// Save fails
mockApiFetch.mockResolvedValueOnce({
data: null,
error: { kind: 'http', status: 500, detail: 'Internal Server Error' },
})
await store.saveResponse(1, { surveyName: 'Round 1', reportedScore: '85%' })
expect(store.saving).toBe(false)
expect(store.error).toBeTruthy()
expect(store.analysis).not.toBeNull()
expect(store.analysis!.output).toBe('1. B — reason')
})
it('clear resets all state to initial values', async () => {
const mockApiFetch = vi.mocked(useApiFetch)
mockApiFetch

View file

@ -2,6 +2,12 @@ import { ref } from 'vue'
import { defineStore } from 'pinia'
import { useApiFetch } from '../composables/useApi'
const validSources = ['text_paste', 'screenshot'] as const
type ValidSource = typeof validSources[number]
function isValidSource(s: string): s is ValidSource {
return validSources.includes(s as ValidSource)
}
export interface SurveyAnalysis {
output: string
source: 'text_paste' | 'screenshot'
@ -40,6 +46,8 @@ export const useSurveyStore = defineStore('survey', () => {
currentJobId.value = jobId
}
loading.value = true
try {
const [historyResult, visionResult] = await Promise.all([
useApiFetch<SurveyResponse[]>(`/api/jobs/${jobId}/survey/responses`),
useApiFetch<{ available: boolean }>('/api/vision/health'),
@ -52,6 +60,9 @@ export const useSurveyStore = defineStore('survey', () => {
}
visionAvailable.value = visionResult.data?.available ?? false
} finally {
loading.value = false
}
}
async function analyze(
@ -71,7 +82,7 @@ export const useSurveyStore = defineStore('survey', () => {
}
analysis.value = {
output: data.output,
source: data.source as 'text_paste' | 'screenshot',
source: isValidSource(data.source) ? data.source : 'text_paste',
mode: payload.mode,
rawInput: payload.text ?? null,
}
@ -103,6 +114,7 @@ export const useSurveyStore = defineStore('survey', () => {
return
}
// Prepend the saved response to history
const now = new Date().toISOString()
const saved: SurveyResponse = {
id: data.id,
survey_name: args.surveyName || null,
@ -112,8 +124,8 @@ export const useSurveyStore = defineStore('survey', () => {
image_path: null,
llm_output: analysis.value.output,
reported_score: args.reportedScore || null,
received_at: new Date().toISOString(),
created_at: new Date().toISOString(),
received_at: now,
created_at: now,
}
history.value = [saved, ...history.value]
analysis.value = null