@wrcb/cb-common 1.0.885 → 1.0.886

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 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);
@@ -1191,9 +1191,8 @@ TenantDataService.tenantDataMap = {
1191
1191
  TENANT: tenant_1.Tenant.MercadoProfissional,
1192
1192
  BACKEND_API_VERSION: '1',
1193
1193
  SITE_NAME: 'Mercado Profissional',
1194
- // TODO: domínio ainda não definido. Enquanto estiver com este valor,
1195
- // o canonical e os links de e-mail apontam para um endereço que não
1196
- // existe — trocar antes de qualquer página ir ao ar.
1194
+ // Domínio registrado em 2026-09-20. Falta apontar o DNS para o
1195
+ // ingress do cluster e emitir o certificado.
1197
1196
  SITE_URL: 'https://www.mercadoprofissional.com.br',
1198
1197
  SITE_WHATSAPP_SUPPORT: '',
1199
1198
  SITE_WHATSAPP_BOT: '',
@@ -1203,8 +1202,14 @@ TenantDataService.tenantDataMap = {
1203
1202
  WHATSAPP_API_VERSION: '',
1204
1203
  IOS_APP_DOWNLOAD_LINK: '',
1205
1204
  ANDROID_APP_DOWNLOAD_LINK: '',
1206
- SITE_DESCRIPTION: 'Encontre pedreiro, eletricista, jardineiro e outros profissionais na sua cidade, e fale direto com eles.',
1207
- KEYWORDS: ['profissionais', 'servicos', 'orcamento'],
1205
+ SITE_DESCRIPTION: 'Encontre eletricista, pedreiro, diarista, manicure e outros profissionais que atendem na sua cidade, e fale direto com eles pelo chat. Grátis.',
1206
+ KEYWORDS: [
1207
+ 'profissionais',
1208
+ 'servicos',
1209
+ 'servico presencial',
1210
+ 'profissional autonomo',
1211
+ 'por cidade'
1212
+ ],
1208
1213
  SOCIAL_X: '',
1209
1214
  SOCIAL_YOUTUBE: '',
1210
1215
  SOCIAL_INSTAGRAM: '',
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrcb/cb-common",
3
- "version": "1.0.885",
3
+ "version": "1.0.886",
4
4
  "description": "Common resources between services",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",