120 lines
3.7 KiB
TypeScript
120 lines
3.7 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { extractQscoreSignals } from "../src/events/projectors/qscore-projector.js";
|
|
import { buildMatchmakingGatewayEvent } from "../src/services/matchmaking-events.js";
|
|
import type { GrowEventRow } from "../src/db/schema.js";
|
|
|
|
function event(overrides: Partial<GrowEventRow> & { type: string; payload: Record<string, unknown> }): GrowEventRow {
|
|
return {
|
|
id: `event-${overrides.type}`,
|
|
userId: "user_test",
|
|
orgId: null,
|
|
source: "matchmaking-v2",
|
|
type: overrides.type,
|
|
category: "service",
|
|
occurredAt: new Date("2026-07-09T00:00:00.000Z"),
|
|
receivedAt: new Date("2026-07-09T00:00:01.000Z"),
|
|
mission: overrides.mission ?? null,
|
|
subject: overrides.subject ?? null,
|
|
correlation: overrides.correlation ?? null,
|
|
payload: overrides.payload,
|
|
raw: {},
|
|
dedupeKey: null,
|
|
processingStatus: "pending",
|
|
processingError: null,
|
|
processedAt: null,
|
|
};
|
|
}
|
|
|
|
const saved = buildMatchmakingGatewayEvent({
|
|
userId: "user_test",
|
|
action: "mark_saved",
|
|
body: {
|
|
action: "mark_saved",
|
|
params: {
|
|
opportunity_id: "job_123",
|
|
curatorTaskId: "task_123",
|
|
missionId: "curator-sprint",
|
|
missionInstanceId: "sprint_123",
|
|
stageId: "stage_123",
|
|
source: "curator-v1",
|
|
},
|
|
},
|
|
result: { task_id: "a2a_123", status: "completed", messages: [] },
|
|
});
|
|
|
|
assert.equal(saved.type, "matchmaking.match.saved");
|
|
assert.deepEqual(saved.mission, {
|
|
missionId: "curator-sprint",
|
|
instanceId: "sprint_123",
|
|
stageId: "stage_123",
|
|
source: "curator-v1",
|
|
});
|
|
assert.deepEqual(saved.subject, {
|
|
serviceId: "matchmaking",
|
|
kind: "opportunity",
|
|
id: "job_123",
|
|
externalId: "job_123",
|
|
});
|
|
assert.equal(saved.correlation?.taskId, "task_123");
|
|
assert.equal(saved.correlation?.curatorTaskId, "task_123");
|
|
assert.equal(saved.correlation?.opportunityId, "job_123");
|
|
assert.equal(saved.payload.curatorTaskId, "task_123");
|
|
assert.equal(saved.payload.opportunityId, "job_123");
|
|
assert.equal(saved.payload.action, "mark_saved");
|
|
|
|
const generatedSignals = extractQscoreSignals(event({
|
|
type: "matchmaking.matches.generated",
|
|
payload: {
|
|
action: "run_search",
|
|
matchCount: 6,
|
|
scanned: 120,
|
|
result: { status: "completed" },
|
|
},
|
|
}));
|
|
assert.ok(
|
|
generatedSignals.some((signal) => signal.signalId === "market.matches" && signal.score > 0),
|
|
"generated matches should produce a market opportunity signal from match counts",
|
|
);
|
|
|
|
const savedSignals = extractQscoreSignals(event({
|
|
type: "matchmaking.match.saved",
|
|
payload: {
|
|
action: "mark_saved",
|
|
opportunityId: "job_123",
|
|
curatorTaskId: "task_123",
|
|
result: { status: "completed" },
|
|
},
|
|
}));
|
|
assert.ok(
|
|
savedSignals.some((signal) => signal.signalId === "networking.opportunities" && signal.score > 0),
|
|
"saved opportunities should produce an opportunity engagement signal without numeric match score",
|
|
);
|
|
|
|
const reviewed = buildMatchmakingGatewayEvent({
|
|
userId: "user_test",
|
|
action: "record_feedback",
|
|
body: {
|
|
action: "record_feedback",
|
|
params: { opportunity_id: "job_123", curatorTaskId: "task_123" },
|
|
},
|
|
result: { task_id: "a2a_456", status: "completed", messages: [] },
|
|
});
|
|
assert.equal(reviewed.type, "matchmaking.matches.reviewed");
|
|
|
|
const appliedSignals = extractQscoreSignals(event({
|
|
type: "matchmaking.match.applied",
|
|
payload: {
|
|
action: "mark_applied",
|
|
opportunityId: "job_123",
|
|
curatorTaskId: "task_123",
|
|
result: { status: "completed" },
|
|
},
|
|
}));
|
|
assert.ok(
|
|
appliedSignals.some((signal) => signal.signalId === "networking.opportunities" && signal.score >= 80),
|
|
"applied opportunities should produce a stronger opportunity signal without numeric match score",
|
|
);
|
|
|
|
console.log("matchmaking-events tests passed");
|
|
process.exit(0);
|