feat: add external funnel monitoring and conversion alerts
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 7s
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 7s
This commit is contained in:
@@ -14,6 +14,7 @@ import { logAuditEvent } from "@/lib/audit";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { authHold, capturePayment } from "@/lib/payment";
|
||||
import { sendTrafficAlert } from "@/lib/traffic-alert";
|
||||
import { evaluateExternalFunnelHealth } from "@/lib/traffic-conversion-monitor";
|
||||
import crypto from "crypto";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -182,6 +183,13 @@ export async function POST(request: NextRequest, props: { params: Promise<{ tool
|
||||
},
|
||||
});
|
||||
|
||||
if (isPublicIp) {
|
||||
void evaluateExternalFunnelHealth({
|
||||
surface: "mcp/list_open_tasks",
|
||||
periodMinutes: 10,
|
||||
});
|
||||
}
|
||||
|
||||
void prisma.auditEvent.count({
|
||||
where: {
|
||||
createdAt: {
|
||||
@@ -288,6 +296,11 @@ export async function POST(request: NextRequest, props: { params: Promise<{ tool
|
||||
},
|
||||
});
|
||||
|
||||
void evaluateExternalFunnelHealth({
|
||||
surface: "mcp/claim_task",
|
||||
periodMinutes: 10,
|
||||
});
|
||||
|
||||
// Set Redis TTL key (3600 seconds)
|
||||
await redis.set(`vw:task:${claim.task_id}:executing`, claim.claim_token, "EX", 3600);
|
||||
|
||||
@@ -364,6 +377,11 @@ export async function POST(request: NextRequest, props: { params: Promise<{ tool
|
||||
},
|
||||
});
|
||||
|
||||
void evaluateExternalFunnelHealth({
|
||||
surface: "mcp/submit_solution",
|
||||
periodMinutes: 10,
|
||||
});
|
||||
|
||||
// Async trigger E2B Sandbox evaluation
|
||||
const taskObj = await prisma.task.findUnique({ where: { id: submission.task_id }});
|
||||
if (taskObj && typeof taskObj.acceptance_criteria === "object" && taskObj.acceptance_criteria !== null) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { prisma } from "@/lib/prisma";
|
||||
import { TaskStatus } from "@agent-bounty/contracts";
|
||||
import { sendTrafficAlert } from "@/lib/traffic-alert";
|
||||
import { isIP } from "node:net";
|
||||
import { evaluateExternalFunnelHealth } from "@/lib/traffic-conversion-monitor";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -235,6 +236,13 @@ export async function GET(request: Request) {
|
||||
}
|
||||
}).catch(() => {});
|
||||
|
||||
if (isPublicIp) {
|
||||
void evaluateExternalFunnelHealth({
|
||||
surface: "public-open-tasks",
|
||||
periodMinutes: 10,
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
platform: "VibeWork",
|
||||
version: "v1",
|
||||
|
||||
@@ -162,6 +162,14 @@ export async function GET(request: NextRequest) {
|
||||
return false;
|
||||
};
|
||||
|
||||
const isInternalActor = (params: {
|
||||
actorType: string | null | undefined;
|
||||
actorId: string | null | undefined;
|
||||
}) => {
|
||||
if (params.actorType === "AGENT") return false;
|
||||
return isInternalActorId(params.actorId);
|
||||
};
|
||||
|
||||
const externalActorSummary = externalActorRows
|
||||
.map((row) => ({
|
||||
actorId: row.actorId || "unknown",
|
||||
@@ -246,7 +254,11 @@ export async function GET(request: NextRequest) {
|
||||
});
|
||||
|
||||
const recentExternalEvents = recentEvents.filter((event) =>
|
||||
event.action.startsWith("EXTERNAL_") && !isInternalActorId(event.actorId)
|
||||
event.action.startsWith("EXTERNAL_") &&
|
||||
!isInternalActor({
|
||||
actorType: event.actorType,
|
||||
actorId: event.actorId,
|
||||
})
|
||||
);
|
||||
|
||||
const recentInternalEvents = recentEvents.filter(
|
||||
|
||||
Reference in New Issue
Block a user