Compare commits

...

4 Commits

Author SHA1 Message Date
yushen
519811006d fix: update test description from 'node id' to 'instance id'
Co-authored-by: multica-agent <github@multica.ai>
2026-05-21 18:07:10 +08:00
yushen
233bd7db60 fix: pass node.instance_id and rename param to instanceId
- cloud-runtime-dialog.tsx: deleteNode.mutate(node.instance_id)
- client.ts: rename nodeId param to instanceId
- cloud-runtime.ts: rename nodeId param to instanceId
- client.test.ts: use i-0123456789abcdef0 test value

Co-authored-by: multica-agent <github@multica.ai>
2026-05-21 18:03:13 +08:00
yushen
ae4191fab1 fix(ui): pass node.instance_id instead of node.id to deleteNode mutation
Fleet expects the actual AWS instance_id (e.g. i-0123456789abcdef0),
not the internal DB id. Updated the mutate call in cloud-runtime-dialog
to pass node.instance_id so the correct value reaches Fleet's
DELETE /api/v1/nodes endpoint.

Co-authored-by: multica-agent <github@multica.ai>
2026-05-21 17:59:32 +08:00
yushen
bc79a94b5f fix(api): use instance_id in deleteCloudRuntimeNode body
Fleet API requires instance_id, not id. Fixes 'instance_id is required' error.

MUL-2510

Co-authored-by: multica-agent <github@multica.ai>
2026-05-21 17:53:33 +08:00
4 changed files with 7 additions and 7 deletions

View File

@@ -234,21 +234,21 @@ describe("ApiClient", () => {
).resolves.toMatchObject({ id: "", status: "" });
});
it("deleteCloudRuntimeNode sends DELETE with JSON body containing node id", async () => {
it("deleteCloudRuntimeNode sends DELETE with JSON body containing instance id", async () => {
const fetchMock = vi.fn().mockResolvedValueOnce(
new Response(null, { status: 204 }),
);
vi.stubGlobal("fetch", fetchMock);
const client = new ApiClient("https://api.example.test");
await client.deleteCloudRuntimeNode("node-abc-123");
await client.deleteCloudRuntimeNode("i-0123456789abcdef0");
expect(fetchMock).toHaveBeenCalledTimes(1);
const [url, opts] = fetchMock.mock.calls[0]!;
expect(url).toBe("https://api.example.test/api/cloud-runtime/nodes");
expect(opts).toMatchObject({
method: "DELETE",
body: JSON.stringify({ id: "node-abc-123" }),
body: JSON.stringify({ instance_id: "i-0123456789abcdef0" }),
});
expect((opts.headers as Record<string, string>)["Content-Type"]).toBe(
"application/json",

View File

@@ -869,10 +869,10 @@ export class ApiClient {
);
}
async deleteCloudRuntimeNode(nodeId: string): Promise<void> {
async deleteCloudRuntimeNode(instanceId: string): Promise<void> {
await this.fetchRaw("/api/cloud-runtime/nodes", {
method: "DELETE",
body: JSON.stringify({ id: nodeId }),
body: JSON.stringify({ instance_id: instanceId }),
extraHeaders: { "Content-Type": "application/json" },
});
}

View File

@@ -83,7 +83,7 @@ export function useCreateCloudRuntimeNode(wsId: string) {
export function useDeleteCloudRuntimeNode(wsId: string) {
const qc = useQueryClient();
return useMutation({
mutationFn: (nodeId: string) => api.deleteCloudRuntimeNode(nodeId),
mutationFn: (instanceId: string) => api.deleteCloudRuntimeNode(instanceId),
onSettled: () => {
qc.invalidateQueries({ queryKey: cloudRuntimeKeys.all(wsId) });
},

View File

@@ -327,7 +327,7 @@ function CloudRuntimeNodeRow({ node, wsId }: { node: CloudRuntimeNode; wsId: str
disabled={deleteNode.isPending}
onClick={() => {
if (!confirm(t(($) => $.cloud_runtime.delete_confirm))) return;
deleteNode.mutate(node.id, {
deleteNode.mutate(node.instance_id, {
onSuccess: () => toast.success(t(($) => $.cloud_runtime.toast_deleted)),
onError: (err) =>
toast.error(