mirror of
https://github.com/melgarafael/DeskcommCRM.git
synced 2026-10-02 01:28:34 +08:00
refactor: remove agent logging from automation and webhook handling
- Eliminated redundant logging fetch calls from various automation functions and webhook routes to streamline code and improve performance. - Added a new trigger kind "case_opened" in TriggerConfigControl for better categorization of follow-up actions. - Cleaned up imports in LeadFieldsForm and KanbanBoard components to remove duplicates and enhance readability.
This commit is contained in:
@@ -290,20 +290,6 @@ export async function POST(req: NextRequest, ctx: RouteCtx): Promise<NextRespons
|
||||
});
|
||||
|
||||
// localhost: sem crontab. Prod não entra aqui (NODE_ENV=production).
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "A",
|
||||
location: "app/api/v1/webhooks/in/[token]/route.ts:before-kick",
|
||||
message: "webhook lead created, kicking local pipeline",
|
||||
data: { nodeEnv: process.env.NODE_ENV ?? null, hasLeadId: Boolean(lead.id) },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
await kickLocalPipeline(admin);
|
||||
|
||||
return respondWithLead(String(lead.id));
|
||||
|
||||
@@ -67,6 +67,7 @@ const KIND_LABEL: Record<TriggerKind, string> = {
|
||||
manual: "Manual",
|
||||
silence: "Silêncio",
|
||||
stage_change: "Etapa do funil",
|
||||
case_opened: "Pedido de ajuda",
|
||||
webhook: "Automação (Webhooks)",
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { midpoint } from "@/lib/kanban/fractional-indexing";
|
||||
import type { Lead } from "@/lib/types/leads";
|
||||
import type { Pipeline, Stage } from "@/lib/kanban/types";
|
||||
import { StageColumn } from "./StageColumn";
|
||||
import { LeadDossier } from "./LeadDossier";
|
||||
import { camposDoFunil } from "@/lib/leads/campos-do-funil";
|
||||
|
||||
interface KanbanBoardProps {
|
||||
@@ -253,7 +254,7 @@ export function KanbanBoard({
|
||||
{leadDoDossie && (
|
||||
<LeadDossier
|
||||
open
|
||||
onOpenChange={(v) => !v && setDossieId(null)}
|
||||
onOpenChange={(v: boolean) => !v && setDossieId(null)}
|
||||
lead={leadDoDossie}
|
||||
pipelineId={pipelineId}
|
||||
fieldDefs={camposDoFunil(data.pipeline.settings ?? null)}
|
||||
|
||||
@@ -12,6 +12,8 @@ import type { Lead } from "@/lib/types/leads";
|
||||
import { updateLeadSchema, type UpdateLeadInput } from "@/lib/schemas/leads";
|
||||
import { parseReaisToCents } from "@/lib/money";
|
||||
import { CustomFieldsEditor, type CustomFieldDef } from "@/components/contacts/CustomFieldsEditor";
|
||||
import { EcoDoValor } from "./EcoDoValor";
|
||||
import { EcoDoValor } from "./EcoDoValor";
|
||||
|
||||
interface FormShape {
|
||||
title: string;
|
||||
|
||||
@@ -26,39 +26,11 @@ export async function executeStartMessageFlow(
|
||||
): Promise<ActionResultDetail> {
|
||||
const pointerId = typeof config.flow_pointer_id === "string" ? config.flow_pointer_id : null;
|
||||
if (!pointerId) {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "D",
|
||||
location: "lib/automation/actions/start-message-flow.ts:missing-config",
|
||||
message: "missing flow_pointer_id",
|
||||
data: { configKeys: Object.keys(config) },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
return { type: TYPE, status: "failed", error: "missing_config" };
|
||||
}
|
||||
|
||||
const contactId = contactIdFromCtx(ctx);
|
||||
if (!contactId) {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "D",
|
||||
location: "lib/automation/actions/start-message-flow.ts:no-contact",
|
||||
message: "no contact on context",
|
||||
data: { hasLead: Boolean(ctx.context.lead), hasContact: Boolean(ctx.context.contact) },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
return { type: TYPE, status: "skipped", detail: { reason: "no_contact" } };
|
||||
}
|
||||
|
||||
@@ -71,20 +43,6 @@ export async function executeStartMessageFlow(
|
||||
});
|
||||
|
||||
if (!result.ok) {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "D",
|
||||
location: "lib/automation/actions/start-message-flow.ts:enroll-fail",
|
||||
message: "enrollFollowupFlow failed",
|
||||
data: { code: result.code },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
if (result.code === "conflict") {
|
||||
return {
|
||||
type: TYPE,
|
||||
@@ -99,20 +57,6 @@ export async function executeStartMessageFlow(
|
||||
return { type: TYPE, status: "failed", error: result.message, detail: { code: result.code } };
|
||||
}
|
||||
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "D",
|
||||
location: "lib/automation/actions/start-message-flow.ts:success",
|
||||
message: "enrollment created",
|
||||
data: { enrollmentId: result.enrollment.id },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
return {
|
||||
type: TYPE,
|
||||
status: "success",
|
||||
|
||||
@@ -99,20 +99,7 @@ export async function runAutomationForEvent(
|
||||
|
||||
const expectedKind = EXPECTED_ENTITY_KIND[row.event_type];
|
||||
if (expectedKind && row.entity_kind !== expectedKind) {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "C",
|
||||
location: "lib/automation/engine.ts:kind-mismatch",
|
||||
message: "entity_kind_mismatch",
|
||||
data: { eventType: row.event_type, entityKind: row.entity_kind, expectedKind },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
|
||||
return { consumer_key: AUTOMATION_CONSUMER_KEY, status: "skipped", detail: "entity_kind_mismatch" };
|
||||
}
|
||||
|
||||
@@ -128,47 +115,12 @@ export async function runAutomationForEvent(
|
||||
}
|
||||
const matched = (rules ?? []) as unknown as RuleRow[];
|
||||
if (!matched.length) {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "C",
|
||||
location: "lib/automation/engine.ts:no-rules",
|
||||
message: "no active rules for event",
|
||||
data: { eventType: row.event_type, rulesError: error?.message ?? null },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
return { consumer_key: AUTOMATION_CONSUMER_KEY, status: "ok", detail: "no_rules" };
|
||||
}
|
||||
|
||||
const context = await buildContext(admin, row);
|
||||
const applicable = matched.filter((r) => evaluateConditions(r.conditions ?? [], context));
|
||||
if (!applicable.length) {
|
||||
const lead = context.lead as { title?: unknown; contact_id?: unknown } | undefined;
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "C",
|
||||
location: "lib/automation/engine.ts:no-match",
|
||||
message: "rules exist but conditions failed",
|
||||
data: {
|
||||
eventType: row.event_type,
|
||||
ruleCount: matched.length,
|
||||
conditions: matched.map((r) => r.conditions),
|
||||
leadTitle: typeof lead?.title === "string" ? lead.title : null,
|
||||
hasContactId: Boolean(lead?.contact_id),
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
return { consumer_key: AUTOMATION_CONSUMER_KEY, status: "ok", detail: "no_match" };
|
||||
}
|
||||
|
||||
|
||||
@@ -19,40 +19,12 @@ import {
|
||||
import { logger } from "@/lib/logger";
|
||||
|
||||
export async function kickLocalPipeline(admin: SupabaseClient): Promise<void> {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "A",
|
||||
location: "lib/dev/kick-local-pipeline.ts:entry",
|
||||
message: "kickLocalPipeline entry",
|
||||
data: { nodeEnv: process.env.NODE_ENV ?? null },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
if (process.env.NODE_ENV !== "development") return;
|
||||
|
||||
try {
|
||||
ensureHandlersRegistered();
|
||||
const drain = await drainEventLog(admin);
|
||||
logger.info("[dev.pipeline] event-log-drain", drain);
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "B",
|
||||
location: "lib/dev/kick-local-pipeline.ts:after-drain",
|
||||
message: "drainEventLog result",
|
||||
data: drain,
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
logger.info("[dev.pipeline] event-log-drain", { ...drain });
|
||||
|
||||
const enqueueJob = async (job: FollowupJobRequest): Promise<void> => {
|
||||
const { error } = await admin.from("job_queue").insert({
|
||||
@@ -78,38 +50,9 @@ export async function kickLocalPipeline(admin: SupabaseClient): Promise<void> {
|
||||
if (!tick.claimed) break;
|
||||
}
|
||||
logger.info("[dev.pipeline] followup-tick", { ticks });
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "E",
|
||||
runId: "post-fix",
|
||||
location: "lib/dev/kick-local-pipeline.ts:after-tick",
|
||||
message: "runFollowupTick loop result",
|
||||
data: { ticks },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
} catch (err) {
|
||||
logger.warn("[dev.pipeline] kick falhou (lead já foi criado)", {
|
||||
error: err instanceof Error ? err.message : String(err),
|
||||
});
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "A",
|
||||
location: "lib/dev/kick-local-pipeline.ts:catch",
|
||||
message: "kickLocalPipeline threw",
|
||||
data: { error: err instanceof Error ? err.message : String(err) },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
}
|
||||
}
|
||||
|
||||
+2
-49
@@ -37,23 +37,7 @@ export async function drainEventLog(
|
||||
const summary: DrainSummary = { scanned: 0, done: 0, retried: 0, failed: 0, dead: 0 };
|
||||
|
||||
const handledTypes = [...new Set(getRegisteredHandlers().flatMap((h) => h.events))];
|
||||
if (!handledTypes.length) {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "B",
|
||||
location: "lib/event-log/drain.ts:no-handlers",
|
||||
message: "no registered handlers",
|
||||
data: {},
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
return summary;
|
||||
}
|
||||
if (!handledTypes.length) return summary;
|
||||
|
||||
const nowIso = new Date().toISOString();
|
||||
const { data: rows, error } = await admin
|
||||
@@ -73,41 +57,10 @@ export async function drainEventLog(
|
||||
|
||||
if (error) {
|
||||
logger.error("[event-log.drain] select failed", { error: error.message });
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "B",
|
||||
location: "lib/event-log/drain.ts:select-error",
|
||||
message: "event_log select failed",
|
||||
data: { error: error.message, handledTypes },
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7701/ingest/87ca3154-89cc-4a8f-92e3-eaa13aed4946", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "a1ee90" },
|
||||
body: JSON.stringify({
|
||||
sessionId: "a1ee90",
|
||||
hypothesisId: "B",
|
||||
location: "lib/event-log/drain.ts:selected",
|
||||
message: "pending events selected",
|
||||
data: {
|
||||
handledTypes,
|
||||
rowCount: (rows ?? []).length,
|
||||
types: (rows ?? []).map((r) => (r as { event_type?: string }).event_type),
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
|
||||
for (const raw of rows ?? []) {
|
||||
const row = raw as unknown as EventRow;
|
||||
|
||||
@@ -50,7 +50,7 @@ export function emitNotification(input: EmitNotificationInput): void {
|
||||
const marca = absUrl("/icon");
|
||||
const icon = absUrl(input.icon || marca);
|
||||
const href = input.href ? absUrl(input.href) : "";
|
||||
const opts: NotificationOptions = {
|
||||
const opts: NotificationOptions & { renotify?: boolean } = {
|
||||
body,
|
||||
tag,
|
||||
silent: false,
|
||||
|
||||
Reference in New Issue
Block a user