@wrcb/cb-common 1.0.885 → 1.0.887
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/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/services/TenantDataService.d.ts +28 -0
- package/build/services/TenantDataService.js +28 -5
- package/build/types/crm.d.ts +19 -0
- package/build/types/mercadoProfissional.d.ts +152 -0
- package/build/types/mercadoProfissional.js +88 -0
- package/package.json +1 -1
package/build/index.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export * from './types/suggestionStatus';
|
|
|
55
55
|
export * from './types/betOutcome';
|
|
56
56
|
export * from './types/betStatus';
|
|
57
57
|
export * from './types/predictionType';
|
|
58
|
+
export * from './types/mercadoProfissional';
|
|
58
59
|
export * from './types/trabalhoHomeOffice';
|
|
59
60
|
export * from './types/crm';
|
|
60
61
|
export * from './types/trader';
|
package/build/index.js
CHANGED
|
@@ -82,6 +82,7 @@ __exportStar(require("./types/betOutcome"), exports);
|
|
|
82
82
|
__exportStar(require("./types/betStatus"), exports);
|
|
83
83
|
__exportStar(require("./types/predictionType"), exports);
|
|
84
84
|
// trabalho-home-office
|
|
85
|
+
__exportStar(require("./types/mercadoProfissional"), exports);
|
|
85
86
|
__exportStar(require("./types/trabalhoHomeOffice"), exports);
|
|
86
87
|
// crm — núcleo multi-tenant (pipeline configurável + agente de IA)
|
|
87
88
|
__exportStar(require("./types/crm"), exports);
|
|
@@ -69,6 +69,34 @@ export interface TenantData {
|
|
|
69
69
|
BACKEND_API_VERSION: string;
|
|
70
70
|
SITE_NAME: string;
|
|
71
71
|
SITE_URL: string;
|
|
72
|
+
/**
|
|
73
|
+
* Remetente dos e-mails transacionais (só o endereço; o nome exibido vem do
|
|
74
|
+
* SITE_NAME, que já sai correto no cabeçalho).
|
|
75
|
+
*
|
|
76
|
+
* HOJE TODOS OS TENANTS USAM O MESMO `app@wrsolucoesdigitais.com.br`, que é
|
|
77
|
+
* o endereço histórico. O campo existe por tenant não porque haja endereço
|
|
78
|
+
* diferente agora, mas para que passar a ter seja UMA LINHA aqui, sem tocar
|
|
79
|
+
* no cb-notifications.
|
|
80
|
+
*
|
|
81
|
+
* QUANDO VALE SEPARAR: cliente de e-mail agrupa por ENDEREÇO e mostra o
|
|
82
|
+
* nome que tem salvo no catálogo. Quem já recebia e-mail de um produto vê o
|
|
83
|
+
* cadastro de OUTRO chegar com o nome do primeiro — foi o que aconteceu com
|
|
84
|
+
* o Mercado Profissional aparecendo como "Spotly.social" para quem já tinha
|
|
85
|
+
* esse contato salvo. Quem nunca recebeu do outro produto vê o nome certo,
|
|
86
|
+
* então isso só incomoda quem usa mais de um. O outro motivo para separar é
|
|
87
|
+
* reputação de entrega, que hoje é compartilhada por todos os produtos.
|
|
88
|
+
*
|
|
89
|
+
* NÃO PRECISA CRIAR CAIXA POSTAL PARA ENVIAR. O Resend assina com o DKIM do
|
|
90
|
+
* DOMÍNIO, então qualquer parte local de `wrsolucoesdigitais.com.br` sai sem
|
|
91
|
+
* existir em lugar nenhum. O que depende de configuração é RESPOSTA: o MX
|
|
92
|
+
* aponta para o Cloudflare Email Routing, onde um catch-all encaminha
|
|
93
|
+
* qualquer endereço para a caixa de sempre.
|
|
94
|
+
*
|
|
95
|
+
* O DOMÍNIO É UM SÓ: `wrsolucoesdigitais.com.br` é o único verificado no
|
|
96
|
+
* Resend, e ele recusa enviar de domínio não verificado. Quando um produto
|
|
97
|
+
* tiver o domínio próprio verificado, é trocar o valor desta linha.
|
|
98
|
+
*/
|
|
99
|
+
FROM_EMAIL: string;
|
|
72
100
|
SITE_WHATSAPP_SUPPORT: string;
|
|
73
101
|
SITE_WHATSAPP_BOT: string;
|
|
74
102
|
IOS_APP_DOWNLOAD_LINK: string;
|
|
@@ -274,6 +274,7 @@ TenantDataService.tenantDataMap = {
|
|
|
274
274
|
BACKEND_API_VERSION: '1',
|
|
275
275
|
SITE_NAME: 'PoliticaBet',
|
|
276
276
|
SITE_URL: 'https://politicabet.com',
|
|
277
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
277
278
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
278
279
|
SITE_WHATSAPP_BOT: '5511921974030',
|
|
279
280
|
WHATSAPP_BOT_NUMBER_ID: '970274559506875',
|
|
@@ -361,6 +362,7 @@ TenantDataService.tenantDataMap = {
|
|
|
361
362
|
BACKEND_API_VERSION: '1',
|
|
362
363
|
SITE_NAME: 'Tourism Site',
|
|
363
364
|
SITE_URL: 'https://tourism.dev',
|
|
365
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
364
366
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
365
367
|
SITE_WHATSAPP_BOT: '5511921974030',
|
|
366
368
|
WHATSAPP_BOT_NUMBER_ID: '970274559506875',
|
|
@@ -448,6 +450,7 @@ TenantDataService.tenantDataMap = {
|
|
|
448
450
|
BACKEND_API_VERSION: '1',
|
|
449
451
|
SITE_NAME: 'Private Show',
|
|
450
452
|
SITE_URL: 'https://privateshow.com.br',
|
|
453
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
451
454
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
452
455
|
SITE_WHATSAPP_BOT: '5511921974030',
|
|
453
456
|
WHATSAPP_BOT_NUMBER_ID: '970274559506875',
|
|
@@ -521,6 +524,7 @@ TenantDataService.tenantDataMap = {
|
|
|
521
524
|
BACKEND_API_VERSION: '1',
|
|
522
525
|
SITE_NAME: 'Promo app',
|
|
523
526
|
SITE_URL: 'https://promoapp.com.br',
|
|
527
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
524
528
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
525
529
|
SITE_WHATSAPP_BOT: '5511921974030',
|
|
526
530
|
WHATSAPP_BOT_NUMBER_ID: '970274559506875',
|
|
@@ -576,6 +580,7 @@ TenantDataService.tenantDataMap = {
|
|
|
576
580
|
BACKEND_API_VERSION: '2',
|
|
577
581
|
SITE_NAME: 'Compranomia Delivery',
|
|
578
582
|
SITE_URL: 'https://compranomia.com.br',
|
|
583
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
579
584
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
580
585
|
SITE_WHATSAPP_BOT: '5511921974030',
|
|
581
586
|
WHATSAPP_BOT_NUMBER_ID: '970274559506875',
|
|
@@ -685,6 +690,7 @@ TenantDataService.tenantDataMap = {
|
|
|
685
690
|
BACKEND_API_VERSION: '2',
|
|
686
691
|
SITE_NAME: 'Babelia',
|
|
687
692
|
SITE_URL: 'https://wrsolucoesdigitais.com.br/babelia',
|
|
693
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
688
694
|
SITE_WHATSAPP_SUPPORT: '',
|
|
689
695
|
SITE_WHATSAPP_BOT: '',
|
|
690
696
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -735,6 +741,7 @@ TenantDataService.tenantDataMap = {
|
|
|
735
741
|
BACKEND_API_VERSION: '1',
|
|
736
742
|
SITE_NAME: 'BrainrotColoring',
|
|
737
743
|
SITE_URL: 'https://wrsolucoesdigitais.com.br',
|
|
744
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
738
745
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
739
746
|
SITE_WHATSAPP_BOT: '',
|
|
740
747
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -794,6 +801,7 @@ TenantDataService.tenantDataMap = {
|
|
|
794
801
|
BACKEND_API_VERSION: '1',
|
|
795
802
|
SITE_NAME: 'LeadAutomator',
|
|
796
803
|
SITE_URL: 'https://leadautomator.com.br',
|
|
804
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
797
805
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
798
806
|
SITE_WHATSAPP_BOT: '',
|
|
799
807
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -838,6 +846,7 @@ TenantDataService.tenantDataMap = {
|
|
|
838
846
|
BACKEND_API_VERSION: '1',
|
|
839
847
|
SITE_NAME: 'RealStateVideos',
|
|
840
848
|
SITE_URL: 'https://realstatevideos.com.br',
|
|
849
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
841
850
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
842
851
|
SITE_WHATSAPP_BOT: '',
|
|
843
852
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -882,6 +891,7 @@ TenantDataService.tenantDataMap = {
|
|
|
882
891
|
BACKEND_API_VERSION: '1',
|
|
883
892
|
SITE_NAME: 'CaloriesNutri',
|
|
884
893
|
SITE_URL: 'https://wrsolucoesdigitais.com.br',
|
|
894
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
885
895
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
886
896
|
SITE_WHATSAPP_BOT: '',
|
|
887
897
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -926,6 +936,7 @@ TenantDataService.tenantDataMap = {
|
|
|
926
936
|
BACKEND_API_VERSION: '1',
|
|
927
937
|
SITE_NAME: 'YoutubeDark',
|
|
928
938
|
SITE_URL: 'https://wrsolucoesdigitais.com.br',
|
|
939
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
929
940
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
930
941
|
SITE_WHATSAPP_BOT: '',
|
|
931
942
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -970,6 +981,7 @@ TenantDataService.tenantDataMap = {
|
|
|
970
981
|
BACKEND_API_VERSION: '1',
|
|
971
982
|
SITE_NAME: 'SocialMediaAutomator',
|
|
972
983
|
SITE_URL: 'https://wrsolucoesdigitais.com.br',
|
|
984
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
973
985
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
974
986
|
SITE_WHATSAPP_BOT: '',
|
|
975
987
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -1014,6 +1026,7 @@ TenantDataService.tenantDataMap = {
|
|
|
1014
1026
|
BACKEND_API_VERSION: '1',
|
|
1015
1027
|
SITE_NAME: 'Pão da Vida',
|
|
1016
1028
|
SITE_URL: 'https://wrsolucoesdigitais.com.br',
|
|
1029
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
1017
1030
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
1018
1031
|
SITE_WHATSAPP_BOT: '',
|
|
1019
1032
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -1058,6 +1071,7 @@ TenantDataService.tenantDataMap = {
|
|
|
1058
1071
|
BACKEND_API_VERSION: '1',
|
|
1059
1072
|
SITE_NAME: 'Spotly.social',
|
|
1060
1073
|
SITE_URL: 'https://spotly.social',
|
|
1074
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
1061
1075
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
1062
1076
|
SITE_WHATSAPP_BOT: '',
|
|
1063
1077
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -1104,6 +1118,7 @@ TenantDataService.tenantDataMap = {
|
|
|
1104
1118
|
BACKEND_API_VERSION: '1',
|
|
1105
1119
|
SITE_NAME: 'NotasBr',
|
|
1106
1120
|
SITE_URL: 'https://notasbr.com.br',
|
|
1121
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
1107
1122
|
SITE_WHATSAPP_SUPPORT: '37988083717',
|
|
1108
1123
|
SITE_WHATSAPP_BOT: '',
|
|
1109
1124
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -1148,6 +1163,7 @@ TenantDataService.tenantDataMap = {
|
|
|
1148
1163
|
BACKEND_API_VERSION: '1',
|
|
1149
1164
|
SITE_NAME: 'Trabalho Home Office',
|
|
1150
1165
|
SITE_URL: 'https://www.trabalhohomeoffice.com.br',
|
|
1166
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
1151
1167
|
SITE_WHATSAPP_SUPPORT: '',
|
|
1152
1168
|
SITE_WHATSAPP_BOT: '',
|
|
1153
1169
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -1191,10 +1207,10 @@ TenantDataService.tenantDataMap = {
|
|
|
1191
1207
|
TENANT: tenant_1.Tenant.MercadoProfissional,
|
|
1192
1208
|
BACKEND_API_VERSION: '1',
|
|
1193
1209
|
SITE_NAME: 'Mercado Profissional',
|
|
1194
|
-
//
|
|
1195
|
-
//
|
|
1196
|
-
// existe — trocar antes de qualquer página ir ao ar.
|
|
1210
|
+
// Domínio registrado em 2026-09-20. Falta apontar o DNS para o
|
|
1211
|
+
// ingress do cluster e emitir o certificado.
|
|
1197
1212
|
SITE_URL: 'https://www.mercadoprofissional.com.br',
|
|
1213
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
1198
1214
|
SITE_WHATSAPP_SUPPORT: '',
|
|
1199
1215
|
SITE_WHATSAPP_BOT: '',
|
|
1200
1216
|
WHATSAPP_BOT_NUMBER_ID: '',
|
|
@@ -1203,8 +1219,14 @@ TenantDataService.tenantDataMap = {
|
|
|
1203
1219
|
WHATSAPP_API_VERSION: '',
|
|
1204
1220
|
IOS_APP_DOWNLOAD_LINK: '',
|
|
1205
1221
|
ANDROID_APP_DOWNLOAD_LINK: '',
|
|
1206
|
-
SITE_DESCRIPTION: 'Encontre pedreiro,
|
|
1207
|
-
KEYWORDS: [
|
|
1222
|
+
SITE_DESCRIPTION: 'Encontre eletricista, pedreiro, diarista, manicure e outros profissionais que atendem na sua cidade, e fale direto com eles pelo chat. Grátis.',
|
|
1223
|
+
KEYWORDS: [
|
|
1224
|
+
'profissionais',
|
|
1225
|
+
'servicos',
|
|
1226
|
+
'servico presencial',
|
|
1227
|
+
'profissional autonomo',
|
|
1228
|
+
'por cidade'
|
|
1229
|
+
],
|
|
1208
1230
|
SOCIAL_X: '',
|
|
1209
1231
|
SOCIAL_YOUTUBE: '',
|
|
1210
1232
|
SOCIAL_INSTAGRAM: '',
|
|
@@ -1245,6 +1267,7 @@ TenantDataService.tenantDataMap = {
|
|
|
1245
1267
|
BACKEND_API_VERSION: '1',
|
|
1246
1268
|
SITE_NAME: 'BotTrader',
|
|
1247
1269
|
SITE_URL: 'https://trader.wrsolucoesdigitais.com.br',
|
|
1270
|
+
FROM_EMAIL: 'app@wrsolucoesdigitais.com.br',
|
|
1248
1271
|
SITE_WHATSAPP_SUPPORT: '',
|
|
1249
1272
|
SITE_WHATSAPP_BOT: '',
|
|
1250
1273
|
WHATSAPP_BOT_NUMBER_ID: '',
|
package/build/types/crm.d.ts
CHANGED
|
@@ -211,3 +211,22 @@ export declare enum CrmEventType {
|
|
|
211
211
|
ConnectionRestored = "ConnectionRestored",
|
|
212
212
|
MessageRecovered = "MessageRecovered"
|
|
213
213
|
}
|
|
214
|
+
export interface CrmLeadIntentPayload {
|
|
215
|
+
agentId: string | null;
|
|
216
|
+
customFields: CrmCustomFields;
|
|
217
|
+
trackingPrefix?: string;
|
|
218
|
+
utmSource?: string | null;
|
|
219
|
+
utmMedium?: string | null;
|
|
220
|
+
utmCampaign?: string | null;
|
|
221
|
+
utmTerm?: string | null;
|
|
222
|
+
utmContent?: string | null;
|
|
223
|
+
}
|
|
224
|
+
export interface CrmLeadIntentResult {
|
|
225
|
+
trackingCode: string;
|
|
226
|
+
whatsappUrl: string;
|
|
227
|
+
}
|
|
228
|
+
export interface CrmPublicPersona {
|
|
229
|
+
agentId: string;
|
|
230
|
+
name: string;
|
|
231
|
+
publicTag: string | null;
|
|
232
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Como o profissional se apresenta ao público. Decide o schema.org do perfil:
|
|
3
|
+
* `Individual` vira `Person`, `Business` vira `ProfessionalService`.
|
|
4
|
+
*/
|
|
5
|
+
export declare enum ProfessionalKind {
|
|
6
|
+
Individual = "Individual",
|
|
7
|
+
Business = "Business"
|
|
8
|
+
}
|
|
9
|
+
export declare enum ProfessionalStatus {
|
|
10
|
+
Draft = "Draft",
|
|
11
|
+
Active = "Active",
|
|
12
|
+
Paused = "Paused",
|
|
13
|
+
Blocked = "Blocked"
|
|
14
|
+
}
|
|
15
|
+
export declare enum ServiceAdStatus {
|
|
16
|
+
Draft = "Draft",
|
|
17
|
+
Active = "Active",
|
|
18
|
+
Paused = "Paused"
|
|
19
|
+
}
|
|
20
|
+
/** Ordenação do resultado da busca. */
|
|
21
|
+
export declare enum ProfessionalSort {
|
|
22
|
+
/** Melhor avaliado primeiro; sem avaliação vai para o fim. */
|
|
23
|
+
Rating = "Rating",
|
|
24
|
+
/** Perfil publicado mais recentemente. */
|
|
25
|
+
Recent = "Recent"
|
|
26
|
+
}
|
|
27
|
+
/** Faixa de horário em HH:mm, hora local do profissional. */
|
|
28
|
+
export interface TimePeriod {
|
|
29
|
+
openTime: string;
|
|
30
|
+
closeTime: string;
|
|
31
|
+
}
|
|
32
|
+
/** `dayOfWeek` segue o padrão de JS: 0 = domingo. */
|
|
33
|
+
export interface ScheduleDay {
|
|
34
|
+
dayOfWeek: number;
|
|
35
|
+
isOpen: boolean;
|
|
36
|
+
periods: TimePeriod[];
|
|
37
|
+
}
|
|
38
|
+
/** Feriado, férias ou plantão excepcional. */
|
|
39
|
+
export interface ScheduleException {
|
|
40
|
+
date: string;
|
|
41
|
+
isClosed: boolean;
|
|
42
|
+
customHours?: TimePeriod[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Fusos do Brasil, para interpretar o horário de atendimento.
|
|
46
|
+
*
|
|
47
|
+
* É aproximação por UF, e não por município: o oeste do Amazonas e Fernando de
|
|
48
|
+
* Noronha ficam fora do fuso da própria UF. A alternativa seria guardar o fuso
|
|
49
|
+
* por município do IBGE, e o ganho não paga a manutenção — o erro afeta a
|
|
50
|
+
* exibição de "atende das 8h às 18h" em alguns municípios, não a busca.
|
|
51
|
+
*/
|
|
52
|
+
export declare const MP_TIMEZONE_BY_UF: Record<string, string>;
|
|
53
|
+
/**
|
|
54
|
+
* Mínimo de profissionais para uma página de categoria × cidade ser gerada,
|
|
55
|
+
* indexada e linkada no sitemap do frontend.
|
|
56
|
+
*
|
|
57
|
+
* Mora aqui, e não só no frontend, porque a agregação que alimenta o sitemap
|
|
58
|
+
* roda no backend: se os dois lados tivessem a própria cópia, uma página
|
|
59
|
+
* poderia entrar no sitemap e responder `noindex` ao mesmo tempo.
|
|
60
|
+
*/
|
|
61
|
+
export declare const MP_MIN_PROFESSIONALS_PER_CITY_PAGE = 3;
|
|
62
|
+
/**
|
|
63
|
+
* Filtros da busca de profissionais.
|
|
64
|
+
*
|
|
65
|
+
* A geografia tem UMA forma só: `citySlug`, a cidade em que o profissional se
|
|
66
|
+
* cadastrou. NÃO existe lista de cidades atendidas — quem se cadastrou em São
|
|
67
|
+
* Paulo atende São Paulo, e ponto. Município do IBGE é a menor unidade; não há
|
|
68
|
+
* raio nem distância.
|
|
69
|
+
*
|
|
70
|
+
* Isso se paga de três jeitos: o recorte é estável e cabe numa URL
|
|
71
|
+
* (`/<categoria>/<cidade>-<uf>`), então vira página indexável; o profissional
|
|
72
|
+
* declara uma coisa só, sem tela de seleção múltipla; e o resultado é o mesmo
|
|
73
|
+
* para todo mundo, o que permite cachear a página.
|
|
74
|
+
*
|
|
75
|
+
* O raio de atendimento entra na fase 2 (ano 2) como refinamento OPCIONAL:
|
|
76
|
+
* quem não configurar continua sendo encontrado pela cidade de cadastro.
|
|
77
|
+
*/
|
|
78
|
+
export interface ProfessionalSearchFilters {
|
|
79
|
+
/** Slug da categoria de topo. */
|
|
80
|
+
categorySlug?: string;
|
|
81
|
+
/** Slug da subcategoria. Quando presente, `categorySlug` é redundante. */
|
|
82
|
+
subcategorySlug?: string;
|
|
83
|
+
/** Cidade de cadastro do profissional, no formato `campinas-sp`. */
|
|
84
|
+
citySlug?: string;
|
|
85
|
+
/** Nota mínima, de 1 a 5. Perfil sem avaliação não passa neste filtro. */
|
|
86
|
+
minRating?: number;
|
|
87
|
+
/** Só quem está com a disponibilidade ligada agora. */
|
|
88
|
+
availableNow?: boolean;
|
|
89
|
+
/** Só quem atende 24 horas, todos os dias. */
|
|
90
|
+
around24h?: boolean;
|
|
91
|
+
sort?: ProfessionalSort;
|
|
92
|
+
page?: number;
|
|
93
|
+
limit?: number;
|
|
94
|
+
}
|
|
95
|
+
export interface CityDTO {
|
|
96
|
+
/** `campinas-sp` */
|
|
97
|
+
slug: string;
|
|
98
|
+
name: string;
|
|
99
|
+
uf: string;
|
|
100
|
+
/** Código do município no IBGE. */
|
|
101
|
+
ibgeCode: string;
|
|
102
|
+
}
|
|
103
|
+
export interface CategoryDTO {
|
|
104
|
+
id: string;
|
|
105
|
+
/** Slug único no site inteiro — é o primeiro segmento da URL. */
|
|
106
|
+
slug: string;
|
|
107
|
+
name: string;
|
|
108
|
+
/** `null` quando é categoria de topo. */
|
|
109
|
+
parentSlug: string | null;
|
|
110
|
+
description: string;
|
|
111
|
+
}
|
|
112
|
+
export interface ProfessionalCardDTO {
|
|
113
|
+
id: string;
|
|
114
|
+
name: string;
|
|
115
|
+
kind: ProfessionalKind;
|
|
116
|
+
headline: string;
|
|
117
|
+
photoUrl: string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Categoria de topo em que atua. `null` só acontece se a categoria for
|
|
120
|
+
* removida com perfis ainda apontando para ela — o cartão continua
|
|
121
|
+
* renderizável em vez de a busca inteira quebrar.
|
|
122
|
+
*/
|
|
123
|
+
category: CategoryDTO | null;
|
|
124
|
+
/** Cidade em que ele se cadastrou — e, portanto, onde atende. */
|
|
125
|
+
baseCity: CityDTO;
|
|
126
|
+
/**
|
|
127
|
+
* Média de 1 a 5, ou `null` quando ainda não foi avaliado. `null` é
|
|
128
|
+
* diferente de 0: a página mostra "ainda não tem avaliações", nunca nota
|
|
129
|
+
* zero.
|
|
130
|
+
*/
|
|
131
|
+
averageRating: number | null;
|
|
132
|
+
ratingCount: number;
|
|
133
|
+
/** Disponibilidade ligada neste momento. */
|
|
134
|
+
availableNow: boolean;
|
|
135
|
+
around24h: boolean;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Cidade em que a busca aconteceu, já resolvida do slug. O frontend usa isto
|
|
139
|
+
* para escrever "18 eletricistas em Campinas (SP)" em vez de mostrar uma lista
|
|
140
|
+
* sem contexto. `null` quando a busca não filtrou por cidade.
|
|
141
|
+
*/
|
|
142
|
+
export interface SearchGeoContextDTO {
|
|
143
|
+
city: CityDTO | null;
|
|
144
|
+
}
|
|
145
|
+
export interface ProfessionalSearchResultDTO {
|
|
146
|
+
items: ProfessionalCardDTO[];
|
|
147
|
+
total: number;
|
|
148
|
+
page: number;
|
|
149
|
+
limit: number;
|
|
150
|
+
geo: SearchGeoContextDTO;
|
|
151
|
+
appliedSort: ProfessionalSort;
|
|
152
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Mercado Profissional — classificado de profissionais de serviço PRESENCIAL.
|
|
4
|
+
//
|
|
5
|
+
// Coleções com prefixo `mp_` no mercado-profissional-backend. Tudo aqui é
|
|
6
|
+
// contrato entre o backend e o mercado-profissional-frontend.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MP_MIN_PROFESSIONALS_PER_CITY_PAGE = exports.MP_TIMEZONE_BY_UF = exports.ProfessionalSort = exports.ServiceAdStatus = exports.ProfessionalStatus = exports.ProfessionalKind = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* Como o profissional se apresenta ao público. Decide o schema.org do perfil:
|
|
12
|
+
* `Individual` vira `Person`, `Business` vira `ProfessionalService`.
|
|
13
|
+
*/
|
|
14
|
+
var ProfessionalKind;
|
|
15
|
+
(function (ProfessionalKind) {
|
|
16
|
+
ProfessionalKind["Individual"] = "Individual";
|
|
17
|
+
ProfessionalKind["Business"] = "Business";
|
|
18
|
+
})(ProfessionalKind || (exports.ProfessionalKind = ProfessionalKind = {}));
|
|
19
|
+
var ProfessionalStatus;
|
|
20
|
+
(function (ProfessionalStatus) {
|
|
21
|
+
ProfessionalStatus["Draft"] = "Draft";
|
|
22
|
+
ProfessionalStatus["Active"] = "Active";
|
|
23
|
+
ProfessionalStatus["Paused"] = "Paused";
|
|
24
|
+
ProfessionalStatus["Blocked"] = "Blocked";
|
|
25
|
+
})(ProfessionalStatus || (exports.ProfessionalStatus = ProfessionalStatus = {}));
|
|
26
|
+
var ServiceAdStatus;
|
|
27
|
+
(function (ServiceAdStatus) {
|
|
28
|
+
ServiceAdStatus["Draft"] = "Draft";
|
|
29
|
+
ServiceAdStatus["Active"] = "Active";
|
|
30
|
+
ServiceAdStatus["Paused"] = "Paused";
|
|
31
|
+
})(ServiceAdStatus || (exports.ServiceAdStatus = ServiceAdStatus = {}));
|
|
32
|
+
/** Ordenação do resultado da busca. */
|
|
33
|
+
var ProfessionalSort;
|
|
34
|
+
(function (ProfessionalSort) {
|
|
35
|
+
/** Melhor avaliado primeiro; sem avaliação vai para o fim. */
|
|
36
|
+
ProfessionalSort["Rating"] = "Rating";
|
|
37
|
+
/** Perfil publicado mais recentemente. */
|
|
38
|
+
ProfessionalSort["Recent"] = "Recent";
|
|
39
|
+
})(ProfessionalSort || (exports.ProfessionalSort = ProfessionalSort = {}));
|
|
40
|
+
/**
|
|
41
|
+
* Fusos do Brasil, para interpretar o horário de atendimento.
|
|
42
|
+
*
|
|
43
|
+
* É aproximação por UF, e não por município: o oeste do Amazonas e Fernando de
|
|
44
|
+
* Noronha ficam fora do fuso da própria UF. A alternativa seria guardar o fuso
|
|
45
|
+
* por município do IBGE, e o ganho não paga a manutenção — o erro afeta a
|
|
46
|
+
* exibição de "atende das 8h às 18h" em alguns municípios, não a busca.
|
|
47
|
+
*/
|
|
48
|
+
exports.MP_TIMEZONE_BY_UF = {
|
|
49
|
+
AC: 'America/Rio_Branco',
|
|
50
|
+
AM: 'America/Manaus',
|
|
51
|
+
RO: 'America/Porto_Velho',
|
|
52
|
+
RR: 'America/Boa_Vista',
|
|
53
|
+
MT: 'America/Cuiaba',
|
|
54
|
+
MS: 'America/Campo_Grande',
|
|
55
|
+
AL: 'America/Maceio',
|
|
56
|
+
AP: 'America/Belem',
|
|
57
|
+
BA: 'America/Bahia',
|
|
58
|
+
CE: 'America/Fortaleza',
|
|
59
|
+
DF: 'America/Sao_Paulo',
|
|
60
|
+
ES: 'America/Sao_Paulo',
|
|
61
|
+
GO: 'America/Sao_Paulo',
|
|
62
|
+
MA: 'America/Fortaleza',
|
|
63
|
+
MG: 'America/Sao_Paulo',
|
|
64
|
+
PA: 'America/Belem',
|
|
65
|
+
PB: 'America/Fortaleza',
|
|
66
|
+
PE: 'America/Recife',
|
|
67
|
+
PI: 'America/Fortaleza',
|
|
68
|
+
PR: 'America/Sao_Paulo',
|
|
69
|
+
RJ: 'America/Sao_Paulo',
|
|
70
|
+
RN: 'America/Fortaleza',
|
|
71
|
+
RS: 'America/Sao_Paulo',
|
|
72
|
+
SC: 'America/Sao_Paulo',
|
|
73
|
+
SE: 'America/Maceio',
|
|
74
|
+
SP: 'America/Sao_Paulo',
|
|
75
|
+
TO: 'America/Araguaina'
|
|
76
|
+
};
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Busca
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* Mínimo de profissionais para uma página de categoria × cidade ser gerada,
|
|
82
|
+
* indexada e linkada no sitemap do frontend.
|
|
83
|
+
*
|
|
84
|
+
* Mora aqui, e não só no frontend, porque a agregação que alimenta o sitemap
|
|
85
|
+
* roda no backend: se os dois lados tivessem a própria cópia, uma página
|
|
86
|
+
* poderia entrar no sitemap e responder `noindex` ao mesmo tempo.
|
|
87
|
+
*/
|
|
88
|
+
exports.MP_MIN_PROFESSIONALS_PER_CITY_PAGE = 3;
|