evo360-types 1.3.602 → 1.3.606
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/apps/evo-chat/chatbee/zod-schemas.d.ts +4 -4
- package/dist/apps/evo-crm/lead/zod-schemas.d.ts +3 -0
- package/dist/apps/evo-crm/lead/zod-schemas.js +1 -0
- package/dist/apps/evo-crm/lead/zod-schemas.ts +2 -0
- package/dist/apps/evo-csq/zod-schemas.d.ts +595 -10
- package/dist/apps/evo-csq/zod-schemas.js +43 -2
- package/dist/apps/evo-csq/zod-schemas.ts +46 -0
- package/dist/apps/evo-hub-ia/v1/zod-schemas.d.ts +36 -36
- package/dist/apps/evo-med/dic/zod-schemas.d.ts +4 -4
- package/dist/apps/evo-med/people/zod-schemas.d.ts +3 -0
- package/dist/apps/evo-med/people/zod-schemas.js +1 -0
- package/dist/apps/evo-med/people/zod-schemas.ts +2 -0
- package/dist/apps/hub-automation/zod-schemas.d.ts +4 -4
- package/dist/apps/shared/zod-schemas.d.ts +100 -0
- package/dist/apps/shared/zod-schemas.js +39 -1
- package/dist/apps/shared/zod-schemas.ts +44 -0
- package/dist/types/evo-crm/lead/index.d.ts +3 -1
- package/dist/types/evo-crm/lead/index.ts +3 -0
- package/dist/types/evo-csq/index.d.ts +61 -2
- package/dist/types/evo-csq/index.js +5 -1
- package/dist/types/evo-csq/index.ts +72 -2
- package/dist/types/evo-med/people/index.d.ts +3 -1
- package/dist/types/evo-med/people/index.ts +3 -0
- package/dist/types/shared/capture-data.d.ts +49 -0
- package/dist/types/shared/capture-data.js +26 -0
- package/dist/types/shared/capture-data.ts +74 -0
- package/dist/types/shared/index.d.ts +1 -0
- package/dist/types/shared/index.js +1 -0
- package/dist/types/shared/index.ts +1 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.zContactSchema = exports.zAddressSchema = exports.zTagSchema = exports.zFireDocSchema = exports.zFirestoreDateSchema = exports.zEvoAppSchema = void 0;
|
|
3
|
+
exports.zCaptureDataMapSchema = exports.zCaptureDataValueSchema = exports.zCaptureDataFieldSchema = exports.zCaptureDataFieldOptionSchema = exports.zCaptureDataFieldTypeSchema = exports.zContactSchema = exports.zAddressSchema = exports.zTagSchema = exports.zFireDocSchema = exports.zFirestoreDateSchema = exports.zEvoAppSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
// Enum for activity read status
|
|
6
6
|
exports.zEvoAppSchema = zod_1.z.enum([
|
|
@@ -92,3 +92,41 @@ exports.zContactSchema = zod_1.z.object({
|
|
|
92
92
|
// WhatsApp BSUID (Business-Scoped User ID) — contato que a Meta entrega sem telefone
|
|
93
93
|
bsuid: zod_1.z.string().nullable().optional(),
|
|
94
94
|
}).passthrough();
|
|
95
|
+
// ----- Campos complementares (capture-data) — feat-196
|
|
96
|
+
exports.zCaptureDataFieldTypeSchema = zod_1.z.enum([
|
|
97
|
+
"text",
|
|
98
|
+
"number",
|
|
99
|
+
"date",
|
|
100
|
+
"select",
|
|
101
|
+
"boolean",
|
|
102
|
+
]);
|
|
103
|
+
exports.zCaptureDataFieldOptionSchema = zod_1.z
|
|
104
|
+
.object({
|
|
105
|
+
value: zod_1.z.string().min(1).max(255),
|
|
106
|
+
label: zod_1.z.string().min(1).max(255),
|
|
107
|
+
})
|
|
108
|
+
.passthrough();
|
|
109
|
+
/**
|
|
110
|
+
* Campo do dicionário (qualquer entidade). O `code` aceita o legado (1–64);
|
|
111
|
+
* o slug `^[a-z][a-z0-9_]{0,63}$` é regra de CRIAÇÃO, aplicada no backend.
|
|
112
|
+
*/
|
|
113
|
+
exports.zCaptureDataFieldSchema = exports.zFireDocSchema
|
|
114
|
+
.extend({
|
|
115
|
+
code: zod_1.z.string().min(1).max(64),
|
|
116
|
+
name: zod_1.z.string().min(1).max(255),
|
|
117
|
+
type: exports.zCaptureDataFieldTypeSchema.optional(),
|
|
118
|
+
options: zod_1.z.array(exports.zCaptureDataFieldOptionSchema).nullable().optional(),
|
|
119
|
+
required: zod_1.z.boolean().optional(),
|
|
120
|
+
order: zod_1.z.number().int().nullable().optional(),
|
|
121
|
+
searchable: zod_1.z.boolean().optional(),
|
|
122
|
+
mcp_description: zod_1.z.string().max(2000).nullable().optional(),
|
|
123
|
+
mcp_enabled: zod_1.z.boolean().optional(),
|
|
124
|
+
})
|
|
125
|
+
.passthrough();
|
|
126
|
+
exports.zCaptureDataValueSchema = zod_1.z.union([
|
|
127
|
+
zod_1.z.string(),
|
|
128
|
+
zod_1.z.number(),
|
|
129
|
+
zod_1.z.boolean(),
|
|
130
|
+
]);
|
|
131
|
+
/** Mapa `capture_data` gravado na entidade. */
|
|
132
|
+
exports.zCaptureDataMapSchema = zod_1.z.record(exports.zCaptureDataValueSchema);
|
|
@@ -107,3 +107,47 @@ export const zContactSchema = z.object({
|
|
|
107
107
|
// WhatsApp BSUID (Business-Scoped User ID) — contato que a Meta entrega sem telefone
|
|
108
108
|
bsuid: z.string().nullable().optional(),
|
|
109
109
|
}).passthrough();
|
|
110
|
+
|
|
111
|
+
// ----- Campos complementares (capture-data) — feat-196
|
|
112
|
+
|
|
113
|
+
export const zCaptureDataFieldTypeSchema = z.enum([
|
|
114
|
+
"text",
|
|
115
|
+
"number",
|
|
116
|
+
"date",
|
|
117
|
+
"select",
|
|
118
|
+
"boolean",
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
export const zCaptureDataFieldOptionSchema = z
|
|
122
|
+
.object({
|
|
123
|
+
value: z.string().min(1).max(255),
|
|
124
|
+
label: z.string().min(1).max(255),
|
|
125
|
+
})
|
|
126
|
+
.passthrough();
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Campo do dicionário (qualquer entidade). O `code` aceita o legado (1–64);
|
|
130
|
+
* o slug `^[a-z][a-z0-9_]{0,63}$` é regra de CRIAÇÃO, aplicada no backend.
|
|
131
|
+
*/
|
|
132
|
+
export const zCaptureDataFieldSchema = zFireDocSchema
|
|
133
|
+
.extend({
|
|
134
|
+
code: z.string().min(1).max(64),
|
|
135
|
+
name: z.string().min(1).max(255),
|
|
136
|
+
type: zCaptureDataFieldTypeSchema.optional(),
|
|
137
|
+
options: z.array(zCaptureDataFieldOptionSchema).nullable().optional(),
|
|
138
|
+
required: z.boolean().optional(),
|
|
139
|
+
order: z.number().int().nullable().optional(),
|
|
140
|
+
searchable: z.boolean().optional(),
|
|
141
|
+
mcp_description: z.string().max(2000).nullable().optional(),
|
|
142
|
+
mcp_enabled: z.boolean().optional(),
|
|
143
|
+
})
|
|
144
|
+
.passthrough();
|
|
145
|
+
|
|
146
|
+
export const zCaptureDataValueSchema = z.union([
|
|
147
|
+
z.string(),
|
|
148
|
+
z.number(),
|
|
149
|
+
z.boolean(),
|
|
150
|
+
]);
|
|
151
|
+
|
|
152
|
+
/** Mapa `capture_data` gravado na entidade. */
|
|
153
|
+
export const zCaptureDataMapSchema = z.record(zCaptureDataValueSchema);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "../fb_collections";
|
|
2
|
-
import { FirestoreDocumentReference, IAddress, IContact, IExternalLink, ITag } from "../../shared";
|
|
2
|
+
import { CaptureDataMap, FirestoreDocumentReference, IAddress, IContact, IExternalLink, ITag } from "../../shared";
|
|
3
3
|
import { IProfile } from "../../evo-people";
|
|
4
4
|
import { QualificationFunnelLevel } from "../dic";
|
|
5
5
|
export declare const EvoCrmLeadPermissions: {
|
|
@@ -112,6 +112,8 @@ export interface ILead extends IProfile {
|
|
|
112
112
|
/** Derivado de `externalLinks` (`"type:id"`) pelo model — habilita `array-contains`. */
|
|
113
113
|
externalLinkKeys?: string[];
|
|
114
114
|
tags?: ITag[] | null;
|
|
115
|
+
/** Campos complementares (code → valor), validados contra o dicionário `dics/leads/capture-data` (feat-196). */
|
|
116
|
+
capture_data?: CaptureDataMap | null;
|
|
115
117
|
userRef?: FirestoreDocumentReference;
|
|
116
118
|
ctwa_clid?: string | null;
|
|
117
119
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "../fb_collections";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
CaptureDataMap,
|
|
4
5
|
FirestoreDocumentReference,
|
|
5
6
|
IAddress,
|
|
6
7
|
IContact,
|
|
@@ -154,6 +155,8 @@ export interface ILead extends IProfile {
|
|
|
154
155
|
/** Derivado de `externalLinks` (`"type:id"`) pelo model — habilita `array-contains`. */
|
|
155
156
|
externalLinkKeys?: string[];
|
|
156
157
|
tags?: ITag[] | null;
|
|
158
|
+
/** Campos complementares (code → valor), validados contra o dicionário `dics/leads/capture-data` (feat-196). */
|
|
159
|
+
capture_data?: CaptureDataMap | null;
|
|
157
160
|
userRef?: FirestoreDocumentReference;
|
|
158
161
|
// CTWA attribution (feat-034) — capturado do referral do 1º inbound vindo de anúncio Click-to-WhatsApp.
|
|
159
162
|
ctwa_clid?: string | null;
|
|
@@ -9,7 +9,11 @@ export * from "./fb_collections";
|
|
|
9
9
|
* da rubrica (profissional de saude no canal, nome completo so com agendamento, agenda so pelo
|
|
10
10
|
* codigo, urgencia = encaixe, soma de familia, responsavel x paciente). Serve para separar as
|
|
11
11
|
* series antes/depois na analise. */
|
|
12
|
-
|
|
12
|
+
/** v1.3 (2026-09-24, auditoria dos laudos "encaminhar a supervisao"): mesmos pilares/criterios;
|
|
13
|
+
* muda o TEXTO (hierarquia de precedencia: autorizacao da profissional > roteiro do tenant >
|
|
14
|
+
* regra generica; familia em horarios vizinhos e esperada; `retorno_apos_vou_verificar` e
|
|
15
|
+
* `nomes_corretos` com ponderacao) e a SAIDA do juiz ganha `revalidations` e `resolved_alerts`. */
|
|
16
|
+
export declare const CSQ_RUBRIC_VERSION = "v1.3";
|
|
13
17
|
/** Modo do CSQ por departamento (gravado no binding da HubIA).
|
|
14
18
|
* - `off` : nao avalia (default quando ausente).
|
|
15
19
|
* - `shadow` : avalia e grava o laudo, sem notificar supervisores.
|
|
@@ -29,6 +33,14 @@ export type CsqAlertScope = "ticket" | "journey";
|
|
|
29
33
|
/** Ciclo de vida do alerta. Um alerta da jornada fica `open` no laudo corrente
|
|
30
34
|
* ate uma avaliacao posterior constatar a correcao; entao vira `resolved`. */
|
|
31
35
|
export type CsqAlertLifecycle = "open" | "resolved";
|
|
36
|
+
/** Por que um alerta virou `resolved` (feat-154 lote 9). Ausente em laudos anteriores.
|
|
37
|
+
* - `fact` : o recomputo/fato da avaliacao seguinte o encerrou.
|
|
38
|
+
* - `judge_resolved` : o juiz declarou corrigido/insustentavel (alerta `llm`).
|
|
39
|
+
* - `judge_dismissed` : o juiz revalidou um achado automatico e o descartou.
|
|
40
|
+
* - `code_guard` : guarda deterministica aplicada a alerta herdado.
|
|
41
|
+
* - `recheck_ok` : a rechecagem da agenda passou a bater.
|
|
42
|
+
* - `supervisor_false_positive` : marcado como falso positivo na revisao do supervisor. */
|
|
43
|
+
export type CsqAlertResolvedReason = "fact" | "judge_resolved" | "judge_dismissed" | "code_guard" | "recheck_ok" | "supervisor_false_positive";
|
|
32
44
|
/** Estado da rechecagem agendada de agenda (adendo §B). Alertas de agenda
|
|
33
45
|
* nascem `pending` (sem auto-fail nem notificacao) e sao reavaliados em
|
|
34
46
|
* `closed_at + CSQ_DEFAULTS.recheck_delay_min`.
|
|
@@ -145,6 +157,10 @@ export interface ICsqAlert {
|
|
|
145
157
|
recheck_after?: Date;
|
|
146
158
|
/** Ticket em que o alerta foi constatado como resolvido. */
|
|
147
159
|
resolved_in_ticket?: string;
|
|
160
|
+
/** Motivo da resolucao (lote 9). */
|
|
161
|
+
resolved_reason?: CsqAlertResolvedReason;
|
|
162
|
+
/** Texto do motivo, quando houver (ex.: justificativa do juiz). */
|
|
163
|
+
resolved_note?: string;
|
|
148
164
|
/** So em alertas de agenda: agendamento com que o claim foi cruzado, para o
|
|
149
165
|
* Nexus linkar `/{tenant}/evo-med/calendar/{calendar_id}/appointment/{appointment_id}`. */
|
|
150
166
|
appointment_id?: string;
|
|
@@ -442,6 +458,18 @@ export interface ICsqLlmUsage {
|
|
|
442
458
|
/** Tentativas gastas. Contrato: <= 2 (1 retry por falha de schema). */
|
|
443
459
|
rounds?: number;
|
|
444
460
|
}
|
|
461
|
+
/** Veredito do juiz sobre um achado automatico revalidavel (lote 9). O codigo
|
|
462
|
+
* so aplica `dismiss` a codigos da allowlist de revalidacao. */
|
|
463
|
+
export interface ICsqJudgeRevalidation {
|
|
464
|
+
fingerprint: string;
|
|
465
|
+
verdict: "confirm" | "dismiss";
|
|
466
|
+
reason: string;
|
|
467
|
+
}
|
|
468
|
+
/** Alerta anterior (fonte `llm`) que o juiz declarou resolvido, com o motivo. */
|
|
469
|
+
export interface ICsqJudgeResolvedAlert {
|
|
470
|
+
fingerprint: string;
|
|
471
|
+
reason: string;
|
|
472
|
+
}
|
|
445
473
|
/** Saida estruturada da tool `submit_csq_evaluation`. O juiz NAO recebe tools
|
|
446
474
|
* de leitura e nao decide o score final: so pontua, extrai e cita evidencia. */
|
|
447
475
|
export interface ICsqJudgeOutput {
|
|
@@ -454,6 +482,11 @@ export interface ICsqJudgeOutput {
|
|
|
454
482
|
/** Fingerprints de alertas anteriores que este atendimento resolveu.
|
|
455
483
|
* So resolve alertas de fonte `llm` (adendo §G). */
|
|
456
484
|
resolved_alert_ids: string[];
|
|
485
|
+
/** Lote 9: os mesmos resolvidos, com o motivo. Os fingerprints entram tambem em
|
|
486
|
+
* `resolved_alert_ids` na normalizacao. */
|
|
487
|
+
resolved_alerts?: ICsqJudgeResolvedAlert[];
|
|
488
|
+
/** Lote 9: veredito sobre os "achados automaticos a revalidar" do prompt. */
|
|
489
|
+
revalidations?: ICsqJudgeRevalidation[];
|
|
457
490
|
highlights: string[];
|
|
458
491
|
improvements: string[];
|
|
459
492
|
confidence: number;
|
|
@@ -472,12 +505,35 @@ export interface ICsqAppointmentFact {
|
|
|
472
505
|
modality?: string;
|
|
473
506
|
created_at?: Date;
|
|
474
507
|
}
|
|
475
|
-
/**
|
|
508
|
+
/** Agendamento envolvido numa sobreposicao (lote 9). */
|
|
509
|
+
export interface ICsqOverlapAppointmentFact {
|
|
510
|
+
id: string;
|
|
511
|
+
patient_id?: string;
|
|
512
|
+
patient_name?: string;
|
|
513
|
+
start_at: Date;
|
|
514
|
+
end_at?: Date;
|
|
515
|
+
professional_name?: string;
|
|
516
|
+
/** O agendamento e de paciente vinculado ao lead avaliado. */
|
|
517
|
+
is_lead: boolean;
|
|
518
|
+
}
|
|
519
|
+
/** Pistas de agendamento de familia numa sobreposicao (lote 9). */
|
|
520
|
+
export interface ICsqOverlapFamilyHints {
|
|
521
|
+
/** Os pacientes envolvidos (ou o lead) compartilham o sobrenome. */
|
|
522
|
+
same_surname: boolean;
|
|
523
|
+
/** O outro paciente tem o mesmo telefone do lead. */
|
|
524
|
+
same_contact: boolean;
|
|
525
|
+
/** Todos os pacientes envolvidos estao vinculados ao mesmo lead. */
|
|
526
|
+
same_lead: boolean;
|
|
527
|
+
}
|
|
528
|
+
/** Sobreposicao detectada entre agendamentos do mesmo profissional. Desde o
|
|
529
|
+
* lote 9 so envolve agendamentos em que pelo menos um e do lead. */
|
|
476
530
|
export interface ICsqOverlapFact {
|
|
477
531
|
professional_name?: string;
|
|
478
532
|
appointment_ids: string[];
|
|
479
533
|
start_at: Date;
|
|
480
534
|
end_at: Date;
|
|
535
|
+
appointments?: ICsqOverlapAppointmentFact[];
|
|
536
|
+
family_hints?: ICsqOverlapFamilyHints;
|
|
481
537
|
}
|
|
482
538
|
/** Ticket anterior da jornada (motivo, quem fechou). */
|
|
483
539
|
export interface ICsqPreviousTicketFact {
|
|
@@ -633,6 +689,9 @@ export interface ICsqLeadReport extends IFireDoc {
|
|
|
633
689
|
data_quality?: ICsqDataQuality;
|
|
634
690
|
/** Veredito humano (adendo §D). */
|
|
635
691
|
review?: ICsqReview;
|
|
692
|
+
/** Fingerprints marcados como falso positivo pelo supervisor em laudos anteriores
|
|
693
|
+
* (acumulado, lote 9). Alerta com fingerprint aqui fica `resolved` e nao reabre. */
|
|
694
|
+
suppressed_alert_fingerprints?: string[];
|
|
636
695
|
/** Exclusao (soft delete) pelo supervisor: `deleted_at` vem do IFireDoc. O laudo
|
|
637
696
|
* some da fila e do historico do lead; a proxima avaliacao do lead comeca do zero.
|
|
638
697
|
* Transcricao e prompt ficam em `artifacts/` para auditoria. */
|
|
@@ -34,7 +34,11 @@ __exportStar(require("./fb_collections"), exports);
|
|
|
34
34
|
* da rubrica (profissional de saude no canal, nome completo so com agendamento, agenda so pelo
|
|
35
35
|
* codigo, urgencia = encaixe, soma de familia, responsavel x paciente). Serve para separar as
|
|
36
36
|
* series antes/depois na analise. */
|
|
37
|
-
|
|
37
|
+
/** v1.3 (2026-09-24, auditoria dos laudos "encaminhar a supervisao"): mesmos pilares/criterios;
|
|
38
|
+
* muda o TEXTO (hierarquia de precedencia: autorizacao da profissional > roteiro do tenant >
|
|
39
|
+
* regra generica; familia em horarios vizinhos e esperada; `retorno_apos_vou_verificar` e
|
|
40
|
+
* `nomes_corretos` com ponderacao) e a SAIDA do juiz ganha `revalidations` e `resolved_alerts`. */
|
|
41
|
+
exports.CSQ_RUBRIC_VERSION = "v1.3";
|
|
38
42
|
// ───────── Catalogo de alertas (report-spec §6) ─────────
|
|
39
43
|
/** Codigos de alerta v1. Os subtipos de `POLITICA_VIOLADA` e
|
|
40
44
|
* `FLUXO_VENDA_NAO_SEGUIDO` vivem em `ICsqAlert.subtype`, nao como codigos. */
|
|
@@ -22,7 +22,11 @@ export * from "./fb_collections";
|
|
|
22
22
|
* da rubrica (profissional de saude no canal, nome completo so com agendamento, agenda so pelo
|
|
23
23
|
* codigo, urgencia = encaixe, soma de familia, responsavel x paciente). Serve para separar as
|
|
24
24
|
* series antes/depois na analise. */
|
|
25
|
-
|
|
25
|
+
/** v1.3 (2026-09-24, auditoria dos laudos "encaminhar a supervisao"): mesmos pilares/criterios;
|
|
26
|
+
* muda o TEXTO (hierarquia de precedencia: autorizacao da profissional > roteiro do tenant >
|
|
27
|
+
* regra generica; familia em horarios vizinhos e esperada; `retorno_apos_vou_verificar` e
|
|
28
|
+
* `nomes_corretos` com ponderacao) e a SAIDA do juiz ganha `revalidations` e `resolved_alerts`. */
|
|
29
|
+
export const CSQ_RUBRIC_VERSION = "v1.3";
|
|
26
30
|
|
|
27
31
|
// ───────── Enums / Literals ─────────
|
|
28
32
|
|
|
@@ -57,6 +61,21 @@ export type CsqAlertScope = "ticket" | "journey";
|
|
|
57
61
|
* ate uma avaliacao posterior constatar a correcao; entao vira `resolved`. */
|
|
58
62
|
export type CsqAlertLifecycle = "open" | "resolved";
|
|
59
63
|
|
|
64
|
+
/** Por que um alerta virou `resolved` (feat-154 lote 9). Ausente em laudos anteriores.
|
|
65
|
+
* - `fact` : o recomputo/fato da avaliacao seguinte o encerrou.
|
|
66
|
+
* - `judge_resolved` : o juiz declarou corrigido/insustentavel (alerta `llm`).
|
|
67
|
+
* - `judge_dismissed` : o juiz revalidou um achado automatico e o descartou.
|
|
68
|
+
* - `code_guard` : guarda deterministica aplicada a alerta herdado.
|
|
69
|
+
* - `recheck_ok` : a rechecagem da agenda passou a bater.
|
|
70
|
+
* - `supervisor_false_positive` : marcado como falso positivo na revisao do supervisor. */
|
|
71
|
+
export type CsqAlertResolvedReason =
|
|
72
|
+
| "fact"
|
|
73
|
+
| "judge_resolved"
|
|
74
|
+
| "judge_dismissed"
|
|
75
|
+
| "code_guard"
|
|
76
|
+
| "recheck_ok"
|
|
77
|
+
| "supervisor_false_positive";
|
|
78
|
+
|
|
60
79
|
/** Estado da rechecagem agendada de agenda (adendo §B). Alertas de agenda
|
|
61
80
|
* nascem `pending` (sem auto-fail nem notificacao) e sao reavaliados em
|
|
62
81
|
* `closed_at + CSQ_DEFAULTS.recheck_delay_min`.
|
|
@@ -337,6 +356,10 @@ export interface ICsqAlert {
|
|
|
337
356
|
recheck_after?: Date;
|
|
338
357
|
/** Ticket em que o alerta foi constatado como resolvido. */
|
|
339
358
|
resolved_in_ticket?: string;
|
|
359
|
+
/** Motivo da resolucao (lote 9). */
|
|
360
|
+
resolved_reason?: CsqAlertResolvedReason;
|
|
361
|
+
/** Texto do motivo, quando houver (ex.: justificativa do juiz). */
|
|
362
|
+
resolved_note?: string;
|
|
340
363
|
/** So em alertas de agenda: agendamento com que o claim foi cruzado, para o
|
|
341
364
|
* Nexus linkar `/{tenant}/evo-med/calendar/{calendar_id}/appointment/{appointment_id}`. */
|
|
342
365
|
appointment_id?: string;
|
|
@@ -691,6 +714,20 @@ export interface ICsqLlmUsage {
|
|
|
691
714
|
rounds?: number;
|
|
692
715
|
}
|
|
693
716
|
|
|
717
|
+
/** Veredito do juiz sobre um achado automatico revalidavel (lote 9). O codigo
|
|
718
|
+
* so aplica `dismiss` a codigos da allowlist de revalidacao. */
|
|
719
|
+
export interface ICsqJudgeRevalidation {
|
|
720
|
+
fingerprint: string;
|
|
721
|
+
verdict: "confirm" | "dismiss";
|
|
722
|
+
reason: string;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/** Alerta anterior (fonte `llm`) que o juiz declarou resolvido, com o motivo. */
|
|
726
|
+
export interface ICsqJudgeResolvedAlert {
|
|
727
|
+
fingerprint: string;
|
|
728
|
+
reason: string;
|
|
729
|
+
}
|
|
730
|
+
|
|
694
731
|
/** Saida estruturada da tool `submit_csq_evaluation`. O juiz NAO recebe tools
|
|
695
732
|
* de leitura e nao decide o score final: so pontua, extrai e cita evidencia. */
|
|
696
733
|
export interface ICsqJudgeOutput {
|
|
@@ -703,6 +740,11 @@ export interface ICsqJudgeOutput {
|
|
|
703
740
|
/** Fingerprints de alertas anteriores que este atendimento resolveu.
|
|
704
741
|
* So resolve alertas de fonte `llm` (adendo §G). */
|
|
705
742
|
resolved_alert_ids: string[];
|
|
743
|
+
/** Lote 9: os mesmos resolvidos, com o motivo. Os fingerprints entram tambem em
|
|
744
|
+
* `resolved_alert_ids` na normalizacao. */
|
|
745
|
+
resolved_alerts?: ICsqJudgeResolvedAlert[];
|
|
746
|
+
/** Lote 9: veredito sobre os "achados automaticos a revalidar" do prompt. */
|
|
747
|
+
revalidations?: ICsqJudgeRevalidation[];
|
|
706
748
|
highlights: string[];
|
|
707
749
|
improvements: string[];
|
|
708
750
|
confidence: number;
|
|
@@ -725,12 +767,37 @@ export interface ICsqAppointmentFact {
|
|
|
725
767
|
created_at?: Date;
|
|
726
768
|
}
|
|
727
769
|
|
|
728
|
-
/**
|
|
770
|
+
/** Agendamento envolvido numa sobreposicao (lote 9). */
|
|
771
|
+
export interface ICsqOverlapAppointmentFact {
|
|
772
|
+
id: string;
|
|
773
|
+
patient_id?: string;
|
|
774
|
+
patient_name?: string;
|
|
775
|
+
start_at: Date;
|
|
776
|
+
end_at?: Date;
|
|
777
|
+
professional_name?: string;
|
|
778
|
+
/** O agendamento e de paciente vinculado ao lead avaliado. */
|
|
779
|
+
is_lead: boolean;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/** Pistas de agendamento de familia numa sobreposicao (lote 9). */
|
|
783
|
+
export interface ICsqOverlapFamilyHints {
|
|
784
|
+
/** Os pacientes envolvidos (ou o lead) compartilham o sobrenome. */
|
|
785
|
+
same_surname: boolean;
|
|
786
|
+
/** O outro paciente tem o mesmo telefone do lead. */
|
|
787
|
+
same_contact: boolean;
|
|
788
|
+
/** Todos os pacientes envolvidos estao vinculados ao mesmo lead. */
|
|
789
|
+
same_lead: boolean;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/** Sobreposicao detectada entre agendamentos do mesmo profissional. Desde o
|
|
793
|
+
* lote 9 so envolve agendamentos em que pelo menos um e do lead. */
|
|
729
794
|
export interface ICsqOverlapFact {
|
|
730
795
|
professional_name?: string;
|
|
731
796
|
appointment_ids: string[];
|
|
732
797
|
start_at: Date;
|
|
733
798
|
end_at: Date;
|
|
799
|
+
appointments?: ICsqOverlapAppointmentFact[];
|
|
800
|
+
family_hints?: ICsqOverlapFamilyHints;
|
|
734
801
|
}
|
|
735
802
|
|
|
736
803
|
/** Ticket anterior da jornada (motivo, quem fechou). */
|
|
@@ -905,6 +972,9 @@ export interface ICsqLeadReport extends IFireDoc {
|
|
|
905
972
|
data_quality?: ICsqDataQuality;
|
|
906
973
|
/** Veredito humano (adendo §D). */
|
|
907
974
|
review?: ICsqReview;
|
|
975
|
+
/** Fingerprints marcados como falso positivo pelo supervisor em laudos anteriores
|
|
976
|
+
* (acumulado, lote 9). Alerta com fingerprint aqui fica `resolved` e nao reabre. */
|
|
977
|
+
suppressed_alert_fingerprints?: string[];
|
|
908
978
|
/** Exclusao (soft delete) pelo supervisor: `deleted_at` vem do IFireDoc. O laudo
|
|
909
979
|
* some da fila e do historico do lead; a proxima avaliacao do lead comeca do zero.
|
|
910
980
|
* Transcricao e prompt ficam em `artifacts/` para auditoria. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "../fb_collections";
|
|
2
2
|
import { IProfile } from "../../evo-people";
|
|
3
|
-
import type { FirestoreDocumentReference, IAddress, IContact, IExternalLink, ITag } from "../../shared";
|
|
3
|
+
import type { CaptureDataMap, FirestoreDocumentReference, IAddress, IContact, IExternalLink, ITag } from "../../shared";
|
|
4
4
|
import { IMedication, PatientAttachmentBaseCategory } from "../dic";
|
|
5
5
|
export declare const EvoMedProfessionalPermissions: {
|
|
6
6
|
readonly List: "evo_med_people_professional_read";
|
|
@@ -184,6 +184,8 @@ export interface IPatient extends IProfile {
|
|
|
184
184
|
attachments?: IPatientAttachment[] | null;
|
|
185
185
|
attachmentExternalLinkKeys?: string[] | null;
|
|
186
186
|
tags?: ITag[] | null;
|
|
187
|
+
/** Campos complementares (code → valor), validados contra o dicionário `dics/patients/capture-data` (feat-196). */
|
|
188
|
+
capture_data?: CaptureDataMap | null;
|
|
187
189
|
userRef?: FirestoreDocumentReference;
|
|
188
190
|
[key: string]: unknown;
|
|
189
191
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "../fb_collections";
|
|
2
2
|
import { IProfile } from "../../evo-people";
|
|
3
3
|
import type {
|
|
4
|
+
CaptureDataMap,
|
|
4
5
|
FirestoreDocumentReference,
|
|
5
6
|
IAddress,
|
|
6
7
|
IContact,
|
|
@@ -249,6 +250,8 @@ export interface IPatient extends IProfile {
|
|
|
249
250
|
attachments?: IPatientAttachment[] | null;
|
|
250
251
|
attachmentExternalLinkKeys?: string[] | null;
|
|
251
252
|
tags?: ITag[] | null;
|
|
253
|
+
/** Campos complementares (code → valor), validados contra o dicionário `dics/patients/capture-data` (feat-196). */
|
|
254
|
+
capture_data?: CaptureDataMap | null;
|
|
252
255
|
userRef?: FirestoreDocumentReference;
|
|
253
256
|
[key: string]: unknown; // index signature
|
|
254
257
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { IFireDoc } from "./index";
|
|
2
|
+
/** Nome da subcoleção do dicionário, sob `dics/{entidade}/`. */
|
|
3
|
+
export declare const CAPTURE_DATA_COLLECTION = "capture-data";
|
|
4
|
+
/** Entidades que têm dicionário de campos complementares (= segmento do path em `dics/`). */
|
|
5
|
+
export type CaptureDataEntity = "leads" | "patients";
|
|
6
|
+
export declare const CAPTURE_DATA_FIELD_TYPES: readonly ["text", "number", "date", "select", "boolean"];
|
|
7
|
+
/** Tipo do campo. Ausente no doc = `text` (campos legados de lead). */
|
|
8
|
+
export type CaptureDataFieldType = (typeof CAPTURE_DATA_FIELD_TYPES)[number];
|
|
9
|
+
/**
|
|
10
|
+
* Valor gravado no mapa `capture_data`. `date` é string `YYYY-MM-DD`;
|
|
11
|
+
* `select` grava o `value` da opção.
|
|
12
|
+
*/
|
|
13
|
+
export type CaptureDataValue = string | number | boolean;
|
|
14
|
+
/** Mapa gravado na entidade (`lead.capture_data`, `patient.capture_data`). */
|
|
15
|
+
export type CaptureDataMap = Record<string, CaptureDataValue>;
|
|
16
|
+
/**
|
|
17
|
+
* Regra de CRIAÇÃO do `code` (aplicada no backend). Codes legados fora desse
|
|
18
|
+
* padrão (ex.: `Convênio`, `nome-paciente`) continuam válidos para leitura.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CAPTURE_DATA_CODE_PATTERN = "^[a-z][a-z0-9_]{0,63}$";
|
|
21
|
+
/** Limite de caracteres de um valor `text`. */
|
|
22
|
+
export declare const CAPTURE_DATA_TEXT_MAX_LENGTH = 2000;
|
|
23
|
+
export interface ICaptureDataFieldOption {
|
|
24
|
+
/** O que vai gravado no mapa. */
|
|
25
|
+
value: string;
|
|
26
|
+
/** O que a UI mostra. */
|
|
27
|
+
label: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ICaptureDataField extends IFireDoc {
|
|
30
|
+
/** Chave no mapa `capture_data`. Imutável depois de criado. */
|
|
31
|
+
code: string;
|
|
32
|
+
name: string;
|
|
33
|
+
/** Ausente = `text` (legado). Imutável depois de definido. */
|
|
34
|
+
type?: CaptureDataFieldType;
|
|
35
|
+
/** Só para `select`. */
|
|
36
|
+
options?: ICaptureDataFieldOption[] | null;
|
|
37
|
+
required?: boolean;
|
|
38
|
+
order?: number | null;
|
|
39
|
+
/** Envia o valor ao índice de busca (Algolia, região US). Default false (D2). */
|
|
40
|
+
searchable?: boolean;
|
|
41
|
+
/** Instrução para a IA preencher o campo. */
|
|
42
|
+
mcp_description?: string | null;
|
|
43
|
+
/** Default true. */
|
|
44
|
+
mcp_enabled?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** Compatibilidade: o dicionário de lead é o genérico. */
|
|
47
|
+
export type ILeadCaptureDataField = ICaptureDataField;
|
|
48
|
+
/** Dicionário de campos complementares de paciente. */
|
|
49
|
+
export type IPatientCaptureDataField = ICaptureDataField;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CAPTURE_DATA_TEXT_MAX_LENGTH = exports.CAPTURE_DATA_CODE_PATTERN = exports.CAPTURE_DATA_FIELD_TYPES = exports.CAPTURE_DATA_COLLECTION = void 0;
|
|
4
|
+
// ----- Campos complementares (capture-data) — feat-196
|
|
5
|
+
//
|
|
6
|
+
// Dicionário genérico por entidade: cada tenant define campos próprios que são
|
|
7
|
+
// gravados em `{entidade}.capture_data` (mapa code → valor).
|
|
8
|
+
// leads → tenants/{t}/apps/evo-crm/dics/leads/capture-data/{id}
|
|
9
|
+
// patients → tenants/{t}/apps/evo-med/dics/patients/capture-data/{id}
|
|
10
|
+
// Herda do `base_tenant` (o tenant atual vence o base, deduplicado por `code`).
|
|
11
|
+
/** Nome da subcoleção do dicionário, sob `dics/{entidade}/`. */
|
|
12
|
+
exports.CAPTURE_DATA_COLLECTION = "capture-data";
|
|
13
|
+
exports.CAPTURE_DATA_FIELD_TYPES = [
|
|
14
|
+
"text",
|
|
15
|
+
"number",
|
|
16
|
+
"date",
|
|
17
|
+
"select",
|
|
18
|
+
"boolean",
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Regra de CRIAÇÃO do `code` (aplicada no backend). Codes legados fora desse
|
|
22
|
+
* padrão (ex.: `Convênio`, `nome-paciente`) continuam válidos para leitura.
|
|
23
|
+
*/
|
|
24
|
+
exports.CAPTURE_DATA_CODE_PATTERN = "^[a-z][a-z0-9_]{0,63}$";
|
|
25
|
+
/** Limite de caracteres de um valor `text`. */
|
|
26
|
+
exports.CAPTURE_DATA_TEXT_MAX_LENGTH = 2000;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { IFireDoc } from "./index";
|
|
2
|
+
|
|
3
|
+
// ----- Campos complementares (capture-data) — feat-196
|
|
4
|
+
//
|
|
5
|
+
// Dicionário genérico por entidade: cada tenant define campos próprios que são
|
|
6
|
+
// gravados em `{entidade}.capture_data` (mapa code → valor).
|
|
7
|
+
// leads → tenants/{t}/apps/evo-crm/dics/leads/capture-data/{id}
|
|
8
|
+
// patients → tenants/{t}/apps/evo-med/dics/patients/capture-data/{id}
|
|
9
|
+
// Herda do `base_tenant` (o tenant atual vence o base, deduplicado por `code`).
|
|
10
|
+
|
|
11
|
+
/** Nome da subcoleção do dicionário, sob `dics/{entidade}/`. */
|
|
12
|
+
export const CAPTURE_DATA_COLLECTION = "capture-data";
|
|
13
|
+
|
|
14
|
+
/** Entidades que têm dicionário de campos complementares (= segmento do path em `dics/`). */
|
|
15
|
+
export type CaptureDataEntity = "leads" | "patients";
|
|
16
|
+
|
|
17
|
+
export const CAPTURE_DATA_FIELD_TYPES = [
|
|
18
|
+
"text",
|
|
19
|
+
"number",
|
|
20
|
+
"date",
|
|
21
|
+
"select",
|
|
22
|
+
"boolean",
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
/** Tipo do campo. Ausente no doc = `text` (campos legados de lead). */
|
|
26
|
+
export type CaptureDataFieldType = (typeof CAPTURE_DATA_FIELD_TYPES)[number];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Valor gravado no mapa `capture_data`. `date` é string `YYYY-MM-DD`;
|
|
30
|
+
* `select` grava o `value` da opção.
|
|
31
|
+
*/
|
|
32
|
+
export type CaptureDataValue = string | number | boolean;
|
|
33
|
+
|
|
34
|
+
/** Mapa gravado na entidade (`lead.capture_data`, `patient.capture_data`). */
|
|
35
|
+
export type CaptureDataMap = Record<string, CaptureDataValue>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Regra de CRIAÇÃO do `code` (aplicada no backend). Codes legados fora desse
|
|
39
|
+
* padrão (ex.: `Convênio`, `nome-paciente`) continuam válidos para leitura.
|
|
40
|
+
*/
|
|
41
|
+
export const CAPTURE_DATA_CODE_PATTERN = "^[a-z][a-z0-9_]{0,63}$";
|
|
42
|
+
|
|
43
|
+
/** Limite de caracteres de um valor `text`. */
|
|
44
|
+
export const CAPTURE_DATA_TEXT_MAX_LENGTH = 2000;
|
|
45
|
+
|
|
46
|
+
export interface ICaptureDataFieldOption {
|
|
47
|
+
/** O que vai gravado no mapa. */
|
|
48
|
+
value: string;
|
|
49
|
+
/** O que a UI mostra. */
|
|
50
|
+
label: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ICaptureDataField extends IFireDoc {
|
|
54
|
+
/** Chave no mapa `capture_data`. Imutável depois de criado. */
|
|
55
|
+
code: string;
|
|
56
|
+
name: string;
|
|
57
|
+
/** Ausente = `text` (legado). Imutável depois de definido. */
|
|
58
|
+
type?: CaptureDataFieldType;
|
|
59
|
+
/** Só para `select`. */
|
|
60
|
+
options?: ICaptureDataFieldOption[] | null;
|
|
61
|
+
required?: boolean;
|
|
62
|
+
order?: number | null;
|
|
63
|
+
/** Envia o valor ao índice de busca (Algolia, região US). Default false (D2). */
|
|
64
|
+
searchable?: boolean;
|
|
65
|
+
/** Instrução para a IA preencher o campo. */
|
|
66
|
+
mcp_description?: string | null;
|
|
67
|
+
/** Default true. */
|
|
68
|
+
mcp_enabled?: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Compatibilidade: o dicionário de lead é o genérico. */
|
|
72
|
+
export type ILeadCaptureDataField = ICaptureDataField;
|
|
73
|
+
/** Dicionário de campos complementares de paciente. */
|
|
74
|
+
export type IPatientCaptureDataField = ICaptureDataField;
|
|
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
exports.IEvoApp = void 0;
|
|
18
18
|
__exportStar(require("./fb_collections"), exports);
|
|
19
19
|
__exportStar(require("./external-links"), exports);
|
|
20
|
+
__exportStar(require("./capture-data"), exports);
|
|
20
21
|
var IEvoApp;
|
|
21
22
|
(function (IEvoApp) {
|
|
22
23
|
IEvoApp["EvoActivity"] = "evo-activity";
|