/** * Shared persist phase for opportunity creation: enrichOrCreate → create (or create+expire) → optional chat injection. * Used by the opportunity graph persist node and by the manual opportunity service for consistency. */ import type { CreateOpportunityData, IntentScopedOpportunityPersistenceResult, Opportunity, OpportunityDedupConflict, OpportunityNetworkEligibility, OpportunityStatus } from '../../shared/interfaces/database.interface.js'; import type { Embedder } from '../../shared/interfaces/embedder.interface.js'; import type { EnricherDatabase } from './opportunity.enricher.js'; export type PersistOpportunityDatabase = EnricherDatabase & { createOpportunity(data: CreateOpportunityData): Promise; createOpportunityIfNetworkEligible?(data: CreateOpportunityData, eligibility: OpportunityNetworkEligibility): Promise; updateOpportunityStatus(id: string, status: OpportunityStatus): Promise; createOpportunityAndExpireIds?(data: CreateOpportunityData, expireIds: string[]): Promise<{ created: Opportunity; expired: Opportunity[]; }>; createOpportunityAndExpireIdsIfNetworkEligible?(data: CreateOpportunityData, expireIds: string[], eligibility: OpportunityNetworkEligibility): Promise<{ created: Opportunity; expired: Opportunity[]; } | null>; persistIntentScopedOpportunityIfNetworkEligible?(data: CreateOpportunityData, expireIds: string[], eligibility: OpportunityNetworkEligibility & { triggerIntentId: string; }, dedupWindowMs: number): Promise; /** Optional: used to populate expired list in non-atomic path. */ getOpportunity?(id: string): Promise; }; export interface PersistOpportunitiesParams { database: PersistOpportunityDatabase; embedder: Embedder; items: CreateOpportunityData[]; injectChat?: (opportunity: Opportunity) => Promise; /** Require adapter-level membership/assignment locks for discovery-created rows. */ networkEligibility?: OpportunityNetworkEligibility; /** Scope dedup/enrichment and the final atomic re-check to one owned intent. */ intentDedupScope?: { triggerIntentId: string; dedupWindowMs: number; }; } export interface PersistOpportunitiesError { itemIndex: number; error: unknown; } export interface PersistOpportunitiesConflict extends OpportunityDedupConflict { itemIndex: number; finalAtomic: true; } export interface PersistOpportunitiesResult { created: Opportunity[]; expired: Opportunity[]; conflicts: PersistOpportunitiesConflict[]; errors?: PersistOpportunitiesError[]; } /** * Persist one or more opportunities: enrich (merge overlapping), create, expire replaced, optional chat injection. * When the database has createOpportunityAndExpireIds and enrichment produced expireIds, uses it for atomic create+expire. * Returns both created and expired so callers can emit events (e.g. manual service). */ export declare function persistOpportunities(params: PersistOpportunitiesParams): Promise;