- Turborepo monorepo structure (packages: api, db, types, jobs; services: darkwatch) - Prisma schema: User, WatchListItem, Exposure, Alert, ScanJob models - WatchListService: CRUD with normalization, dedup, tier-based limits - HIBPService: API integration with severity scoring - MatchingEngine: exact-match with content hash dedup - AlertPipeline: dedup window, email notifications - ScanService: orchestrates watch list -> HIBP -> match -> alert flow - BullMQ job workers for scan and alert processing - Fastify API routes: watchlist, exposures, alerts, scan - Docker Compose: PostgreSQL 16 + Redis 7 - 15 unit tests passing - Implementation plan document uploaded
21 lines
811 B
TypeScript
21 lines
811 B
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { MatchingEngine } from "../src/matching/MatchingEngine";
|
|
import { DataSource } from "@shieldai/types";
|
|
|
|
describe("MatchingEngine", () => {
|
|
const engine = new MatchingEngine();
|
|
|
|
it("computes consistent content hash", () => {
|
|
const hash1 = engine.computeContentHash(DataSource.HIBP, "TestBreach", "item-123");
|
|
const hash2 = engine.computeContentHash(DataSource.HIBP, "TestBreach", "item-123");
|
|
expect(hash1).toBe(hash2);
|
|
expect(hash1).toHaveLength(64);
|
|
});
|
|
|
|
it("produces different hashes for different inputs", () => {
|
|
const hash1 = engine.computeContentHash(DataSource.HIBP, "BreachA", "item-123");
|
|
const hash2 = engine.computeContentHash(DataSource.HIBP, "BreachB", "item-123");
|
|
expect(hash1).not.toBe(hash2);
|
|
});
|
|
});
|