Add follow-up status tracking slice

This commit is contained in:
2026-06-05 21:35:55 +02:00
parent 807532a0a4
commit 3f148bcec2
11 changed files with 395 additions and 11 deletions

View File

@@ -0,0 +1,34 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import test from "node:test";
const outreachSource = readFileSync(
join(process.cwd(), "convex", "outreach.ts"),
"utf8",
);
const schemaSource = readFileSync(
join(process.cwd(), "convex", "schema.ts"),
"utf8",
);
test("outreach schema stores follow-up due and do-not-contact recheck dates as optional migration-safe fields", () => {
assert.match(schemaSource, /followUpDueAt:\s*v\.optional\(v\.number\(\)\)/);
assert.match(schemaSource, /parentOutreachId:\s*v\.optional\(v\.id\("outreachRecords"\)\)/);
assert.match(schemaSource, /doNotContactUntil:\s*v\.optional\(v\.number\(\)\)/);
});
test("successful initial sends create one follow-up draft for manual approval", () => {
assert.match(outreachSource, /createFollowUpDraftAfterInitialSend/);
assert.match(outreachSource, /followUpDueAt:\s*sentAt\s*\+\s*FOLLOW_UP_DUE_DELAY_MS/);
assert.match(outreachSource, /approvalStatus:\s*"draft"[\s\S]*sendStatus:\s*"not_sent"/);
assert.match(outreachSource, /parentOutreachId:\s*outreach\._id/);
});
test("manual sales status mutation updates lead suppression states", () => {
assert.match(outreachSource, /export const updateManualSalesStatus = mutation/);
assert.match(outreachSource, /salesStatus:\s*manualSalesStatus/);
assert.match(outreachSource, /reply_received[\s\S]*leadPatch\.contactStatus\s*=\s*"replied"/);
assert.match(outreachSource, /not_interested[\s\S]*outreachPatch\.responseStatus\s*=\s*"no_interest"/);
assert.match(outreachSource, /do_not_pursue[\s\S]*outreachPatch\.doNotContactUntil\s*=\s*now\s*\+\s*DO_NOT_CONTACT_RECHECK_MS/);
});