@lanitamarihuanera/suspicious-companies
v1.1.0
Published
NestJS library for tracking suspicious companies with red flags, threat scoring, and fraud detection
Maintainers
Readme
@neko-arc/suspicious-companies
NestJS library for tracking suspicious companies with red flags, threat scoring, and fraud detection
Features
- 🚩 Red Flag Tracking - 15+ categories of suspicious activities
- 📊 Automatic Threat Scoring - 0-100 scale with algorithmic calculation
- ⚖️ Risk Classification - LOW/MEDIUM/HIGH/CRITICAL levels
- 🔍 Evidence Management - Track sources, documents, and testimony
- 📝 Investigation Workflow - INITIAL → ACTIVE → VERIFIED → RESOLVED
- 💾 MongoDB Integration - Persistent storage with full TypeScript support
- 🎯 Worker Protection - Identify fake job postings and employment scams
- 🇨🇱 Labor Law Support - Chilean labor law integration ready
Installation
npm install @neko-arc/suspicious-companiesPeer Dependencies
npm install @nestjs/common@^10.0.0 @nestjs/core@^10.0.0 mongodb@^6.0.0Quick Start
1. Import the Module
import { Module } from '@nestjs/common';
import { SuspiciousCompanyModule } from '@neko-arc/suspicious-companies';
@Module({
imports: [
SuspiciousCompanyModule.forRoot({
mongodbUri: process.env.MONGODB_URI,
database: 'hannibal-forensic-archives', // optional
collection: 'suspicious-companies', // optional
}),
],
})
export class AppModule {}2. Inject the Service
import { Injectable } from '@nestjs/common';
import {
SuspiciousCompanyService,
CreateSuspiciousCompanyDto,
RedFlagCategory,
RedFlagSeverity,
} from '@neko-arc/suspicious-companies';
@Injectable()
export class FraudDetectionService {
constructor(
private readonly suspiciousCompanyService: SuspiciousCompanyService,
) {}
async investigateCompany(name: string) {
const company = await this.suspiciousCompanyService.create({
legalName: name,
country: 'Chile',
industry: 'Tourism',
companyType: 'SPA',
investigatedBy: ['Neko-Arc', 'Hannibal'],
redFlags: [
{
category: RedFlagCategory.NO_DIGITAL_PRESENCE,
severity: RedFlagSeverity.CRITICAL,
title: 'No online presence',
description: 'Company has zero digital footprint in 2025',
discoveredBy: 'Neko-Arc',
},
],
digitalFootprint: {
hasWebsite: false,
hasSocialMedia: false,
hasReviews: false,
searchResultCount: 0,
},
});
console.log(`Threat Score: ${company.overallThreatScore}/100`);
console.log(`Risk Level: ${company.riskLevel}`);
return company;
}
}API Reference
SuspiciousCompanyService
create(dto: CreateSuspiciousCompanyDto): Promise
Create a new suspicious company record with automatic threat scoring.
const company = await service.create({
legalName: 'ACME Corporation SPA',
country: 'Chile',
industry: 'Technology',
companyType: 'SPA',
investigatedBy: ['Investigator 1'],
redFlags: [...],
});findById(companyId: string): Promise<ISuspiciousCompany | null>
Find a company by its unique ID.
const company = await service.findById('company-1731276000000');findByName(legalName: string): Promise<ISuspiciousCompany[]>
Search companies by legal name (case-insensitive partial match).
const companies = await service.findByName('ACME');findByRiskLevel(riskLevel: RiskLevel): Promise<ISuspiciousCompany[]>
Find all companies with a specific risk level.
import { RiskLevel } from '@neko-arc/suspicious-companies';
const critical = await service.findByRiskLevel(RiskLevel.CRITICAL);update(companyId: string, dto: UpdateSuspiciousCompanyDto): Promise<ISuspiciousCompany | null>
Update a company record. Scores are automatically recalculated if relevant fields change.
const updated = await service.update('company-1731276000000', {
rut: '12.345.678-9',
legalStatus: {
registrationVerified: true,
},
});getStatistics(): Promise
Get database statistics including total count and risk level breakdown.
const stats = await service.getStatistics();
// { total: 100, byRiskLevel: { critical: 10, high: 20, medium: 30, low: 40 } }ThreatScoringService
calculateThreatScore(company: ISuspiciousCompany): number
Calculate threat score (0-100) based on red flags and company attributes.
getRiskLevel(score: number): RiskLevel
Determine risk level classification from threat score.
updateScores(company: ISuspiciousCompany): ISuspiciousCompany
Update company with calculated threat score and risk level.
Red Flag Categories
enum RedFlagCategory {
NO_DIGITAL_PRESENCE = 'NO_DIGITAL_PRESENCE',
FAKE_CREDENTIALS = 'FAKE_CREDENTIALS',
LABOR_VIOLATIONS = 'LABOR_VIOLATIONS',
UNPAID_WAGES = 'UNPAID_WAGES',
FRAUDULENT_ACTIVITY = 'FRAUDULENT_ACTIVITY',
TAX_EVASION = 'TAX_EVASION',
HARASSMENT = 'HARASSMENT',
WRONGFUL_TERMINATION = 'WRONGFUL_TERMINATION',
SHELL_COMPANY = 'SHELL_COMPANY',
DEFUNCT_BUSINESS = 'DEFUNCT_BUSINESS',
SUSPICIOUS_REGISTRATION = 'SUSPICIOUS_REGISTRATION',
NO_PHYSICAL_ADDRESS = 'NO_PHYSICAL_ADDRESS',
UNREACHABLE = 'UNREACHABLE',
FAKE_JOB_POSTINGS = 'FAKE_JOB_POSTINGS',
INVESTMENT_SCAM = 'INVESTMENT_SCAM',
OTHER = 'OTHER',
}Threat Scoring Algorithm
The threat score (0-100) is calculated based on multiple factors:
Red Flag Severity
- CRITICAL: +25 points per flag
- WARNING: +15 points per flag
- INFO: +5 points per flag
Digital Presence Penalties
- No website: +20 points
- No social media: +15 points
- No reviews: +10 points
- Low search results (<5): +15 points
Legal Status Penalties
- Unverified registration: +20 points
- Dormant status: +10 points
- Labor violations: +25 points
- Pending litigation: +15 points
Risk Levels
- 0-25: LOW - Minor concerns
- 26-50: MEDIUM - Suspicious patterns
- 51-75: HIGH - Significant red flags
- 76-100: CRITICAL - Severe threats
TypeScript Support
Full TypeScript support with complete type definitions included:
import {
ISuspiciousCompany,
IRedFlag,
CreateSuspiciousCompanyDto,
RiskLevel,
} from '@neko-arc/suspicious-companies';
const company: ISuspiciousCompany = await service.findById('company-123');Use Cases
1. Worker Protection
Identify fraudulent job postings and protect job seekers:
const company = await service.create({
legalName: 'Fake Recruitment Inc',
country: 'Chile',
industry: 'Recruitment',
companyType: 'LTDA',
investigatedBy: ['HR Security Team'],
redFlags: [
{
category: RedFlagCategory.FAKE_JOB_POSTINGS,
severity: RedFlagSeverity.CRITICAL,
title: 'Fraudulent job ads',
description: 'Company posting fake jobs to collect personal data',
discoveredBy: 'Security Team',
},
],
});2. Investment Due Diligence
Verify companies before investment:
const companies = await service.findByName('Investment Opportunity LLC');
for (const company of companies) {
if (company.riskLevel === RiskLevel.CRITICAL) {
console.warn(`⚠️ HIGH RISK: ${company.legalName}`);
console.warn(`Threat Score: ${company.overallThreatScore}/100`);
console.warn(`Red Flags: ${company.redFlags.length}`);
}
}3. Labor Law Compliance
Track companies with labor violations:
const company = await service.create({
legalName: 'Labor Violator SA',
country: 'Chile',
industry: 'Construction',
companyType: 'SA',
investigatedBy: ['Labor Inspector'],
legalStatus: {
hasLaborViolations: true,
laborViolationDetails: ['Unpaid wages', 'Workplace harassment'],
},
redFlags: [
{
category: RedFlagCategory.UNPAID_WAGES,
severity: RedFlagSeverity.CRITICAL,
title: 'Systematic wage theft',
description: '20 employees unpaid for 3 months',
discoveredBy: 'Labor Inspector',
},
],
});Security
- ✅ No hardcoded credentials - All configuration via environment variables
- ✅ MongoDB connection string - Provided at runtime
- ✅ Private repository - Source code is private
- ✅ Public package - NPM distribution for easy installation
- ✅ Security audited - Pre-publishing security scan
Configuration Options
interface ISuspiciousCompanyModuleOptions {
mongodbUri: string; // Required: MongoDB Atlas connection string
database?: string; // Optional: Database name (default: 'hannibal-forensic-archives')
collection?: string; // Optional: Collection name (default: 'suspicious-companies')
}Environment Variables
# .env file
MONGODB_URI=mongodb+srv://user:[email protected]/?retryWrites=true&w=majority// app.module.ts
SuspiciousCompanyModule.forRoot({
mongodbUri: process.env.MONGODB_URI,
})Examples
Complete Investigation Workflow
// 1. Create initial investigation
const company = await service.create({
legalName: 'Suspicious Company SPA',
country: 'Chile',
industry: 'Tourism',
companyType: 'SPA',
investigatedBy: ['Neko-Arc', 'Hannibal'],
digitalFootprint: {
hasWebsite: false,
searchResultCount: 0,
},
suspiciousPatterns: [
'No digital presence despite being in tourism',
'Formal legal structure without operations',
],
tags: ['ghost-company', 'patagonia', 'tourism-fraud'],
});
// 2. Add verification after registry check
await service.update(company.companyId, {
rut: '12.345.678-9',
legalStatus: {
registrationVerified: true,
isActive: true,
isDormant: false,
},
});
// 3. Add new red flag after discovery
const updated = await service.findById(company.companyId);
updated.redFlags.push({
flagId: `flag-${Date.now()}`,
category: RedFlagCategory.SHELL_COMPANY,
severity: RedFlagSeverity.CRITICAL,
title: 'Active registration without operations',
description: 'Registered and active but no commercial activity',
discoveredDate: new Date(),
discoveredBy: 'Hannibal',
verified: true,
});
await service.update(company.companyId, {
redFlags: updated.redFlags,
investigationStatus: InvestigationStatus.VERIFIED,
});License
MIT
Author
Javier Collipal
Repository
- Source Code: Private (GitHub)
- NPM Package: Public (npmjs.com)
Support
For issues and questions:
- GitHub Issues: https://github.com/JavierCollipal/neko-suspicious-companies/issues
Part of the Neko-Arc Six-Personality System 🐾
Developed with forensic precision by:
- 🐾 Neko-Arc - Technical Coordination
- 🎭 Mario - Procedural Orchestration
- 🗡️ Noel - Precision Analysis
- 🎸 Glam - Worker Advocacy
- 🧠 Hannibal - Forensic Dissection
- 🧠 Tetora - Multi-Perspective Analysis
