@adatechnology/meta-whatsapp-module 0.2.0-rc.14 → 0.2.0-rc.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
2
2
  import { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
3
3
  import * as _adatechnology_meta_whatsapp_contracts from '@adatechnology/meta-whatsapp-contracts';
4
- import { SessionState, SessionMode, ConversationSummary, FlowGraphData, FlowGraphSummary, LiveFlowPosition, WhatsAppSettings, MessageDirection, MessageSender, MessageStatus, RealtimeNotifierInterface, ChannelAdapterInterface, ObjectStorageInterface, FlowActionKind, FlowActionHandler, ConversationSession, MetaWhatsAppHooks, SubjectResolverInterface, CatalogPort } from '@adatechnology/meta-whatsapp-contracts';
4
+ import { SessionState, SessionMode, ConversationSummary, CacheInterface, FlowGraphData, FlowGraphSummary, LiveFlowPosition, WhatsAppSettings, MessageDirection, MessageSender, MessageStatus, RealtimeNotifierInterface, ChannelAdapterInterface, ObjectStorageInterface, FlowActionKind, FlowActionHandler, ConversationSession, MetaWhatsAppHooks, SubjectResolverInterface, CatalogPort } from '@adatechnology/meta-whatsapp-contracts';
5
5
  import { WhatsAppMessageProvider } from '@adatechnology/meta-whatsapp-provider';
6
6
 
7
7
  type MetaWhatsAppDatabase = PgDatabase<PgQueryResultHKT, any, any>;
@@ -1484,6 +1484,29 @@ declare class SessionRepository {
1484
1484
  } | null>;
1485
1485
  }
1486
1486
 
1487
+ declare const DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS = 300;
1488
+ /**
1489
+ * Cache de leitura dos grafos de fluxo, com invalidação na publicação.
1490
+ *
1491
+ * TTL **e** invalidação explícita, e não um dos dois: só TTL deixaria o cliente andando no grafo
1492
+ * antigo até a chave expirar, logo depois de alguém corrigir o fluxo no editor; só invalidação
1493
+ * deixaria cache envenenado para sempre se um `delete` se perdesse (Redis reiniciando, deploy no
1494
+ * meio da escrita).
1495
+ *
1496
+ * Toda operação é tolerante a falha por decisão de projeto: cache é aceleração, não dependência.
1497
+ * Redis fora do ar tem que degradar para leitura no banco — que é exatamente o comportamento de
1498
+ * quem não configura cache nenhum — em vez de derrubar a conversa do cliente.
1499
+ */
1500
+ declare class FlowGraphCache {
1501
+ private readonly provider;
1502
+ private readonly ttlSeconds;
1503
+ constructor(provider: CacheInterface, ttlSeconds?: number);
1504
+ private keyFor;
1505
+ read(companyId: string, flowKey: string): Promise<FlowGraphData | undefined>;
1506
+ write(companyId: string, graph: FlowGraphData): Promise<void>;
1507
+ invalidate(companyId: string, flowKey: string): Promise<void>;
1508
+ }
1509
+
1487
1510
  declare class InvalidFlowGraphError extends Error {
1488
1511
  readonly validationMessage: string;
1489
1512
  constructor(key: string, validationMessage: string);
@@ -1493,7 +1516,8 @@ declare class OptimisticLockError extends Error {
1493
1516
  }
1494
1517
  declare class FlowGraphRepository {
1495
1518
  private readonly db;
1496
- constructor(db: MetaWhatsAppDatabase);
1519
+ private readonly cache?;
1520
+ constructor(db: MetaWhatsAppDatabase, cache?: FlowGraphCache | undefined);
1497
1521
  get(companyId: string, key: string): Promise<FlowGraphData | undefined>;
1498
1522
  list(companyId: string): Promise<FlowGraphSummary[]>;
1499
1523
  private assertValidNodes;
@@ -2145,9 +2169,13 @@ interface MetaWhatsAppModuleConfig {
2145
2169
  }
2146
2170
  interface MetaWhatsAppModuleFeatures {
2147
2171
  flowEngine?: boolean;
2172
+ flowGraphCache?: boolean | {
2173
+ ttlSeconds?: number;
2174
+ };
2148
2175
  }
2149
2176
  interface MetaWhatsAppModuleProviders {
2150
2177
  objectStorage?: ObjectStorageInterface;
2178
+ cache?: CacheInterface;
2151
2179
  realtime?: RealtimeNotifierInterface;
2152
2180
  subjectResolver?: SubjectResolverInterface;
2153
2181
  catalog?: CatalogPort;
@@ -2283,12 +2311,23 @@ declare function redeemSseTicket(store: TicketStoreInterface, ticket: string): P
2283
2311
  whatsappNumber: string;
2284
2312
  } | null>;
2285
2313
 
2314
+ /**
2315
+ * Porta de escrita no transcript, e não a classe `LogMessageUseCase`.
2316
+ *
2317
+ * Exigir a classe amarraria a action a quem já guarda as mensagens nas tabelas do módulo — um host
2318
+ * em migração, com o transcript ainda no schema dele, não conseguiria usar a única action built-in
2319
+ * sem gravar o envio numa tabela que o painel dele não lê. O que a action precisa é só de um lugar
2320
+ * para registrar o que saiu.
2321
+ */
2322
+ type FlowMediaTranscriptLogger = {
2323
+ execute(params: LogMessageParams): Promise<unknown>;
2324
+ };
2286
2325
  type CreateSendMediaActionParams = {
2287
2326
  flowMediaRepository: FlowMediaRepository;
2288
2327
  objectStorage: ObjectStorageInterface & {
2289
2328
  getObject: NonNullable<ObjectStorageInterface['getObject']>;
2290
2329
  };
2291
- logMessage: LogMessageUseCase;
2330
+ logMessage: FlowMediaTranscriptLogger;
2292
2331
  startState: SessionState;
2293
2332
  onError?: (error: unknown, details: {
2294
2333
  flowKey: string;
@@ -2310,4 +2349,4 @@ type CreateSendMediaActionParams = {
2310
2349
  */
2311
2350
  declare function createSendMediaAction(params: CreateSendMediaActionParams): FlowActionHandler;
2312
2351
 
2313
- export { type AttachFlowMediaParams, type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type CreateSendMediaActionParams, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowMediaLocation, FlowMediaRepository, type FlowMediaRow, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type LinkDocumentParams, type ListCompanyDocumentsParams, ListCompanyDocumentsUseCase, type ListConversationDocumentsParams, ListConversationDocumentsUseCase, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, type ListDocumentsParams, type ListDocumentsResult, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, type MessageModerator, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewDocumentRow, type NewFlowGraphRow, type NewFlowMediaRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type PurgeExpiredDocumentsParams, type PurgeExpiredDocumentsResult, PurgeExpiredDocumentsUseCase, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, type UpdateFlowMediaParams, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, createSendMediaAction, documents, extractMediaDescriptor, flowGraphs, flowMedia, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
2352
+ export { type AttachFlowMediaParams, type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type CreateSendMediaActionParams, DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphCache, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowMediaLocation, FlowMediaRepository, type FlowMediaRow, type FlowMediaTranscriptLogger, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type LinkDocumentParams, type ListCompanyDocumentsParams, ListCompanyDocumentsUseCase, type ListConversationDocumentsParams, ListConversationDocumentsUseCase, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, type ListDocumentsParams, type ListDocumentsResult, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, type MessageModerator, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewDocumentRow, type NewFlowGraphRow, type NewFlowMediaRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type PurgeExpiredDocumentsParams, type PurgeExpiredDocumentsResult, PurgeExpiredDocumentsUseCase, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, type UpdateFlowMediaParams, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, createSendMediaAction, documents, extractMediaDescriptor, flowGraphs, flowMedia, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
2
2
  import { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
3
3
  import * as _adatechnology_meta_whatsapp_contracts from '@adatechnology/meta-whatsapp-contracts';
4
- import { SessionState, SessionMode, ConversationSummary, FlowGraphData, FlowGraphSummary, LiveFlowPosition, WhatsAppSettings, MessageDirection, MessageSender, MessageStatus, RealtimeNotifierInterface, ChannelAdapterInterface, ObjectStorageInterface, FlowActionKind, FlowActionHandler, ConversationSession, MetaWhatsAppHooks, SubjectResolverInterface, CatalogPort } from '@adatechnology/meta-whatsapp-contracts';
4
+ import { SessionState, SessionMode, ConversationSummary, CacheInterface, FlowGraphData, FlowGraphSummary, LiveFlowPosition, WhatsAppSettings, MessageDirection, MessageSender, MessageStatus, RealtimeNotifierInterface, ChannelAdapterInterface, ObjectStorageInterface, FlowActionKind, FlowActionHandler, ConversationSession, MetaWhatsAppHooks, SubjectResolverInterface, CatalogPort } from '@adatechnology/meta-whatsapp-contracts';
5
5
  import { WhatsAppMessageProvider } from '@adatechnology/meta-whatsapp-provider';
6
6
 
7
7
  type MetaWhatsAppDatabase = PgDatabase<PgQueryResultHKT, any, any>;
@@ -1484,6 +1484,29 @@ declare class SessionRepository {
1484
1484
  } | null>;
1485
1485
  }
1486
1486
 
1487
+ declare const DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS = 300;
1488
+ /**
1489
+ * Cache de leitura dos grafos de fluxo, com invalidação na publicação.
1490
+ *
1491
+ * TTL **e** invalidação explícita, e não um dos dois: só TTL deixaria o cliente andando no grafo
1492
+ * antigo até a chave expirar, logo depois de alguém corrigir o fluxo no editor; só invalidação
1493
+ * deixaria cache envenenado para sempre se um `delete` se perdesse (Redis reiniciando, deploy no
1494
+ * meio da escrita).
1495
+ *
1496
+ * Toda operação é tolerante a falha por decisão de projeto: cache é aceleração, não dependência.
1497
+ * Redis fora do ar tem que degradar para leitura no banco — que é exatamente o comportamento de
1498
+ * quem não configura cache nenhum — em vez de derrubar a conversa do cliente.
1499
+ */
1500
+ declare class FlowGraphCache {
1501
+ private readonly provider;
1502
+ private readonly ttlSeconds;
1503
+ constructor(provider: CacheInterface, ttlSeconds?: number);
1504
+ private keyFor;
1505
+ read(companyId: string, flowKey: string): Promise<FlowGraphData | undefined>;
1506
+ write(companyId: string, graph: FlowGraphData): Promise<void>;
1507
+ invalidate(companyId: string, flowKey: string): Promise<void>;
1508
+ }
1509
+
1487
1510
  declare class InvalidFlowGraphError extends Error {
1488
1511
  readonly validationMessage: string;
1489
1512
  constructor(key: string, validationMessage: string);
@@ -1493,7 +1516,8 @@ declare class OptimisticLockError extends Error {
1493
1516
  }
1494
1517
  declare class FlowGraphRepository {
1495
1518
  private readonly db;
1496
- constructor(db: MetaWhatsAppDatabase);
1519
+ private readonly cache?;
1520
+ constructor(db: MetaWhatsAppDatabase, cache?: FlowGraphCache | undefined);
1497
1521
  get(companyId: string, key: string): Promise<FlowGraphData | undefined>;
1498
1522
  list(companyId: string): Promise<FlowGraphSummary[]>;
1499
1523
  private assertValidNodes;
@@ -2145,9 +2169,13 @@ interface MetaWhatsAppModuleConfig {
2145
2169
  }
2146
2170
  interface MetaWhatsAppModuleFeatures {
2147
2171
  flowEngine?: boolean;
2172
+ flowGraphCache?: boolean | {
2173
+ ttlSeconds?: number;
2174
+ };
2148
2175
  }
2149
2176
  interface MetaWhatsAppModuleProviders {
2150
2177
  objectStorage?: ObjectStorageInterface;
2178
+ cache?: CacheInterface;
2151
2179
  realtime?: RealtimeNotifierInterface;
2152
2180
  subjectResolver?: SubjectResolverInterface;
2153
2181
  catalog?: CatalogPort;
@@ -2283,12 +2311,23 @@ declare function redeemSseTicket(store: TicketStoreInterface, ticket: string): P
2283
2311
  whatsappNumber: string;
2284
2312
  } | null>;
2285
2313
 
2314
+ /**
2315
+ * Porta de escrita no transcript, e não a classe `LogMessageUseCase`.
2316
+ *
2317
+ * Exigir a classe amarraria a action a quem já guarda as mensagens nas tabelas do módulo — um host
2318
+ * em migração, com o transcript ainda no schema dele, não conseguiria usar a única action built-in
2319
+ * sem gravar o envio numa tabela que o painel dele não lê. O que a action precisa é só de um lugar
2320
+ * para registrar o que saiu.
2321
+ */
2322
+ type FlowMediaTranscriptLogger = {
2323
+ execute(params: LogMessageParams): Promise<unknown>;
2324
+ };
2286
2325
  type CreateSendMediaActionParams = {
2287
2326
  flowMediaRepository: FlowMediaRepository;
2288
2327
  objectStorage: ObjectStorageInterface & {
2289
2328
  getObject: NonNullable<ObjectStorageInterface['getObject']>;
2290
2329
  };
2291
- logMessage: LogMessageUseCase;
2330
+ logMessage: FlowMediaTranscriptLogger;
2292
2331
  startState: SessionState;
2293
2332
  onError?: (error: unknown, details: {
2294
2333
  flowKey: string;
@@ -2310,4 +2349,4 @@ type CreateSendMediaActionParams = {
2310
2349
  */
2311
2350
  declare function createSendMediaAction(params: CreateSendMediaActionParams): FlowActionHandler;
2312
2351
 
2313
- export { type AttachFlowMediaParams, type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type CreateSendMediaActionParams, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowMediaLocation, FlowMediaRepository, type FlowMediaRow, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type LinkDocumentParams, type ListCompanyDocumentsParams, ListCompanyDocumentsUseCase, type ListConversationDocumentsParams, ListConversationDocumentsUseCase, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, type ListDocumentsParams, type ListDocumentsResult, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, type MessageModerator, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewDocumentRow, type NewFlowGraphRow, type NewFlowMediaRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type PurgeExpiredDocumentsParams, type PurgeExpiredDocumentsResult, PurgeExpiredDocumentsUseCase, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, type UpdateFlowMediaParams, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, createSendMediaAction, documents, extractMediaDescriptor, flowGraphs, flowMedia, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
2352
+ export { type AttachFlowMediaParams, type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type CreateSendMediaActionParams, DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphCache, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowMediaLocation, FlowMediaRepository, type FlowMediaRow, type FlowMediaTranscriptLogger, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type LinkDocumentParams, type ListCompanyDocumentsParams, ListCompanyDocumentsUseCase, type ListConversationDocumentsParams, ListConversationDocumentsUseCase, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, type ListDocumentsParams, type ListDocumentsResult, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, type MessageModerator, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewDocumentRow, type NewFlowGraphRow, type NewFlowMediaRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type PurgeExpiredDocumentsParams, type PurgeExpiredDocumentsResult, PurgeExpiredDocumentsUseCase, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, type UpdateFlowMediaParams, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, createSendMediaAction, documents, extractMediaDescriptor, flowGraphs, flowMedia, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
package/dist/index.js CHANGED
@@ -562,12 +562,21 @@ var FlowGraphRepository = class {
562
562
  __name(this, "FlowGraphRepository");
563
563
  }
564
564
  db;
565
- constructor(db) {
565
+ cache;
566
+ // Cache opcional: sem ele o repositório se comporta exatamente como antes, lendo sempre do
567
+ // banco. É o host que decide se quer cachear e com qual provedor (ver CacheInterface).
568
+ constructor(db, cache) {
566
569
  this.db = db;
570
+ this.cache = cache;
567
571
  }
568
572
  async get(companyId, key) {
573
+ const cached = await this.cache?.read(companyId, key);
574
+ if (cached) return cached;
569
575
  const [row] = await this.db.select().from(flowGraphs).where(and3(eq3(flowGraphs.companyId, companyId), eq3(flowGraphs.key, key))).limit(1);
570
- return row ? toContractGraph(row) : void 0;
576
+ if (!row) return void 0;
577
+ const graph = toContractGraph(row);
578
+ await this.cache?.write(companyId, graph);
579
+ return graph;
571
580
  }
572
581
  async list(companyId) {
573
582
  const rows = await this.db.select().from(flowGraphs).where(eq3(flowGraphs.companyId, companyId));
@@ -597,7 +606,9 @@ var FlowGraphRepository = class {
597
606
  showInMenu: graph.showInMenu ?? false,
598
607
  menuOptionLabel: graph.menuOptionLabel
599
608
  }).returning();
600
- return toContractGraph(created);
609
+ const createdGraph = toContractGraph(created);
610
+ await this.cache?.invalidate(companyId, createdGraph.key);
611
+ return createdGraph;
601
612
  }
602
613
  // Lock otimista: a escrita só aplica se `expectedVersion` ainda bater com o que está salvo —
603
614
  // senão, alguém mais salvou entretanto e o editor precisa recarregar (ver comentário no schema).
@@ -611,10 +622,12 @@ var FlowGraphRepository = class {
611
622
  updatedAt: /* @__PURE__ */ new Date()
612
623
  }).where(and3(eq3(flowGraphs.companyId, companyId), eq3(flowGraphs.key, graph.key), eq3(flowGraphs.version, expectedVersion))).returning();
613
624
  if (rows.length === 0) throw new OptimisticLockError(graph.key);
625
+ await this.cache?.invalidate(companyId, graph.key);
614
626
  return toContractGraph(rows[0]);
615
627
  }
616
628
  async delete(companyId, key) {
617
629
  await this.db.delete(flowGraphs).where(and3(eq3(flowGraphs.companyId, companyId), eq3(flowGraphs.key, key)));
630
+ await this.cache?.invalidate(companyId, key);
618
631
  }
619
632
  // T4.2 — GetLiveFlowPositions: agrega sessões ativas por (flowKey, currentNodeId), lendo as
620
633
  // colunas dedicadas gravadas por SessionRepository.setFlowPosition. Agrega no banco (GROUP BY,
@@ -634,6 +647,48 @@ var FlowGraphRepository = class {
634
647
  }
635
648
  };
636
649
 
650
+ // src/repositories/FlowGraphCache.ts
651
+ var KEY_PREFIX = "meta-whatsapp:flow-graph";
652
+ var DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS = 300;
653
+ var FlowGraphCache = class {
654
+ static {
655
+ __name(this, "FlowGraphCache");
656
+ }
657
+ provider;
658
+ ttlSeconds;
659
+ constructor(provider, ttlSeconds = DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS) {
660
+ this.provider = provider;
661
+ this.ttlSeconds = ttlSeconds;
662
+ }
663
+ // companyId na chave, e não só a flowKey: a chave do fluxo é escolhida por quem edita e se
664
+ // repete entre empresas — 'consorcio' existe em todas — então uma chave sem tenant serviria o
665
+ // grafo de uma empresa para a conversa de outra.
666
+ keyFor(companyId, flowKey) {
667
+ return `${KEY_PREFIX}:${companyId}:${flowKey}`;
668
+ }
669
+ async read(companyId, flowKey) {
670
+ try {
671
+ const cached = await this.provider.get(this.keyFor(companyId, flowKey));
672
+ if (!cached) return void 0;
673
+ return JSON.parse(cached);
674
+ } catch {
675
+ return void 0;
676
+ }
677
+ }
678
+ async write(companyId, graph) {
679
+ try {
680
+ await this.provider.set(this.keyFor(companyId, graph.key), JSON.stringify(graph), this.ttlSeconds);
681
+ } catch {
682
+ }
683
+ }
684
+ async invalidate(companyId, flowKey) {
685
+ try {
686
+ await this.provider.delete(this.keyFor(companyId, flowKey));
687
+ } catch {
688
+ }
689
+ }
690
+ };
691
+
637
692
  // src/repositories/SettingsRepository.ts
638
693
  import { eq as eq4 } from "drizzle-orm";
639
694
  function toContractSettings(row) {
@@ -2018,7 +2073,9 @@ function createMetaWhatsAppModule(params) {
2018
2073
  const sessionRepository = new SessionRepository(db);
2019
2074
  const messageRepository = new MessageRepository(db);
2020
2075
  const settingsRepository = new SettingsRepository(db);
2021
- const flowGraphRepository = new FlowGraphRepository(db);
2076
+ const flowGraphCacheFeature = params.features?.flowGraphCache ?? false;
2077
+ const flowGraphCache = flowGraphCacheFeature && providers.cache ? new FlowGraphCache(providers.cache, typeof flowGraphCacheFeature === "object" ? flowGraphCacheFeature.ttlSeconds ?? DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS : DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS) : void 0;
2078
+ const flowGraphRepository = new FlowGraphRepository(db, flowGraphCache);
2022
2079
  const documentRepository = new DocumentRepository(db);
2023
2080
  const flowMediaRepository = new FlowMediaRepository(db);
2024
2081
  const logMessage = new LogMessageUseCase(sessionRepository, messageRepository, providers.realtime, providers.moderator);
@@ -2189,10 +2246,12 @@ async function redeemSseTicket(store, ticket) {
2189
2246
  __name(redeemSseTicket, "redeemSseTicket");
2190
2247
  export {
2191
2248
  CreateFlowGraphUseCase,
2249
+ DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS,
2192
2250
  DeleteConversationUseCase,
2193
2251
  DeleteFlowGraphUseCase,
2194
2252
  DocumentRepository,
2195
2253
  ExportConversationUseCase,
2254
+ FlowGraphCache,
2196
2255
  FlowGraphRepository,
2197
2256
  FlowInterpreter,
2198
2257
  FlowMediaRepository,