Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
57 lines
2.3 KiB
TypeScript
57 lines
2.3 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const migrationSql = readFileSync(
|
|
join(
|
|
dirname(fileURLToPath(import.meta.url)),
|
|
"../prisma/migrations/20260901120000_messaging_surface/migration.sql",
|
|
),
|
|
"utf8",
|
|
);
|
|
|
|
/** Close-out predicate from the messaging_surface migration. */
|
|
function closeOutPending(
|
|
rows: Array<{ status: string; identityId: string | null; threadId: string | null }>,
|
|
) {
|
|
return rows.map((row) =>
|
|
row.status === "pending" && row.identityId === null && row.threadId === null
|
|
? { ...row, status: "failed" }
|
|
: row,
|
|
);
|
|
}
|
|
|
|
describe("messaging_surface outbound close-out", () => {
|
|
it("fails only pending rows that lack identityId and threadId", () => {
|
|
expect(migrationSql).toMatch(
|
|
/UPDATE "messaging_outbound"\s+SET "status" = 'failed'\s+WHERE "status" = 'pending'\s+AND "identityId" IS NULL\s+AND "threadId" IS NULL/,
|
|
);
|
|
expect(migrationSql).not.toMatch(
|
|
/UPDATE "messaging_outbound" SET "status" = 'failed' WHERE "status" = 'pending';/,
|
|
);
|
|
});
|
|
|
|
it("keeps identity-mapped DMs pending and fails unaddressable group/intro rows", () => {
|
|
const after = closeOutPending([
|
|
{ status: "pending", identityId: "ident-1", threadId: null },
|
|
{ status: "pending", identityId: null, threadId: null },
|
|
{ status: "pending", identityId: null, threadId: "sendblue:group:1" },
|
|
{ status: "sent", identityId: null, threadId: null },
|
|
]);
|
|
expect(after.map((row) => row.status)).toEqual(["pending", "failed", "pending", "sent"]);
|
|
});
|
|
});
|
|
|
|
describe("messaging_surface channel close-out", () => {
|
|
it("retires memberships of the legacy-prefixed channels", () => {
|
|
// The prefixed channels can never receive traffic again; leaving their
|
|
// members active would let a stale row answer the owner's next LEAVE.
|
|
expect(migrationSql).toMatch(
|
|
/UPDATE "messaging_channel_members" m\s+SET "status" = 'left'\s+FROM "messaging_channels" c\s+WHERE m\."channelId" = c\."id"\s+AND c\."threadId" LIKE 'legacy:%'\s+AND m\."status" IN \('invited', 'approved'\)/,
|
|
);
|
|
// Declined and already-left members keep their answer.
|
|
expect(migrationSql).not.toMatch(/UPDATE "messaging_channel_members" SET "status" = 'left';/);
|
|
});
|
|
});
|