fc5: migration Pinia store — trigger + FormData upload + 2s poll + history list

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 09:03:38 -04:00
parent 89224a7895
commit b600cf6e86
+83
View File
@@ -0,0 +1,83 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useApi } from '../composables/useApi.js'
const POLL_MS = 2000
export const useMigrationStore = defineStore('migration', () => {
const api = useApi()
const activeRun = ref(null)
const recentRuns = ref([])
const error = ref(null)
const loading = ref(false)
let pollHandle = null
async function trigger(kind, params, file = null) {
loading.value = true
error.value = null
try {
let body
if (file) {
// Multipart upload for ingest kinds.
const form = new FormData()
form.append('export_file', file)
if (params && params.dry_run) form.append('dry_run', 'true')
if (params && params.force) form.append('force', 'true')
body = await api.post(`/api/migrate/${kind}`, { body: form })
} else {
body = await api.post(`/api/migrate/${kind}`, { body: params || {} })
}
await loadRun(body.run_id)
pollActive(body.run_id)
return body
} catch (e) {
error.value = e
throw e
} finally {
loading.value = false
}
}
async function loadRun(runId) {
activeRun.value = await api.get(`/api/migrate/runs/${runId}`)
}
async function loadRecent() {
recentRuns.value = await api.get('/api/migrate/runs', { params: { limit: 10 } })
}
function pollActive(runId) {
stopPolling()
pollHandle = setInterval(async () => {
try {
const run = await api.get(`/api/migrate/runs/${runId}`)
activeRun.value = run
if (run.status === 'ok' || run.status === 'error') {
stopPolling()
await loadRecent()
}
} catch (e) {
error.value = e
stopPolling()
}
}, POLL_MS)
}
function stopPolling() {
if (pollHandle) {
clearInterval(pollHandle)
pollHandle = null
}
}
const isRunning = computed(
() => activeRun.value && activeRun.value.status === 'running',
)
return {
activeRun, recentRuns, error, loading, isRunning,
trigger, loadRun, loadRecent, pollActive, stopPolling,
}
})