Co-authored-by: domfelipe <53182096+domfelipe@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot] 2026-05-28 21:56:41 +00:00
parent b687ad9b72
commit 2fe5d4a33e

View file

@ -35,6 +35,9 @@ Deno.serve(async (req) => {
const userId = userData.user.id; const userId = userData.user.id;
let body: { skill_version_id?: string; test_input?: string }; let body: { skill_version_id?: string; test_input?: string };
try {
body = await req.json();
let body: { skill_version_id?: string; test_input?: string; markdown_content?: string };
try { try {
body = await req.json(); body = await req.json();
} catch { } catch {
@ -44,53 +47,62 @@ Deno.serve(async (req) => {
}); });
} }
const { skill_version_id, test_input } = body; const { skill_version_id, test_input, markdown_content } = body;
if (!skill_version_id || !test_input || test_input.trim().length === 0) { if (!test_input || test_input.trim().length === 0) {
return new Response( return new Response(
JSON.stringify({ error: "skill_version_id e test_input são obrigatórios" }), JSON.stringify({ error: "test_input é obrigatório" }),
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }, { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } },
); );
} }
// Verifica ownership: skill_version -> skill -> user_id // Stateless mode: markdown_content direto (preview de nova skill, sem persistência)
const { data: versionRow, error: vErr } = await admin const isStateless =
.from("skill_versions") !!markdown_content &&
.select("id, markdown_content, skills!inner(user_id)") markdown_content.trim().length > 0 &&
.eq("id", skill_version_id) (!skill_version_id || skill_version_id === "preview");
.maybeSingle();
if (vErr || !versionRow) { let resolvedMarkdown: string | null = null;
return new Response(JSON.stringify({ error: "Versão não encontrada" }), { let persistedVersionId: string | null = null;
status: 404,
headers: { ...corsHeaders, "Content-Type": "application/json" }, if (isStateless) {
}); if (markdown_content!.length > 50000) {
} return new Response(JSON.stringify({ error: "markdown_content excede 50.000 caracteres" }), {
// @ts-expect-error supabase nested type status: 400,
if (versionRow.skills.user_id !== userId) { headers: { ...corsHeaders, "Content-Type": "application/json" },
return new Response(JSON.stringify({ error: "Acesso negado" }), { });
status: 403, }
headers: { ...corsHeaders, "Content-Type": "application/json" }, resolvedMarkdown = markdown_content!;
}); } else {
if (!skill_version_id) {
return new Response(
JSON.stringify({ error: "skill_version_id ou markdown_content é obrigatório" }),
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } },
);
}
// Verifica ownership: skill_version -> skill -> user_id
const { data: versionRow, error: vErr } = await admin
.from("skill_versions")
.select("id, markdown_content, skills!inner(user_id)")
.eq("id", skill_version_id)
.maybeSingle();
if (vErr || !versionRow) {
return new Response(JSON.stringify({ error: "Versão não encontrada" }), {
status: 404,
headers: { ...corsHeaders, "Content-Type": "application/json" },
});
}
// @ts-expect-error supabase nested type
if (versionRow.skills.user_id !== userId) {
return new Response(JSON.stringify({ error: "Acesso negado" }), {
status: 403,
headers: { ...corsHeaders, "Content-Type": "application/json" },
});
}
resolvedMarkdown = versionRow.markdown_content as string;
persistedVersionId = skill_version_id;
} }
// Cria registro running
const { data: runRow, error: runErr } = await admin
.from("skill_test_runs")
.insert({
skill_version_id,
user_id: userId,
test_input,
status: "running",
test_type: "dry_run",
})
.select("id")
.single();
if (runErr || !runRow) {
console.error("Failed to create test run:", runErr);
return new Response(JSON.stringify({ error: "Falha ao registrar teste" }), {
status: 500,
headers: { ...corsHeaders, "Content-Type": "application/json" },
}); });
} }