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, } })