FRE-4471: Scaffold DarkWatch MVP — monorepo, schema, services, API routes, tests

- 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
This commit is contained in:
Senior Engineer
2026-04-29 09:47:45 -04:00
committed by Michael Freno
parent f8f90502fa
commit 218de3b03b
40 changed files with 5225 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
{
"name": "@shieldai/types",
"version": "0.1.0",
"main": "./dist/index.js",
"types": "./dist/index.js",
"scripts": {
"build": "tsc",
"lint": "eslint src/"
},
"exports": {
".": "./src/index.ts"
}
}

View File

@@ -0,0 +1,84 @@
export const IdentifierType = {
EMAIL: "EMAIL",
PHONE: "PHONE",
SSN: "SSN",
} as const;
export type IdentifierType = (typeof IdentifierType)[keyof typeof IdentifierType];
export const SubscriptionTier = {
BASIC: "BASIC",
PLUS: "PLUS",
PREMIUM: "PREMIUM",
} as const;
export type SubscriptionTier = (typeof SubscriptionTier)[keyof typeof SubscriptionTier];
export const Severity = {
INFO: "INFO",
WARNING: "WARNING",
CRITICAL: "CRITICAL",
} as const;
export type Severity = (typeof Severity)[keyof typeof Severity];
export const AlertChannel = {
EMAIL: "EMAIL",
PUSH: "PUSH",
SMS: "SMS",
} as const;
export type AlertChannel = (typeof AlertChannel)[keyof typeof AlertChannel];
export const AlertStatus = {
PENDING: "PENDING",
SENT: "SENT",
READ: "READ",
} as const;
export type AlertStatus = (typeof AlertStatus)[keyof typeof AlertStatus];
export const ScanJobStatus = {
PENDING: "PENDING",
RUNNING: "RUNNING",
COMPLETED: "COMPLETED",
FAILED: "FAILED",
} as const;
export type ScanJobStatus = (typeof ScanJobStatus)[keyof typeof ScanJobStatus];
export const WatchListStatus = {
ACTIVE: "ACTIVE",
PAUSED: "PAUSED",
} as const;
export type WatchListStatus = (typeof WatchListStatus)[keyof typeof WatchListStatus];
export const DataSource = {
HIBP: "HIBP",
SECURITY_TRAILS: "SECURITY_TRAILS",
CENSYS: "CENSYS",
SHODAN: "SHODAN",
HONEYPOT: "HONEYPOT",
} as const;
export type DataSource = (typeof DataSource)[keyof typeof DataSource];
export interface WatchListItemInput {
identifierType: IdentifierType;
identifierValue: string;
}
export interface ScanTriggerInput {
userId: string;
source?: DataSource;
}
export interface ExposureResult {
dataSource: DataSource;
breachName: string;
exposedAt: Date;
dataType: string[];
severity: Severity;
details: string;
}
export interface AlertInput {
userId: string;
exposureId: string;
severity: Severity;
channel: AlertChannel;
dedupKey: string;
}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*.ts"]
}