mirror of
https://github.com/melgarafael/DeskcommCRM.git
synced 2026-10-02 01:28:34 +08:00
refactor(webhooks): enhance lead processing and pipeline handling
- Updated comments in `route.ts` to clarify the lead capture process and its implications in production environments. - Modified `kickLocalPipeline` to ensure immediate processing of events in Vercel's Hobby plan, addressing the lack of a cron job. - Adjusted `enroll.ts` to omit `next_eval_at` during enrollment, allowing the database's default behavior to manage timing. - Enhanced unit tests to reflect changes in enrollment behavior and ensure proper handling of lead processing.
This commit is contained in:
@@ -289,7 +289,8 @@ export async function POST(req: NextRequest, ctx: RouteCtx): Promise<NextRespons
|
||||
metadata: { webhook_source_id: source.id },
|
||||
});
|
||||
|
||||
// localhost: sem crontab. Prod não entra aqui (NODE_ENV=production).
|
||||
// Captação: drena lead.created e inscreve no fluxo neste mesmo request.
|
||||
// Sem isto, em prod (Vercel Hobby sem cron de 1 min) o gatilho fica pending.
|
||||
await kickLocalPipeline(admin);
|
||||
|
||||
return respondWithLead(String(lead.id));
|
||||
|
||||
@@ -23,10 +23,6 @@ import {
|
||||
} from "@/lib/followup/engine";
|
||||
import { logger } from "@/lib/logger";
|
||||
|
||||
function deveAcionarPipelineInline(): boolean {
|
||||
return process.env.NODE_ENV === "development" || process.env.VERCEL === "1";
|
||||
}
|
||||
|
||||
async function tickFollowupAteParar(admin: SupabaseClient): Promise<void> {
|
||||
const enqueueJob = async (job: FollowupJobRequest): Promise<void> => {
|
||||
const { error } = await admin.from("job_queue").insert({
|
||||
@@ -67,6 +63,7 @@ export async function acelerarPipelineDeEventos(admin: SupabaseClient): Promise<
|
||||
}
|
||||
|
||||
export async function kickLocalPipeline(admin: SupabaseClient): Promise<void> {
|
||||
if (!deveAcionarPipelineInline()) return;
|
||||
// Sempre: o webhook de captação em Vercel/Hobby não tem cron de 1 min.
|
||||
// Na VPS o crontab continua; drenar neste request só antecipa o mesmo trabalho.
|
||||
await acelerarPipelineDeEventos(admin);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ function fakeDb(pointer: Row) {
|
||||
insert(obj: Row) {
|
||||
mode = "insert";
|
||||
payload = obj;
|
||||
expect(obj).not.toHaveProperty("next_eval_at");
|
||||
return b;
|
||||
},
|
||||
eq(col: string, val: unknown) {
|
||||
|
||||
@@ -107,7 +107,6 @@ export async function enrollFollowupFlow(
|
||||
);
|
||||
}
|
||||
|
||||
const now = new Date().toISOString();
|
||||
const { data: created, error: insErr } = await supabase
|
||||
.from("followup_enrollments")
|
||||
.insert({
|
||||
@@ -117,7 +116,8 @@ export async function enrollFollowupFlow(
|
||||
contact_id: contactId,
|
||||
current_node_id: triggerNode.id,
|
||||
status: "active",
|
||||
next_eval_at: now,
|
||||
// next_eval_at omite: default now() do banco (migration 0147). new Date()
|
||||
// do processo fica 17–34 ms à frente e o claim `<= now()` pula o tick.
|
||||
agent_id: agentId,
|
||||
})
|
||||
.select(ENROLLMENT_LIST_COLUMNS)
|
||||
|
||||
@@ -58,6 +58,10 @@ const DIR = join(process.cwd(), "lib", "followup");
|
||||
* `agenda` = 'nenhum' → menciona a coluna sem agendar (leitura, tradução).
|
||||
*/
|
||||
const ESCRITORES: Record<string, { agenda: "agora" | "futuro" | "nenhum"; nota: string }> = {
|
||||
"enroll.ts": {
|
||||
agenda: "agora",
|
||||
nota: "o enrollment nasce vencido — o insert omite next_eval_at e o default now() do banco decide (0147).",
|
||||
},
|
||||
"gatilho-etapa.ts": {
|
||||
agenda: "agora",
|
||||
nota: "o enrollment nasce vencido — o insert omite a coluna e o default now() do banco decide (0147).",
|
||||
|
||||
Reference in New Issue
Block a user