// engine/domain-detector.ts — Detects spec domains from title + description (SPEC-290)
//
// Analyzes spec text to identify which technical domains apply.
// Detection is keyword-based and returns evidence for each domain found.
const DOMAIN_KEYWORDS = [
    {
        domain: 'payments',
        keywords: [
            'payment',
            'payments',
            'stripe',
            'paypal',
            'billing',
            'invoice',
            'checkout',
            'subscription',
            'transaction',
            'charge',
            'refund',
            'pci',
            'credit card',
            'debit card',
            'wallet',
            'purchase',
        ],
    },
    {
        domain: 'authentication',
        keywords: [
            'authentication',
            'login',
            'logout',
            'sign in',
            'sign up',
            'register',
            'password',
            'credentials',
            'jwt',
            'oauth',
            'saml',
            'sso',
            'mfa',
            '2fa',
            'two factor',
            'magic link',
        ],
    },
    {
        domain: 'authorization',
        keywords: [
            'authorization',
            'permission',
            'role',
            'rbac',
            'abac',
            'access control',
            'acl',
            'privilege',
            'grant',
            'revoke',
            'policy',
            'can i',
        ],
    },
    {
        domain: 'file-upload',
        keywords: [
            'file upload',
            'upload',
            'attachment',
            'file storage',
            'blob',
            's3',
            'gcs',
            'azure blob',
            'media upload',
            'image upload',
            'document upload',
            'multipart',
        ],
    },
    {
        domain: 'email',
        keywords: [
            'email',
            'e-mail',
            'smtp',
            'sendgrid',
            'mailgun',
            'ses',
            'newsletter',
            'transactional email',
            'email template',
            'inbox',
            'mailer',
        ],
    },
    {
        domain: 'notifications',
        keywords: [
            'notification',
            'push notification',
            'fcm',
            'apns',
            'alert',
            'in-app notification',
            'toast',
            'bell icon',
            'notify',
        ],
    },
    {
        domain: 'search',
        keywords: [
            'search',
            'full-text search',
            'elasticsearch',
            'algolia',
            'meilisearch',
            'typesense',
            'solr',
            'query',
            'filter results',
            'autocomplete',
            'typeahead',
        ],
    },
    {
        domain: 'mobile-offline',
        keywords: [
            'offline',
            'offline first',
            'offline mode',
            'sync',
            'synchronization',
            'local database',
            'sqlite',
            'realm',
            'pouchdb',
            'service worker',
            'cache first',
            'background sync',
        ],
    },
    {
        domain: 'realtime',
        keywords: [
            'realtime',
            'real-time',
            'websocket',
            'socket.io',
            'sse',
            'server-sent events',
            'live update',
            'live feed',
            'pub/sub',
            'presence',
            'collaborative',
            'live collaboration',
        ],
    },
    {
        domain: 'background-jobs',
        keywords: [
            'background job',
            'queue',
            'worker',
            'cron',
            'scheduled task',
            'bull',
            'celery',
            'sidekiq',
            'job processor',
            'async job',
            'job runner',
            'task queue',
            'message queue',
        ],
    },
    {
        domain: 'api-public',
        keywords: [
            'public api',
            'rest api',
            'graphql api',
            'api key',
            'third-party integration',
            'webhook',
            'sdk',
            'developer portal',
            'external api',
            'openapi',
        ],
    },
    {
        domain: 'data-export',
        keywords: [
            'export',
            'download',
            'report',
            'csv export',
            'excel export',
            'data export',
            'bulk export',
            'generate report',
            'export data',
        ],
    },
    {
        domain: 'multi-tenant',
        keywords: [
            'multi-tenant',
            'multitenant',
            'tenant',
            'organization',
            'workspace',
            'team isolation',
            'account isolation',
            'saas',
        ],
    },
    {
        domain: 'gdpr',
        keywords: [
            'gdpr',
            'privacy',
            'personal data',
            'pii',
            'data protection',
            'right to erasure',
            'right to be forgotten',
            'consent',
            'dpa',
            'data subject',
            'data processor',
            'ccpa',
            'lgpd',
        ],
    },
];
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * Detect domains from spec title + description text.
 * Returns each detected domain with the matching keywords as evidence.
 */
export function detectDomains(title, description) {
    const combinedText = `${title} ${description}`;
    const lower = combinedText.toLowerCase();
    const domains = [];
    const evidence = {};
    for (const entry of DOMAIN_KEYWORDS) {
        const matched = entry.keywords.filter((kw) => lower.includes(kw.toLowerCase()));
        if (matched.length > 0) {
            domains.push(entry.domain);
            evidence[entry.domain] = matched;
        }
    }
    return { domains, evidence, analyzedText: combinedText };
}
/**
 * Detect a single dominant domain (highest keyword hit count).
 * Returns null if no domain is detected.
 */
export function detectPrimaryDomain(title, description) {
    const result = detectDomains(title, description);
    if (result.domains.length === 0) {
        return null;
    }
    const firstDomain = result.domains[0];
    if (!firstDomain) {
        return null;
    }
    let best = firstDomain;
    let bestCount = result.evidence[best]?.length ?? 0;
    for (const domain of result.domains.slice(1)) {
        const count = result.evidence[domain]?.length ?? 0;
        if (count > bestCount) {
            best = domain;
            bestCount = count;
        }
    }
    return best;
}
//# sourceMappingURL=domain-detector.js.map