import { ScopePredicateSource } from "../../../common/repositories/scope-predicate.source"; import { AppLoggingService } from "../../../core/logging/services/logging.service"; import { Neo4jService } from "../../../core/neo4j/services/neo4j.service"; import { CommunityRepository } from "../../../foundations/community/repositories/community.repository"; import { GraphCatalogService } from "../../graph/services/graph.catalog.service"; export declare class CommunityDetectorService { private readonly neo4j; private readonly logger; private readonly communityRepository; private readonly catalog?; private readonly scopePredicates?; private readonly louvainResolutions; private readonly minCommunitySize; constructor(neo4j: Neo4jService, logger: AppLoggingService, communityRepository: CommunityRepository, catalog?: GraphCatalogService, scopePredicates?: ScopePredicateSource); /** * Detect communities for all KeyConcepts belonging to the current company * Creates hierarchical communities at multiple resolution levels */ detectCommunities(): Promise; /** * Count KeyConcepts for the current company */ private countKeyConceptsForCompany; /** * Check if Neo4j GDS is available */ private checkGdsAvailability; /** * Detect communities at a specific resolution level using Louvain algorithm */ private detectCommunitiesAtLevel; /** * Project KeyConcept graph into Neo4j GDS * Uses KeyConceptRelationship weights as relationship weights */ private projectGraph; /** * Every scope-root node the current company owns. * * Root types come from the catalog — an entity whose compiled scope chain is * empty IS a root. Without a catalog (a consumer that never loads the graph * layer) there are no roots, and detection stays company-wide. */ private listScopeRoots; /** * The scope root a single content node sits under — the inverse of * `listScopeRoots`, walking the catalog chain up rather than enumerating * down. `undefined` when the app has no catalog, the label is not * catalogued, or the node has no chain to a root; the caller then falls back * to unpartitioned behaviour, which is correct for content that genuinely * belongs to no root. */ private resolveScopeRootForContent; /** * Run Louvain community detection algorithm */ private runLouvain; /** * Create Community nodes from Louvain results */ private createCommunityNodes; /** * Build PARENT_OF hierarchy between communities at different levels * A parent community at level N+1 contains child communities at level N * if the child's members are a subset of the parent's members */ private buildHierarchy; /** * Drop a projected graph from GDS */ private dropGraph; /** * Mark communities affected by a KeyConcept change as stale */ markAffectedCommunitiesStale(keyConceptId: string): Promise; /** * Incrementally assign KeyConcepts from a content to existing communities * Called after document processing completes */ assignKeyConceptsToCommunities(contentId: string, label: string): Promise; /** * Detect or assign communities based on current state. * - If no communities exist: run full Louvain detection * - If communities exist: incrementally assign orphan KeyConcepts */ detectAndAssignCommunities(contentId: string, label: string): Promise; } //# sourceMappingURL=community.detector.service.d.ts.map