- 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
28 lines
763 B
TypeScript
28 lines
763 B
TypeScript
import { FastifyInstance } from "fastify";
|
|
import { MatchingEngine } from "@shieldai/darkwatch";
|
|
|
|
export function exposureRoutes(fastify: FastifyInstance) {
|
|
const engine = new MatchingEngine();
|
|
|
|
fastify.get("/", async (request, reply) => {
|
|
const userId = (request.user as { id: string })?.id;
|
|
|
|
if (!userId) {
|
|
return reply.code(401).send({ error: "User not authenticated" });
|
|
}
|
|
|
|
const exposures = await engine.getExposuresForUser(userId);
|
|
return reply.send(exposures);
|
|
});
|
|
|
|
fastify.get("/:id", async (request, reply) => {
|
|
const exposure = await engine.getExposureById(request.params.id);
|
|
|
|
if (!exposure) {
|
|
return reply.code(404).send({ error: "Exposure not found" });
|
|
}
|
|
|
|
return reply.send(exposure);
|
|
});
|
|
}
|