/** * Address Crowding — "shell-firm hotel" detector. Basic (public) variant. * * Counts how many Czech companies share the same registered address and * maps the count to a threshold-based risk signal. No cross-DB enrichment; * pure function over data already fetched by the caller (server.ts). * * Thresholds: * 1-9 → none (multi-tenant office, normal) * 10-49 → low (coworking / legitimate shared space) * 50-199 → medium (virtual office provider) * 200+ → high (shell-firm hotel) * * Rich variant (+ provider detection + clustering + recommendations) * available in @czagents/ddplus (paid Compliance tier). */ import type { AresSearchHit } from '../clients.js'; export interface AddressCrowdingInput { /** ARES subject record for the queried IČO. Must have `sidlo` populated. */ company: { ico: string; sidlo?: { nazevUlice?: string; nazevObce?: string; psc?: number; }; }; /** All companies found at the same address via reverse ARES search. */ companiesAtAddress: AresSearchHit[]; /** * Total count from ARES (pocetCelkem). May exceed companiesAtAddress.length * when the first page (cap 200) is smaller than the full result set. */ totalCountAtAddress: number; } export type CrowdingRiskSignal = 'none' | 'low' | 'medium' | 'high'; export type CrowdingThreshold = 'normal' | 'crowded' | 'shell-hotel'; export interface AddressCrowdingReport { ico: string; address: { ulice?: string; obec?: string; psc?: number; }; /** Total count of companies registered at this address per ARES. */ companyCountAtAddress: number; /** * Set when ARES returned more results than the page cap (200). * companyCountAtAddress = totalCountAtAddress in that case. */ cappedAt?: number; riskSignal: CrowdingRiskSignal; threshold: CrowdingThreshold; /** Weighted risk score 0-100. */ riskScore: number; /** Up to 10 example IČOs from the result set (random sample if > 10). */ sampleCompanyIcos: string[]; } export declare const RISK_LABELS: Record; export declare function detectAddressCrowding(input: AddressCrowdingInput): AddressCrowdingReport; /** * Returns up to `n` elements from `arr`. When arr.length > n, picks * a deterministic random-looking sample (Fisher-Yates partial shuffle * seeded on arr.length to keep tests stable when using fixed-size arrays). */ export declare function pickSample(arr: string[], n: number): string[]; //# sourceMappingURL=address-crowding.d.ts.map