Skip to the content.

Task 114 — Studio: migрація stores на Vue Query hooks

Phase: 8 Status: pending Owner: — Slug: studio-migrate-vue-query Studio Stage: 0-2

Goal

Мигрировать Pinia stores в Hercules Studio с hand-written HerculesClient calls на generated Orval Vue Query hooks. Постепенная миграция по доменам. Добавить @tanstack/vue-query plugin в Vue app.

Acceptance criteria

Vue Query setup

// main.ts
import { VueQueryPlugin } from "@tanstack/vue-query";
import { QueryClient } from "@tanstack/vue-query";

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 30_000,  // 30s — same as health polling
      retry: 1,
      refetchOnWindowFocus: false,
    },
    mutations: {
      onError: (err) => {
        const errorStore = useErrorStore();
        errorStore.report(err instanceof Error ? err.message : String(err), "mutation");
      },
    },
  },
});

app.use(VueQueryPlugin, { queryClient });

Migration pattern

// Before (hand-written)
import { HerculesClient } from "../sdk/client";

// In store:
async function loadSkills() {
  skills.value = await client.value.listSkills();
}

// After (generated Vue Query)
import { useListSkillsQuery, useCreateSkillMutation } from "../api/generated/skills/skills";

// In component <script setup>:
const { data: skills, isLoading, error } = useListSkillsQuery();
const { mutateAsync: createSkill } = useCreateSkillMutation();

Cache invalidation

import { useQueryClient } from "@tanstack/vue-query";

const queryClient = useQueryClient();

const { mutateAsync: createSkill } = useCreateSkillMutation({
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ["skills"] });
  },
});

Dependencies

Scope / Likely files

Notes