@adatechnology/meta-whatsapp-module 0.2.0-rc.11 → 0.2.0-rc.13
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.cjs +527 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +467 -3
- package/dist/index.d.ts +467 -3
- package/dist/index.js +507 -78
- package/dist/index.js.map +1 -1
- package/dist/migrations/0006_conversation_documents.sql +19 -0
- package/dist/migrations/meta/_journal.json +7 -0
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -580,6 +580,222 @@ declare const messages: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
580
580
|
};
|
|
581
581
|
dialect: "pg";
|
|
582
582
|
}>;
|
|
583
|
+
/**
|
|
584
|
+
* Biblioteca de arquivos da conversa.
|
|
585
|
+
*
|
|
586
|
+
* Tabela própria, e não derivada de `messages.payload`: o painel precisa de `source` e `linkedAt`,
|
|
587
|
+
* que não existem no payload; busca por nome de arquivo quer índice, não varredura de jsonb; e
|
|
588
|
+
* `messageId` anulável é o que permite o atendente anexar documento à conversa sem que exista uma
|
|
589
|
+
* mensagem correspondente.
|
|
590
|
+
*
|
|
591
|
+
* `sessionId` em cascata apaga a LINHA junto com a conversa, mas não o binário no storage — quem
|
|
592
|
+
* apaga objeto é passo de aplicação (listar `uploadId` → apagar no storage → apagar a sessão).
|
|
593
|
+
* Confiar só na FK deixaria objeto órfão sendo cobrado para sempre.
|
|
594
|
+
*/
|
|
595
|
+
declare const documents: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
596
|
+
name: "documents";
|
|
597
|
+
schema: "meta_whatsapp";
|
|
598
|
+
columns: {
|
|
599
|
+
id: drizzle_orm_pg_core.PgColumn<{
|
|
600
|
+
name: "id";
|
|
601
|
+
tableName: "documents";
|
|
602
|
+
dataType: "string";
|
|
603
|
+
columnType: "PgUUID";
|
|
604
|
+
data: string;
|
|
605
|
+
driverParam: string;
|
|
606
|
+
notNull: true;
|
|
607
|
+
hasDefault: true;
|
|
608
|
+
isPrimaryKey: true;
|
|
609
|
+
isAutoincrement: false;
|
|
610
|
+
hasRuntimeDefault: false;
|
|
611
|
+
enumValues: undefined;
|
|
612
|
+
baseColumn: never;
|
|
613
|
+
identity: undefined;
|
|
614
|
+
generated: undefined;
|
|
615
|
+
}, {}, {}>;
|
|
616
|
+
companyId: drizzle_orm_pg_core.PgColumn<{
|
|
617
|
+
name: "company_id";
|
|
618
|
+
tableName: "documents";
|
|
619
|
+
dataType: "string";
|
|
620
|
+
columnType: "PgUUID";
|
|
621
|
+
data: string;
|
|
622
|
+
driverParam: string;
|
|
623
|
+
notNull: true;
|
|
624
|
+
hasDefault: false;
|
|
625
|
+
isPrimaryKey: false;
|
|
626
|
+
isAutoincrement: false;
|
|
627
|
+
hasRuntimeDefault: false;
|
|
628
|
+
enumValues: undefined;
|
|
629
|
+
baseColumn: never;
|
|
630
|
+
identity: undefined;
|
|
631
|
+
generated: undefined;
|
|
632
|
+
}, {}, {}>;
|
|
633
|
+
sessionId: drizzle_orm_pg_core.PgColumn<{
|
|
634
|
+
name: "session_id";
|
|
635
|
+
tableName: "documents";
|
|
636
|
+
dataType: "string";
|
|
637
|
+
columnType: "PgUUID";
|
|
638
|
+
data: string;
|
|
639
|
+
driverParam: string;
|
|
640
|
+
notNull: true;
|
|
641
|
+
hasDefault: false;
|
|
642
|
+
isPrimaryKey: false;
|
|
643
|
+
isAutoincrement: false;
|
|
644
|
+
hasRuntimeDefault: false;
|
|
645
|
+
enumValues: undefined;
|
|
646
|
+
baseColumn: never;
|
|
647
|
+
identity: undefined;
|
|
648
|
+
generated: undefined;
|
|
649
|
+
}, {}, {}>;
|
|
650
|
+
messageId: drizzle_orm_pg_core.PgColumn<{
|
|
651
|
+
name: "message_id";
|
|
652
|
+
tableName: "documents";
|
|
653
|
+
dataType: "string";
|
|
654
|
+
columnType: "PgUUID";
|
|
655
|
+
data: string;
|
|
656
|
+
driverParam: string;
|
|
657
|
+
notNull: false;
|
|
658
|
+
hasDefault: false;
|
|
659
|
+
isPrimaryKey: false;
|
|
660
|
+
isAutoincrement: false;
|
|
661
|
+
hasRuntimeDefault: false;
|
|
662
|
+
enumValues: undefined;
|
|
663
|
+
baseColumn: never;
|
|
664
|
+
identity: undefined;
|
|
665
|
+
generated: undefined;
|
|
666
|
+
}, {}, {}>;
|
|
667
|
+
uploadId: drizzle_orm_pg_core.PgColumn<{
|
|
668
|
+
name: "upload_id";
|
|
669
|
+
tableName: "documents";
|
|
670
|
+
dataType: "string";
|
|
671
|
+
columnType: "PgVarchar";
|
|
672
|
+
data: string;
|
|
673
|
+
driverParam: string;
|
|
674
|
+
notNull: true;
|
|
675
|
+
hasDefault: false;
|
|
676
|
+
isPrimaryKey: false;
|
|
677
|
+
isAutoincrement: false;
|
|
678
|
+
hasRuntimeDefault: false;
|
|
679
|
+
enumValues: [string, ...string[]];
|
|
680
|
+
baseColumn: never;
|
|
681
|
+
identity: undefined;
|
|
682
|
+
generated: undefined;
|
|
683
|
+
}, {}, {
|
|
684
|
+
length: 256;
|
|
685
|
+
}>;
|
|
686
|
+
filename: drizzle_orm_pg_core.PgColumn<{
|
|
687
|
+
name: "filename";
|
|
688
|
+
tableName: "documents";
|
|
689
|
+
dataType: "string";
|
|
690
|
+
columnType: "PgVarchar";
|
|
691
|
+
data: string;
|
|
692
|
+
driverParam: string;
|
|
693
|
+
notNull: true;
|
|
694
|
+
hasDefault: false;
|
|
695
|
+
isPrimaryKey: false;
|
|
696
|
+
isAutoincrement: false;
|
|
697
|
+
hasRuntimeDefault: false;
|
|
698
|
+
enumValues: [string, ...string[]];
|
|
699
|
+
baseColumn: never;
|
|
700
|
+
identity: undefined;
|
|
701
|
+
generated: undefined;
|
|
702
|
+
}, {}, {
|
|
703
|
+
length: 512;
|
|
704
|
+
}>;
|
|
705
|
+
mimeType: drizzle_orm_pg_core.PgColumn<{
|
|
706
|
+
name: "mime_type";
|
|
707
|
+
tableName: "documents";
|
|
708
|
+
dataType: "string";
|
|
709
|
+
columnType: "PgVarchar";
|
|
710
|
+
data: string;
|
|
711
|
+
driverParam: string;
|
|
712
|
+
notNull: true;
|
|
713
|
+
hasDefault: false;
|
|
714
|
+
isPrimaryKey: false;
|
|
715
|
+
isAutoincrement: false;
|
|
716
|
+
hasRuntimeDefault: false;
|
|
717
|
+
enumValues: [string, ...string[]];
|
|
718
|
+
baseColumn: never;
|
|
719
|
+
identity: undefined;
|
|
720
|
+
generated: undefined;
|
|
721
|
+
}, {}, {
|
|
722
|
+
length: 128;
|
|
723
|
+
}>;
|
|
724
|
+
sizeBytes: drizzle_orm_pg_core.PgColumn<{
|
|
725
|
+
name: "size_bytes";
|
|
726
|
+
tableName: "documents";
|
|
727
|
+
dataType: "number";
|
|
728
|
+
columnType: "PgInteger";
|
|
729
|
+
data: number;
|
|
730
|
+
driverParam: string | number;
|
|
731
|
+
notNull: true;
|
|
732
|
+
hasDefault: false;
|
|
733
|
+
isPrimaryKey: false;
|
|
734
|
+
isAutoincrement: false;
|
|
735
|
+
hasRuntimeDefault: false;
|
|
736
|
+
enumValues: undefined;
|
|
737
|
+
baseColumn: never;
|
|
738
|
+
identity: undefined;
|
|
739
|
+
generated: undefined;
|
|
740
|
+
}, {}, {}>;
|
|
741
|
+
sha256: drizzle_orm_pg_core.PgColumn<{
|
|
742
|
+
name: "sha256";
|
|
743
|
+
tableName: "documents";
|
|
744
|
+
dataType: "string";
|
|
745
|
+
columnType: "PgVarchar";
|
|
746
|
+
data: string;
|
|
747
|
+
driverParam: string;
|
|
748
|
+
notNull: false;
|
|
749
|
+
hasDefault: false;
|
|
750
|
+
isPrimaryKey: false;
|
|
751
|
+
isAutoincrement: false;
|
|
752
|
+
hasRuntimeDefault: false;
|
|
753
|
+
enumValues: [string, ...string[]];
|
|
754
|
+
baseColumn: never;
|
|
755
|
+
identity: undefined;
|
|
756
|
+
generated: undefined;
|
|
757
|
+
}, {}, {
|
|
758
|
+
length: 64;
|
|
759
|
+
}>;
|
|
760
|
+
source: drizzle_orm_pg_core.PgColumn<{
|
|
761
|
+
name: "source";
|
|
762
|
+
tableName: "documents";
|
|
763
|
+
dataType: "string";
|
|
764
|
+
columnType: "PgVarchar";
|
|
765
|
+
data: string;
|
|
766
|
+
driverParam: string;
|
|
767
|
+
notNull: true;
|
|
768
|
+
hasDefault: false;
|
|
769
|
+
isPrimaryKey: false;
|
|
770
|
+
isAutoincrement: false;
|
|
771
|
+
hasRuntimeDefault: false;
|
|
772
|
+
enumValues: [string, ...string[]];
|
|
773
|
+
baseColumn: never;
|
|
774
|
+
identity: undefined;
|
|
775
|
+
generated: undefined;
|
|
776
|
+
}, {}, {
|
|
777
|
+
length: 12;
|
|
778
|
+
}>;
|
|
779
|
+
linkedAt: drizzle_orm_pg_core.PgColumn<{
|
|
780
|
+
name: "linked_at";
|
|
781
|
+
tableName: "documents";
|
|
782
|
+
dataType: "date";
|
|
783
|
+
columnType: "PgTimestamp";
|
|
784
|
+
data: Date;
|
|
785
|
+
driverParam: string;
|
|
786
|
+
notNull: true;
|
|
787
|
+
hasDefault: true;
|
|
788
|
+
isPrimaryKey: false;
|
|
789
|
+
isAutoincrement: false;
|
|
790
|
+
hasRuntimeDefault: false;
|
|
791
|
+
enumValues: undefined;
|
|
792
|
+
baseColumn: never;
|
|
793
|
+
identity: undefined;
|
|
794
|
+
generated: undefined;
|
|
795
|
+
}, {}, {}>;
|
|
796
|
+
};
|
|
797
|
+
dialect: "pg";
|
|
798
|
+
}>;
|
|
583
799
|
declare const flowGraphs: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
584
800
|
name: "flow_graphs";
|
|
585
801
|
schema: "meta_whatsapp";
|
|
@@ -941,6 +1157,8 @@ type MessageRow = typeof messages.$inferSelect;
|
|
|
941
1157
|
type NewMessageRow = typeof messages.$inferInsert;
|
|
942
1158
|
type FlowGraphRow = typeof flowGraphs.$inferSelect;
|
|
943
1159
|
type NewFlowGraphRow = typeof flowGraphs.$inferInsert;
|
|
1160
|
+
type DocumentRow = typeof documents.$inferSelect;
|
|
1161
|
+
type NewDocumentRow = typeof documents.$inferInsert;
|
|
944
1162
|
|
|
945
1163
|
interface ListConversationsFilters {
|
|
946
1164
|
page?: number;
|
|
@@ -962,6 +1180,14 @@ declare class SessionRepository {
|
|
|
962
1180
|
setMode(companyId: string, whatsappNumber: string, mode: SessionMode, assignedUserId?: string | null): Promise<void>;
|
|
963
1181
|
takeover(companyId: string, whatsappNumber: string, agentUserId: string): Promise<void>;
|
|
964
1182
|
release(companyId: string, whatsappNumber: string): Promise<void>;
|
|
1183
|
+
/**
|
|
1184
|
+
* Apaga a sessão; a cascata das FKs leva mensagens e documentos.
|
|
1185
|
+
*
|
|
1186
|
+
* Não apaga o binário no storage — isso é passo de aplicação, e é por isso que este método é
|
|
1187
|
+
* chamado por `DeleteConversationUseCase` e não diretamente pelo host. Chamar daqui sem apagar os
|
|
1188
|
+
* objetos antes deixa mídia órfã sendo cobrada para sempre.
|
|
1189
|
+
*/
|
|
1190
|
+
deleteByNumber(companyId: string, whatsappNumber: string): Promise<void>;
|
|
965
1191
|
requestHuman(companyId: string, whatsappNumber: string): Promise<void>;
|
|
966
1192
|
markRead(companyId: string, whatsappNumber: string): Promise<void>;
|
|
967
1193
|
markAllRead(companyId: string, userId: string): Promise<number>;
|
|
@@ -1091,6 +1317,100 @@ declare class LogMessageUseCase {
|
|
|
1091
1317
|
private moderationOf;
|
|
1092
1318
|
}
|
|
1093
1319
|
|
|
1320
|
+
interface LinkDocumentParams {
|
|
1321
|
+
companyId: string;
|
|
1322
|
+
sessionId: string;
|
|
1323
|
+
messageId?: string | null;
|
|
1324
|
+
uploadId: string;
|
|
1325
|
+
filename: string;
|
|
1326
|
+
mimeType: string;
|
|
1327
|
+
sizeBytes: number;
|
|
1328
|
+
sha256?: string | null;
|
|
1329
|
+
source: string;
|
|
1330
|
+
}
|
|
1331
|
+
interface ListDocumentsParams {
|
|
1332
|
+
companyId: string;
|
|
1333
|
+
sessionId: string;
|
|
1334
|
+
search?: string;
|
|
1335
|
+
/**
|
|
1336
|
+
* Origens aceitas, como lista explícita (`['agent', 'bot']`) e não como apelido de UI.
|
|
1337
|
+
*
|
|
1338
|
+
* Agrupamento tipo "Equipe" é vocabulário de tela e muda por produto; traduzir aqui obrigaria o
|
|
1339
|
+
* módulo a conhecer o rótulo de cada host. Quem recebe o apelido na borda é a rota.
|
|
1340
|
+
*/
|
|
1341
|
+
sources?: readonly string[];
|
|
1342
|
+
sortDirection?: 'asc' | 'desc';
|
|
1343
|
+
page?: number;
|
|
1344
|
+
limit?: number;
|
|
1345
|
+
}
|
|
1346
|
+
interface ListCompanyDocumentsParams$1 {
|
|
1347
|
+
companyId: string;
|
|
1348
|
+
search?: string;
|
|
1349
|
+
sources?: readonly string[];
|
|
1350
|
+
sortDirection?: 'asc' | 'desc';
|
|
1351
|
+
page?: number;
|
|
1352
|
+
limit?: number;
|
|
1353
|
+
}
|
|
1354
|
+
interface CompanyDocumentRow {
|
|
1355
|
+
id: string;
|
|
1356
|
+
uploadId: string;
|
|
1357
|
+
filename: string;
|
|
1358
|
+
mimeType: string;
|
|
1359
|
+
sizeBytes: number;
|
|
1360
|
+
source: string;
|
|
1361
|
+
linkedAt: Date;
|
|
1362
|
+
whatsappNumber: string;
|
|
1363
|
+
}
|
|
1364
|
+
interface ListCompanyDocumentsResult {
|
|
1365
|
+
rows: CompanyDocumentRow[];
|
|
1366
|
+
total: number;
|
|
1367
|
+
}
|
|
1368
|
+
interface ListDocumentsResult {
|
|
1369
|
+
rows: DocumentRow[];
|
|
1370
|
+
/** Total no servidor, ANTES do corte de página — é o que permite calcular a última página. */
|
|
1371
|
+
total: number;
|
|
1372
|
+
}
|
|
1373
|
+
declare class DocumentRepository {
|
|
1374
|
+
private readonly db;
|
|
1375
|
+
constructor(db: MetaWhatsAppDatabase);
|
|
1376
|
+
/**
|
|
1377
|
+
* Idempotente por (companyId, uploadId), garantido pelo índice único e não por SELECT prévio: o
|
|
1378
|
+
* job de ingestão é reentregue por retry e duas tentativas concorrentes passariam as duas por uma
|
|
1379
|
+
* checagem, duplicando a linha no painel.
|
|
1380
|
+
*
|
|
1381
|
+
* Devolve `undefined` quando o documento já estava linkado.
|
|
1382
|
+
*/
|
|
1383
|
+
link(params: LinkDocumentParams): Promise<DocumentRow | undefined>;
|
|
1384
|
+
listByConversation(params: ListDocumentsParams): Promise<ListDocumentsResult>;
|
|
1385
|
+
/**
|
|
1386
|
+
* A biblioteca da EMPRESA inteira, não de uma conversa.
|
|
1387
|
+
*
|
|
1388
|
+
* A busca casa nome do arquivo OU telefone da conversa — ver `companyDocumentSearch`.
|
|
1389
|
+
*
|
|
1390
|
+
* Faz join com `sessions` para carregar de qual conversa cada arquivo veio — numa lista global,
|
|
1391
|
+
* arquivo sem essa referência é inútil: o atendente vê "comprovante.pdf" e não sabe de quem.
|
|
1392
|
+
*
|
|
1393
|
+
* Ordena por `linkedAt` apoiada no índice `idx_documents_company_linked`, que já existia para a
|
|
1394
|
+
* varredura de retenção.
|
|
1395
|
+
*/
|
|
1396
|
+
listByCompany(params: ListCompanyDocumentsParams$1): Promise<ListCompanyDocumentsResult>;
|
|
1397
|
+
/**
|
|
1398
|
+
* Um documento pela key do objeto. Serve para recuperar o nome original na hora de assinar o
|
|
1399
|
+
* download: a key é caminho no bucket e salvaria o arquivo com o id da Meta.
|
|
1400
|
+
*/
|
|
1401
|
+
findByUploadId(companyId: string, uploadId: string): Promise<DocumentRow | undefined>;
|
|
1402
|
+
/**
|
|
1403
|
+
* Os objetos a apagar no storage antes de a linha sumir.
|
|
1404
|
+
*
|
|
1405
|
+
* Existe porque a cascata da FK apaga a linha e deixa o binário órfão: quem for apagar a conversa
|
|
1406
|
+
* precisa desta lista primeiro, senão paga armazenamento para sempre por arquivo inalcançável.
|
|
1407
|
+
*/
|
|
1408
|
+
listUploadIdsBySession(companyId: string, sessionId: string): Promise<string[]>;
|
|
1409
|
+
/** Varredura de retenção por idade — o par é o mesmo cuidado com o objeto no storage. */
|
|
1410
|
+
listExpired(companyId: string, olderThan: Date, limit?: number): Promise<DocumentRow[]>;
|
|
1411
|
+
deleteById(companyId: string, id: string): Promise<void>;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1094
1414
|
type SendTextParams = {
|
|
1095
1415
|
companyId: string;
|
|
1096
1416
|
whatsappNumber: string;
|
|
@@ -1125,7 +1445,8 @@ declare class SendMessageUseCase {
|
|
|
1125
1445
|
private readonly sessionRepository;
|
|
1126
1446
|
private readonly logMessage;
|
|
1127
1447
|
private readonly objectStorage?;
|
|
1128
|
-
|
|
1448
|
+
private readonly documentRepository?;
|
|
1449
|
+
constructor(channel: ChannelAdapterInterface, sessionRepository: SessionRepository, logMessage: LogMessageUseCase, objectStorage?: ObjectStorageInterface | undefined, documentRepository?: DocumentRepository | undefined);
|
|
1129
1450
|
private assertWithinWindow;
|
|
1130
1451
|
sendText(params: SendTextParams): Promise<MessageRow | undefined>;
|
|
1131
1452
|
sendMedia(params: SendMediaParams): Promise<MessageRow | undefined>;
|
|
@@ -1178,6 +1499,143 @@ declare class ListMessagesUseCase {
|
|
|
1178
1499
|
execute(params: ListMessagesParams): Promise<MessageRow[]>;
|
|
1179
1500
|
}
|
|
1180
1501
|
|
|
1502
|
+
type ListConversationDocumentsParams = {
|
|
1503
|
+
companyId: string;
|
|
1504
|
+
whatsappNumber: string;
|
|
1505
|
+
search?: string;
|
|
1506
|
+
/** Origens explícitas. O apelido de UI ("Equipe") é traduzido na borda HTTP, não aqui. */
|
|
1507
|
+
sources?: readonly string[];
|
|
1508
|
+
sortDirection?: 'asc' | 'desc';
|
|
1509
|
+
page?: number;
|
|
1510
|
+
limit?: number;
|
|
1511
|
+
};
|
|
1512
|
+
/**
|
|
1513
|
+
* O que o `ConversationDocumentsPanel` do conversations-ui consome. O shape é o do pacote de UI
|
|
1514
|
+
* (`ConversationDocument`), com `linkedAt` já em ISO para não obrigar cada host a serializar.
|
|
1515
|
+
*/
|
|
1516
|
+
type ConversationDocumentView = {
|
|
1517
|
+
/**
|
|
1518
|
+
* O `uploadId` (key no storage), e NÃO o id da linha.
|
|
1519
|
+
*
|
|
1520
|
+
* É este valor que o consumidor devolve para pedir a URL assinada ou montar o zip, então expor o
|
|
1521
|
+
* UUID da tabela aqui fazia o download apontar para um objeto inexistente — falha que só aparece
|
|
1522
|
+
* no clique, porque a assinatura é gerada sem consultar o bucket.
|
|
1523
|
+
*/
|
|
1524
|
+
id: string;
|
|
1525
|
+
filename: string;
|
|
1526
|
+
mimeType: string;
|
|
1527
|
+
sizeBytes: number;
|
|
1528
|
+
source: string;
|
|
1529
|
+
linkedAt: string;
|
|
1530
|
+
};
|
|
1531
|
+
/** Espelha o `ConversationDocumentPage` do conversations-ui: lista da página + total no servidor. */
|
|
1532
|
+
type ConversationDocumentsPage = {
|
|
1533
|
+
documents: ConversationDocumentView[];
|
|
1534
|
+
total: number;
|
|
1535
|
+
};
|
|
1536
|
+
declare class ListConversationDocumentsUseCase {
|
|
1537
|
+
private readonly sessionRepository;
|
|
1538
|
+
private readonly documentRepository;
|
|
1539
|
+
constructor(sessionRepository: SessionRepository, documentRepository: DocumentRepository);
|
|
1540
|
+
execute(params: ListConversationDocumentsParams): Promise<ConversationDocumentsPage>;
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
type ListCompanyDocumentsParams = {
|
|
1544
|
+
companyId: string;
|
|
1545
|
+
search?: string;
|
|
1546
|
+
/** Origens explícitas. O apelido de UI ("Equipe") é traduzido na borda HTTP, não aqui. */
|
|
1547
|
+
sources?: readonly string[];
|
|
1548
|
+
sortDirection?: 'asc' | 'desc';
|
|
1549
|
+
page?: number;
|
|
1550
|
+
limit?: number;
|
|
1551
|
+
};
|
|
1552
|
+
/**
|
|
1553
|
+
* Um arquivo na biblioteca da empresa. Igual ao da conversa, mais `conversationId` — sem saber de
|
|
1554
|
+
* quem veio, uma lista global de anexos não responde nenhuma pergunta útil.
|
|
1555
|
+
*/
|
|
1556
|
+
type CompanyDocumentView = {
|
|
1557
|
+
/** O `uploadId` (key no storage), pelo mesmo motivo do `ConversationDocumentView`. */
|
|
1558
|
+
id: string;
|
|
1559
|
+
conversationId: string;
|
|
1560
|
+
filename: string;
|
|
1561
|
+
mimeType: string;
|
|
1562
|
+
sizeBytes: number;
|
|
1563
|
+
source: string;
|
|
1564
|
+
linkedAt: string;
|
|
1565
|
+
};
|
|
1566
|
+
type CompanyDocumentsPage = {
|
|
1567
|
+
documents: CompanyDocumentView[];
|
|
1568
|
+
total: number;
|
|
1569
|
+
};
|
|
1570
|
+
/**
|
|
1571
|
+
* Biblioteca de arquivos de todas as conversas da empresa.
|
|
1572
|
+
*
|
|
1573
|
+
* Existe separada de `ListConversationDocumentsUseCase` porque a pergunta é outra: aquela parte de
|
|
1574
|
+
* uma conversa conhecida, esta varre a empresa e por isso precisa dizer de qual conversa cada
|
|
1575
|
+
* arquivo veio. Reaproveitar a primeira exigiria um `sessionId` opcional que muda o significado do
|
|
1576
|
+
* retorno — dois nomes claros custam menos que um parâmetro que dobra o comportamento.
|
|
1577
|
+
*/
|
|
1578
|
+
declare class ListCompanyDocumentsUseCase {
|
|
1579
|
+
private readonly documentRepository;
|
|
1580
|
+
constructor(documentRepository: DocumentRepository);
|
|
1581
|
+
execute(params: ListCompanyDocumentsParams): Promise<CompanyDocumentsPage>;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
type DeleteConversationParams = {
|
|
1585
|
+
companyId: string;
|
|
1586
|
+
whatsappNumber: string;
|
|
1587
|
+
};
|
|
1588
|
+
type DeleteConversationResult = {
|
|
1589
|
+
/** Objetos efetivamente apagados no storage. */
|
|
1590
|
+
deletedObjects: number;
|
|
1591
|
+
/** Objetos que o storage recusou. A conversa NÃO é apagada quando isto é maior que zero. */
|
|
1592
|
+
failedObjects: readonly string[];
|
|
1593
|
+
};
|
|
1594
|
+
/**
|
|
1595
|
+
* Apaga a conversa e a mídia dela.
|
|
1596
|
+
*
|
|
1597
|
+
* A ordem é o ponto: **storage primeiro, banco depois**. A FK de `documents.session_id` é
|
|
1598
|
+
* `on delete cascade`, então apagar a sessão primeiro derrubaria as linhas e levaria embora a única
|
|
1599
|
+
* lista de `uploadId` existente — os binários ficariam órfãos, cobrados para sempre e inalcançáveis.
|
|
1600
|
+
*
|
|
1601
|
+
* Se algum objeto falhar, a conversa é preservada e o chamador recebe a lista. Apagar as linhas
|
|
1602
|
+
* "mesmo assim" transformaria uma falha visível e reexecutável em lixo silencioso no storage.
|
|
1603
|
+
*/
|
|
1604
|
+
declare class DeleteConversationUseCase {
|
|
1605
|
+
private readonly sessionRepository;
|
|
1606
|
+
private readonly documentRepository;
|
|
1607
|
+
private readonly objectStorage?;
|
|
1608
|
+
constructor(sessionRepository: SessionRepository, documentRepository: DocumentRepository, objectStorage?: ObjectStorageInterface | undefined);
|
|
1609
|
+
execute(params: DeleteConversationParams): Promise<DeleteConversationResult>;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
type PurgeExpiredDocumentsParams = {
|
|
1613
|
+
companyId: string;
|
|
1614
|
+
/** Dias de retenção. O produto configura; o módulo não escolhe política de dado pessoal. */
|
|
1615
|
+
retentionDays: number;
|
|
1616
|
+
/** Teto por execução, para o job não segurar conexão nem storage por tempo indefinido. */
|
|
1617
|
+
batchSize?: number;
|
|
1618
|
+
/** Instante de referência — injetado para o teste não depender do relógio. */
|
|
1619
|
+
now?: Date;
|
|
1620
|
+
};
|
|
1621
|
+
type PurgeExpiredDocumentsResult = {
|
|
1622
|
+
purged: number;
|
|
1623
|
+
failed: readonly string[];
|
|
1624
|
+
};
|
|
1625
|
+
/**
|
|
1626
|
+
* Apaga documento vencido: objeto no storage primeiro, linha depois — a mesma ordem do
|
|
1627
|
+
* `DeleteConversationUseCase`, e pelo mesmo motivo.
|
|
1628
|
+
*
|
|
1629
|
+
* A linha só cai quando o objeto caiu. Contar como purgado sem ter apagado o binário deixaria lixo
|
|
1630
|
+
* pago no storage sem nenhum registro que o alcance depois: a linha era o único ponteiro.
|
|
1631
|
+
*/
|
|
1632
|
+
declare class PurgeExpiredDocumentsUseCase {
|
|
1633
|
+
private readonly documentRepository;
|
|
1634
|
+
private readonly objectStorage?;
|
|
1635
|
+
constructor(documentRepository: DocumentRepository, objectStorage?: ObjectStorageInterface | undefined);
|
|
1636
|
+
execute(params: PurgeExpiredDocumentsParams): Promise<PurgeExpiredDocumentsResult>;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1181
1639
|
type ExportConversationParams = {
|
|
1182
1640
|
companyId: string;
|
|
1183
1641
|
whatsappNumber: string;
|
|
@@ -1362,7 +1820,8 @@ declare class IngestInboundMediaUseCase {
|
|
|
1362
1820
|
private readonly db;
|
|
1363
1821
|
private readonly channel;
|
|
1364
1822
|
private readonly objectStorage;
|
|
1365
|
-
|
|
1823
|
+
private readonly documentRepository?;
|
|
1824
|
+
constructor(db: MetaWhatsAppDatabase, channel: ChannelAdapterInterface, objectStorage: ObjectStorageInterface, documentRepository?: DocumentRepository | undefined);
|
|
1366
1825
|
execute(params: IngestInboundMediaParams): Promise<IngestInboundMediaResult>;
|
|
1367
1826
|
}
|
|
1368
1827
|
declare function extractMediaDescriptor(message: MessageRow): {
|
|
@@ -1409,8 +1868,13 @@ declare function createMetaWhatsAppModule(params: CreateMetaWhatsAppModuleParams
|
|
|
1409
1868
|
release: ReleaseConversationUseCase;
|
|
1410
1869
|
list: ListConversationsUseCase;
|
|
1411
1870
|
listMessages: ListMessagesUseCase;
|
|
1871
|
+
listDocuments: ListConversationDocumentsUseCase;
|
|
1872
|
+
listCompanyDocuments: ListCompanyDocumentsUseCase;
|
|
1873
|
+
delete: DeleteConversationUseCase;
|
|
1874
|
+
purgeExpiredDocuments: PurgeExpiredDocumentsUseCase;
|
|
1412
1875
|
export: ExportConversationUseCase;
|
|
1413
1876
|
repository: SessionRepository;
|
|
1877
|
+
documentRepository: DocumentRepository;
|
|
1414
1878
|
};
|
|
1415
1879
|
settings: SettingsRepository;
|
|
1416
1880
|
webhook: {
|
|
@@ -1514,4 +1978,4 @@ declare function redeemSseTicket(store: TicketStoreInterface, ticket: string): P
|
|
|
1514
1978
|
whatsappNumber: string;
|
|
1515
1979
|
} | null>;
|
|
1516
1980
|
|
|
1517
|
-
export { type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, DeleteFlowGraphUseCase, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, 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 NewFlowGraphRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, 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, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, extractMediaDescriptor, flowGraphs, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
|
|
1981
|
+
export { type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, 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 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, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, documents, extractMediaDescriptor, flowGraphs, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
|