Fix answer endpoint to avoid duplicate DB updates
This commit is contained in:
parent
091979390a
commit
1827baaf39
2 changed files with 33 additions and 56 deletions
|
|
@ -157,22 +157,43 @@ const server = Bun.serve<SessionData>({
|
||||||
}
|
}
|
||||||
|
|
||||||
const answer = body.response as AnswerResponse;
|
const answer = body.response as AnswerResponse;
|
||||||
let inputData: string;
|
|
||||||
|
|
||||||
// Handle each response type
|
// Get WebSocket connection
|
||||||
|
const ws = sessionWebSockets.get(prompt.session_id);
|
||||||
|
if (!ws) {
|
||||||
|
return new Response("Session WebSocket not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine response value for DB and broadcast
|
||||||
|
let responseValue: string;
|
||||||
if (answer.type === "option") {
|
if (answer.type === "option") {
|
||||||
inputData = `${answer.value}\n`;
|
responseValue = answer.value;
|
||||||
} else if (answer.type === "text") {
|
} else if (answer.type === "text") {
|
||||||
inputData = `${answer.value}\n`;
|
responseValue = "custom";
|
||||||
} else if (answer.type === "tab_instructions") {
|
} else if (answer.type === "tab_instructions") {
|
||||||
// Execute key sequence for tab instructions with delays:
|
responseValue = `tab:${answer.selected_option}`;
|
||||||
// 1. Navigate to selected_option (up/down arrows)
|
} else {
|
||||||
// 2. Wait 100ms
|
return new Response("Invalid response type", { status: 400 });
|
||||||
// 3. Send Tab key
|
}
|
||||||
// 4. Wait 100ms
|
|
||||||
// 5. Write instruction text
|
|
||||||
// 6. Send Enter key
|
|
||||||
|
|
||||||
|
// Mark as responded in DB (once)
|
||||||
|
respondToPrompt(promptId, responseValue);
|
||||||
|
|
||||||
|
// Broadcast to dashboards (once)
|
||||||
|
broadcastSSE({
|
||||||
|
type: "prompt_response",
|
||||||
|
prompt_id: promptId,
|
||||||
|
response: responseValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle WebSocket input based on type
|
||||||
|
if (answer.type === "option" || answer.type === "text") {
|
||||||
|
// Synchronous send for simple responses
|
||||||
|
const inputData = `${answer.value}\n`;
|
||||||
|
const message: ServerMessage = { type: "input", data: inputData };
|
||||||
|
ws.send(JSON.stringify(message));
|
||||||
|
} else if (answer.type === "tab_instructions") {
|
||||||
|
// Async execution for tab instructions
|
||||||
const promptData = prompt.prompt_json;
|
const promptData = prompt.prompt_json;
|
||||||
if (!promptData || promptData.prompt_type !== "permission") {
|
if (!promptData || promptData.prompt_type !== "permission") {
|
||||||
return new Response(
|
return new Response(
|
||||||
|
|
@ -184,22 +205,6 @@ const server = Bun.serve<SessionData>({
|
||||||
const currentOption = promptData.selected_option;
|
const currentOption = promptData.selected_option;
|
||||||
const targetOption = answer.selected_option;
|
const targetOption = answer.selected_option;
|
||||||
|
|
||||||
// Mark as responded in DB first
|
|
||||||
respondToPrompt(promptId, `tab:${answer.selected_option}`);
|
|
||||||
|
|
||||||
// Broadcast to dashboards
|
|
||||||
broadcastSSE({
|
|
||||||
type: "prompt_response",
|
|
||||||
prompt_id: promptId,
|
|
||||||
response: answer.selected_option === 1 ? "approve" : "reject",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get WebSocket for async execution
|
|
||||||
const ws = sessionWebSockets.get(prompt.session_id);
|
|
||||||
if (!ws) {
|
|
||||||
return new Response("Session WebSocket not found", { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute key sequence asynchronously with delays
|
// Execute key sequence asynchronously with delays
|
||||||
(async () => {
|
(async () => {
|
||||||
const sendInput = (data: string) => {
|
const sendInput = (data: string) => {
|
||||||
|
|
@ -224,36 +229,8 @@ const server = Bun.serve<SessionData>({
|
||||||
})().catch((err) => {
|
})().catch((err) => {
|
||||||
console.error("Error executing tab instruction sequence:", err);
|
console.error("Error executing tab instruction sequence:", err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Return immediately (async execution continues in background)
|
|
||||||
return Response.json({ success: true });
|
|
||||||
} else {
|
|
||||||
return new Response("Invalid response type", { status: 400 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark as responded in DB
|
|
||||||
respondToPrompt(
|
|
||||||
promptId,
|
|
||||||
answer.type === "option" ? answer.value : "custom",
|
|
||||||
);
|
|
||||||
|
|
||||||
// Notify CLI via WebSocket
|
|
||||||
const ws = sessionWebSockets.get(prompt.session_id);
|
|
||||||
if (ws) {
|
|
||||||
const message: ServerMessage = { type: "input", data: inputData };
|
|
||||||
ws.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Broadcast to dashboards
|
|
||||||
broadcastSSE({
|
|
||||||
type: "prompt_response",
|
|
||||||
prompt_id: promptId,
|
|
||||||
response:
|
|
||||||
answer.type === "option" && answer.value === "1"
|
|
||||||
? "approve"
|
|
||||||
: "reject",
|
|
||||||
});
|
|
||||||
|
|
||||||
return Response.json({ success: true });
|
return Response.json({ success: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,5 +118,5 @@ export type SSEEvent =
|
||||||
| {
|
| {
|
||||||
type: "prompt_response";
|
type: "prompt_response";
|
||||||
prompt_id: number;
|
prompt_id: number;
|
||||||
response: "approve" | "reject";
|
response: string;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue