evo360-types 1.3.578 → 1.3.583
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/channel/zod-schemas.d.ts +273 -0
- package/dist/apps/evo-chat/channel/zod-schemas.js +17 -1
- package/dist/apps/evo-chat/channel/zod-schemas.ts +19 -0
- package/dist/apps/evo-chat/thread-message/zod-schemas.d.ts +24 -0
- package/dist/apps/evo-chat/thread-message/zod-schemas.js +2 -0
- package/dist/apps/evo-chat/thread-message/zod-schemas.ts +2 -0
- package/dist/apps/evo-chat/waba-template/zod-schemas.d.ts +6 -0
- package/dist/apps/evo-chat/waba-template/zod-schemas.js +2 -0
- package/dist/apps/evo-chat/waba-template/zod-schemas.ts +2 -0
- package/dist/apps/evo-med/calendar/zod-schemas.d.ts +3996 -1572
- package/dist/apps/evo-med/calendar/zod-schemas.js +9 -0
- package/dist/apps/evo-med/calendar/zod-schemas.ts +9 -0
- package/dist/apps/evo-notifications/zod-schemas.d.ts +110 -0
- package/dist/apps/evo-notifications/zod-schemas.js +8 -1
- package/dist/apps/evo-notifications/zod-schemas.ts +9 -0
- package/dist/apps/evo-telemedicine/zod-schemas.d.ts +30 -4
- package/dist/apps/evo-telemedicine/zod-schemas.js +25 -2
- package/dist/apps/evo-telemedicine/zod-schemas.ts +25 -0
- package/dist/apps/hub-automation/zod-schemas.d.ts +29 -5
- package/dist/apps/hub-automation/zod-schemas.js +28 -2
- package/dist/apps/hub-automation/zod-schemas.ts +31 -5
- package/dist/types/evo-chat/channel/index.d.ts +19 -0
- package/dist/types/evo-chat/channel/index.ts +24 -0
- package/dist/types/evo-chat/thread-message/index.d.ts +4 -0
- package/dist/types/evo-chat/thread-message/index.ts +4 -0
- package/dist/types/evo-chat/waba-template/index.d.ts +6 -0
- package/dist/types/evo-chat/waba-template/index.js +3 -1
- package/dist/types/evo-chat/waba-template/index.ts +7 -0
- package/dist/types/evo-med/calendar/index.d.ts +26 -1
- package/dist/types/evo-med/calendar/index.ts +27 -1
- package/dist/types/evo-notifications/index.d.ts +11 -0
- package/dist/types/evo-notifications/index.ts +13 -0
- package/dist/types/evo-telemedicine/index.d.ts +168 -0
- package/dist/types/evo-telemedicine/index.js +43 -1
- package/dist/types/evo-telemedicine/index.ts +196 -1
- package/dist/types/hub-automation/index.d.ts +9 -1
- package/dist/types/hub-automation/index.js +8 -1
- package/dist/types/hub-automation/index.ts +15 -0
- package/package.json +1 -1
|
@@ -54,6 +54,15 @@ export const zAutomationTimeOfDaySchema = z
|
|
|
54
54
|
.string()
|
|
55
55
|
.regex(/^([01]\d|2[0-3]):[0-5]\d$/, "expected HH:mm");
|
|
56
56
|
|
|
57
|
+
// feat-167: value of the between/not_between branch operators. Kept separate
|
|
58
|
+
// from selection.time_range (inline below), which does not change.
|
|
59
|
+
export const zAutomationTimeOfDayRangeSchema = z
|
|
60
|
+
.object({ start: zAutomationTimeOfDaySchema, end: zAutomationTimeOfDaySchema })
|
|
61
|
+
.refine((r) => r.start !== r.end, {
|
|
62
|
+
message: "start and end must differ",
|
|
63
|
+
path: ["end"],
|
|
64
|
+
});
|
|
65
|
+
|
|
57
66
|
// feat-147: appointment modality (IAppointment.appointmentMode). Fixed enum —
|
|
58
67
|
// the selection matches it exactly (no wildcard glob).
|
|
59
68
|
export const zAutomationAppointmentModeSchema = z.enum([
|
|
@@ -146,13 +155,30 @@ export const zAutomationOperatorSchema = z.enum([
|
|
|
146
155
|
"not_exists",
|
|
147
156
|
"is_true",
|
|
148
157
|
"is_false",
|
|
158
|
+
// feat-167
|
|
159
|
+
"between",
|
|
160
|
+
"not_between",
|
|
149
161
|
]);
|
|
150
162
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
163
|
+
// feat-167: between/not_between validate `value` as a time-of-day range. The
|
|
164
|
+
// operator is NOT tied to `appointment.start_time` here (`fact` stays a free
|
|
165
|
+
// string for forward compat); the evaluator returns false on any other fact and
|
|
166
|
+
// the builder only offers these operators for the time fact.
|
|
167
|
+
export const zAutomationConditionSchema = z
|
|
168
|
+
.object({
|
|
169
|
+
fact: z.string().min(1),
|
|
170
|
+
operator: zAutomationOperatorSchema,
|
|
171
|
+
value: z.unknown().optional(),
|
|
172
|
+
})
|
|
173
|
+
.superRefine((c, ctx) => {
|
|
174
|
+
if (c.operator !== "between" && c.operator !== "not_between") return;
|
|
175
|
+
const r = zAutomationTimeOfDayRangeSchema.safeParse(c.value);
|
|
176
|
+
if (!r.success) {
|
|
177
|
+
for (const issue of r.error.issues) {
|
|
178
|
+
ctx.addIssue({ ...issue, path: ["value", ...issue.path] });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
156
182
|
|
|
157
183
|
// z.lazy needs an explicit type annotation for the recursive reference.
|
|
158
184
|
type ZAutomationConditionGroup = {
|
|
@@ -49,6 +49,23 @@ export interface ICallsChannelConfig {
|
|
|
49
49
|
inbound_voice_enabled?: boolean;
|
|
50
50
|
outbound_permission?: ICallOutboundPermissionConfig;
|
|
51
51
|
}
|
|
52
|
+
export type WabaDirectSendCategory = 'utility' | 'authentication';
|
|
53
|
+
/** Restricao aplicada pela Meta ao Direct Send do WABA (webhook `account_update` / ACCOUNT_RESTRICTION). */
|
|
54
|
+
export interface IChannelDirectSendRestriction {
|
|
55
|
+
violation_type: string;
|
|
56
|
+
restriction_type?: string | null;
|
|
57
|
+
expiration?: Date | null;
|
|
58
|
+
received_at: Date;
|
|
59
|
+
}
|
|
60
|
+
/** Meta Direct Send (beta): envio iniciado pela empresa sem template previo. Desligado por padrao. */
|
|
61
|
+
export interface IChannelDirectSendConfig {
|
|
62
|
+
enabled: boolean;
|
|
63
|
+
categories?: WabaDirectSendCategory[];
|
|
64
|
+
default_ttl_seconds?: number | null;
|
|
65
|
+
/** Enquanto no futuro, o Direct Send do canal fica suspenso. */
|
|
66
|
+
restricted_until?: Date | null;
|
|
67
|
+
restriction?: IChannelDirectSendRestriction | null;
|
|
68
|
+
}
|
|
52
69
|
export interface IChannel extends IFireDoc {
|
|
53
70
|
model_ver: number;
|
|
54
71
|
provider: ChannelProvider | string;
|
|
@@ -61,6 +78,8 @@ export interface IChannel extends IFireDoc {
|
|
|
61
78
|
provider_ref: IChannelProviderRef;
|
|
62
79
|
hub_ia?: IHubIAConfig;
|
|
63
80
|
calls?: ICallsChannelConfig;
|
|
81
|
+
/** feat-165 — Meta Direct Send (beta). */
|
|
82
|
+
direct_send?: IChannelDirectSendConfig;
|
|
64
83
|
/** feat-142 — rollup da recepção do histórico de coexistência (WABA). */
|
|
65
84
|
history_import?: IChannelHistoryImport;
|
|
66
85
|
[key: string]: unknown;
|
|
@@ -71,6 +71,28 @@ export interface ICallsChannelConfig {
|
|
|
71
71
|
outbound_permission?: ICallOutboundPermissionConfig;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
// ── Direct Send config (feat-165) ──
|
|
75
|
+
|
|
76
|
+
export type WabaDirectSendCategory = 'utility' | 'authentication';
|
|
77
|
+
|
|
78
|
+
/** Restricao aplicada pela Meta ao Direct Send do WABA (webhook `account_update` / ACCOUNT_RESTRICTION). */
|
|
79
|
+
export interface IChannelDirectSendRestriction {
|
|
80
|
+
violation_type: string;
|
|
81
|
+
restriction_type?: string | null;
|
|
82
|
+
expiration?: Date | null;
|
|
83
|
+
received_at: Date;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Meta Direct Send (beta): envio iniciado pela empresa sem template previo. Desligado por padrao. */
|
|
87
|
+
export interface IChannelDirectSendConfig {
|
|
88
|
+
enabled: boolean;
|
|
89
|
+
categories?: WabaDirectSendCategory[];
|
|
90
|
+
default_ttl_seconds?: number | null;
|
|
91
|
+
/** Enquanto no futuro, o Direct Send do canal fica suspenso. */
|
|
92
|
+
restricted_until?: Date | null;
|
|
93
|
+
restriction?: IChannelDirectSendRestriction | null;
|
|
94
|
+
}
|
|
95
|
+
|
|
74
96
|
// ── Channel (evo-chat v3) ──
|
|
75
97
|
|
|
76
98
|
export interface IChannel extends IFireDoc {
|
|
@@ -85,6 +107,8 @@ export interface IChannel extends IFireDoc {
|
|
|
85
107
|
provider_ref: IChannelProviderRef;
|
|
86
108
|
hub_ia?: IHubIAConfig;
|
|
87
109
|
calls?: ICallsChannelConfig;
|
|
110
|
+
/** feat-165 — Meta Direct Send (beta). */
|
|
111
|
+
direct_send?: IChannelDirectSendConfig;
|
|
88
112
|
/** feat-142 — rollup da recepção do histórico de coexistência (WABA). */
|
|
89
113
|
history_import?: IChannelHistoryImport;
|
|
90
114
|
[key: string]: unknown;
|
|
@@ -13,6 +13,8 @@ export interface IMessageStatus {
|
|
|
13
13
|
}>;
|
|
14
14
|
error_code?: string;
|
|
15
15
|
error_message?: string;
|
|
16
|
+
/** feat-165 — id do template (inclusive o auto-gerado do Direct Send) informado no webhook de status. */
|
|
17
|
+
template_id?: string | null;
|
|
16
18
|
}
|
|
17
19
|
export interface IMessageMedia {
|
|
18
20
|
gcs_uri?: string;
|
|
@@ -68,6 +70,8 @@ export interface IMessageCreatedBy {
|
|
|
68
70
|
export interface IMessagePricing {
|
|
69
71
|
category?: 'service' | 'utility' | 'authentication' | 'marketing';
|
|
70
72
|
billable?: boolean;
|
|
73
|
+
/** feat-165 — `pricing.pricing_model` do webhook de status (ex.: PMP). */
|
|
74
|
+
pricing_model?: string | null;
|
|
71
75
|
}
|
|
72
76
|
export interface IRenderedTemplateButton {
|
|
73
77
|
type?: string;
|
|
@@ -22,6 +22,8 @@ export interface IMessageStatus {
|
|
|
22
22
|
errors?: Array<{ code: number; title: string }>;
|
|
23
23
|
error_code?: string;
|
|
24
24
|
error_message?: string;
|
|
25
|
+
/** feat-165 — id do template (inclusive o auto-gerado do Direct Send) informado no webhook de status. */
|
|
26
|
+
template_id?: string | null;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
// ── Message media ──
|
|
@@ -97,6 +99,8 @@ export interface IMessageCreatedBy {
|
|
|
97
99
|
export interface IMessagePricing {
|
|
98
100
|
category?: 'service' | 'utility' | 'authentication' | 'marketing';
|
|
99
101
|
billable?: boolean;
|
|
102
|
+
/** feat-165 — `pricing.pricing_model` do webhook de status (ex.: PMP). */
|
|
103
|
+
pricing_model?: string | null;
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
// ── Mensagem de template compilada (feat-114) ──
|
|
@@ -40,6 +40,8 @@ export declare const WabaTemplateParameterFormatEnum: {
|
|
|
40
40
|
readonly Positional: "POSITIONAL";
|
|
41
41
|
};
|
|
42
42
|
export type WabaTemplateParameterFormat = (typeof WabaTemplateParameterFormatEnum)[keyof typeof WabaTemplateParameterFormatEnum];
|
|
43
|
+
/** Valor de `source` dos templates criados pela Meta para mensagens Direct Send (nao editaveis/deletaveis). */
|
|
44
|
+
export declare const WABA_TEMPLATE_SOURCE_AUTO_GENERATED = "AUTO_GENERATED";
|
|
43
45
|
export interface IWabaTemplateButton {
|
|
44
46
|
type: WabaTemplateButtonType;
|
|
45
47
|
text: string;
|
|
@@ -83,6 +85,10 @@ export interface IWabaTemplate extends IFireDoc {
|
|
|
83
85
|
synced_at?: Date | null;
|
|
84
86
|
is_draft: boolean;
|
|
85
87
|
draft_source?: IWabaTemplateDraftSource;
|
|
88
|
+
/** Origem na Meta; `AUTO_GENERATED` = gerado pelo Direct Send. */
|
|
89
|
+
source?: string | null;
|
|
90
|
+
/** Categoria corrigida pela Meta (`template_correct_category_detection`). */
|
|
91
|
+
correct_category?: string | null;
|
|
86
92
|
}
|
|
87
93
|
export interface IWabaTemplateCreateRequest {
|
|
88
94
|
name: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WabaTemplateParameterFormatEnum = exports.WabaTemplateButtonTypeEnum = exports.WabaTemplateHeaderFormatEnum = exports.WabaTemplateComponentTypeEnum = exports.WabaTemplateCategoryEnum = exports.WabaTemplateStatusEnum = void 0;
|
|
3
|
+
exports.WABA_TEMPLATE_SOURCE_AUTO_GENERATED = exports.WabaTemplateParameterFormatEnum = exports.WabaTemplateButtonTypeEnum = exports.WabaTemplateHeaderFormatEnum = exports.WabaTemplateComponentTypeEnum = exports.WabaTemplateCategoryEnum = exports.WabaTemplateStatusEnum = void 0;
|
|
4
4
|
// ── Enums ──
|
|
5
5
|
exports.WabaTemplateStatusEnum = {
|
|
6
6
|
Draft: 'DRAFT',
|
|
@@ -37,3 +37,5 @@ exports.WabaTemplateParameterFormatEnum = {
|
|
|
37
37
|
Named: 'NAMED',
|
|
38
38
|
Positional: 'POSITIONAL',
|
|
39
39
|
};
|
|
40
|
+
/** Valor de `source` dos templates criados pela Meta para mensagens Direct Send (nao editaveis/deletaveis). */
|
|
41
|
+
exports.WABA_TEMPLATE_SOURCE_AUTO_GENERATED = 'AUTO_GENERATED';
|
|
@@ -49,6 +49,9 @@ export const WabaTemplateParameterFormatEnum = {
|
|
|
49
49
|
} as const;
|
|
50
50
|
export type WabaTemplateParameterFormat = (typeof WabaTemplateParameterFormatEnum)[keyof typeof WabaTemplateParameterFormatEnum];
|
|
51
51
|
|
|
52
|
+
/** Valor de `source` dos templates criados pela Meta para mensagens Direct Send (nao editaveis/deletaveis). */
|
|
53
|
+
export const WABA_TEMPLATE_SOURCE_AUTO_GENERATED = 'AUTO_GENERATED';
|
|
54
|
+
|
|
52
55
|
// ── Component types ──
|
|
53
56
|
|
|
54
57
|
export interface IWabaTemplateButton {
|
|
@@ -95,6 +98,10 @@ export interface IWabaTemplate extends IFireDoc {
|
|
|
95
98
|
synced_at?: Date | null;
|
|
96
99
|
is_draft: boolean;
|
|
97
100
|
draft_source?: IWabaTemplateDraftSource;
|
|
101
|
+
/** Origem na Meta; `AUTO_GENERATED` = gerado pelo Direct Send. */
|
|
102
|
+
source?: string | null;
|
|
103
|
+
/** Categoria corrigida pela Meta (`template_correct_category_detection`). */
|
|
104
|
+
correct_category?: string | null;
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
// ── Request types ──
|
|
@@ -47,6 +47,29 @@ export interface IMedCalendarNotificationConfig {
|
|
|
47
47
|
configs?: {
|
|
48
48
|
[configKey: string]: IMedCalendarNotificationEntry;
|
|
49
49
|
} | null;
|
|
50
|
+
/**
|
|
51
|
+
* feat-160 (§10.2) — MESMA forma de `configs`, mas só para agendamento com
|
|
52
|
+
* `appointmentMode === 'telemedicine'`.
|
|
53
|
+
*
|
|
54
|
+
* **Semântica de HERANÇA, resolvida em UM lugar** (`@evo/model`
|
|
55
|
+
* `calendar-notification-config.ts` → `resolveNotificationConfigEntry(config,
|
|
56
|
+
* configKey, mode)`); nenhum leitor decide sozinho:
|
|
57
|
+
*
|
|
58
|
+
* - modo `telemedicine` e a chave EXISTE aqui ⇒ vale esta entrada, inclusive
|
|
59
|
+
* com `enabled: false` (é exatamente assim que a clínica desliga um aviso
|
|
60
|
+
* SÓ na telemedicina sem mexer no presencial);
|
|
61
|
+
* - modo `telemedicine` e a chave NÃO existe aqui ⇒ HERDA `configs[configKey]`;
|
|
62
|
+
* - modo presencial (ou ausente) ⇒ `configs[configKey]`, este bloco é ignorado.
|
|
63
|
+
*
|
|
64
|
+
* Chave ausente ≠ chave com `enabled:false`: a primeira herda, a segunda
|
|
65
|
+
* desliga. É a única distinção que o editor do FE precisa expressar ("herdar
|
|
66
|
+
* do presencial" = remover a chave).
|
|
67
|
+
*
|
|
68
|
+
* Ausência do bloco inteiro = comportamento pré-feat-160 (toda agenda hoje).
|
|
69
|
+
*/
|
|
70
|
+
telemedicine_configs?: {
|
|
71
|
+
[configKey: string]: IMedCalendarNotificationEntry;
|
|
72
|
+
} | null;
|
|
50
73
|
}
|
|
51
74
|
/** Uma config de notificação (feat-092): um evento/momento × seus canais. */
|
|
52
75
|
export interface IMedCalendarNotificationEntry {
|
|
@@ -74,8 +97,10 @@ export interface IMedCalendarNotificationChannelEntry {
|
|
|
74
97
|
department_id?: string | null;
|
|
75
98
|
/** Template principal da mensagem (HSM name no WA / template_id lógico no email). */
|
|
76
99
|
template_id?: string | null;
|
|
77
|
-
/** Tipo do template principal: 'hsm' | 'email' | … O leitor pode inferir pelo canal. */
|
|
100
|
+
/** Tipo do template principal: 'hsm' | 'quick_reply' | 'direct_send' | 'email' | … O leitor pode inferir pelo canal. */
|
|
78
101
|
template_type?: string | null;
|
|
102
|
+
/** feat-165 — texto (com tokens) enviado quando `template_type === 'direct_send'`. */
|
|
103
|
+
direct_send_text?: string | null;
|
|
79
104
|
/** Botões/ações da mensagem → artefato de resposta de cada um. */
|
|
80
105
|
ctas?: IMedCalendarNotificationCta[] | null;
|
|
81
106
|
}
|
|
@@ -61,6 +61,30 @@ export interface IMedCalendarNotificationConfig {
|
|
|
61
61
|
* `email` legados (que os consumidores atuais ainda leem).
|
|
62
62
|
*/
|
|
63
63
|
configs?: { [configKey: string]: IMedCalendarNotificationEntry } | null;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* feat-160 (§10.2) — MESMA forma de `configs`, mas só para agendamento com
|
|
67
|
+
* `appointmentMode === 'telemedicine'`.
|
|
68
|
+
*
|
|
69
|
+
* **Semântica de HERANÇA, resolvida em UM lugar** (`@evo/model`
|
|
70
|
+
* `calendar-notification-config.ts` → `resolveNotificationConfigEntry(config,
|
|
71
|
+
* configKey, mode)`); nenhum leitor decide sozinho:
|
|
72
|
+
*
|
|
73
|
+
* - modo `telemedicine` e a chave EXISTE aqui ⇒ vale esta entrada, inclusive
|
|
74
|
+
* com `enabled: false` (é exatamente assim que a clínica desliga um aviso
|
|
75
|
+
* SÓ na telemedicina sem mexer no presencial);
|
|
76
|
+
* - modo `telemedicine` e a chave NÃO existe aqui ⇒ HERDA `configs[configKey]`;
|
|
77
|
+
* - modo presencial (ou ausente) ⇒ `configs[configKey]`, este bloco é ignorado.
|
|
78
|
+
*
|
|
79
|
+
* Chave ausente ≠ chave com `enabled:false`: a primeira herda, a segunda
|
|
80
|
+
* desliga. É a única distinção que o editor do FE precisa expressar ("herdar
|
|
81
|
+
* do presencial" = remover a chave).
|
|
82
|
+
*
|
|
83
|
+
* Ausência do bloco inteiro = comportamento pré-feat-160 (toda agenda hoje).
|
|
84
|
+
*/
|
|
85
|
+
telemedicine_configs?:
|
|
86
|
+
| { [configKey: string]: IMedCalendarNotificationEntry }
|
|
87
|
+
| null;
|
|
64
88
|
}
|
|
65
89
|
|
|
66
90
|
/** Uma config de notificação (feat-092): um evento/momento × seus canais. */
|
|
@@ -90,8 +114,10 @@ export interface IMedCalendarNotificationChannelEntry {
|
|
|
90
114
|
department_id?: string | null;
|
|
91
115
|
/** Template principal da mensagem (HSM name no WA / template_id lógico no email). */
|
|
92
116
|
template_id?: string | null;
|
|
93
|
-
/** Tipo do template principal: 'hsm' | 'email' | … O leitor pode inferir pelo canal. */
|
|
117
|
+
/** Tipo do template principal: 'hsm' | 'quick_reply' | 'direct_send' | 'email' | … O leitor pode inferir pelo canal. */
|
|
94
118
|
template_type?: string | null;
|
|
119
|
+
/** feat-165 — texto (com tokens) enviado quando `template_type === 'direct_send'`. */
|
|
120
|
+
direct_send_text?: string | null;
|
|
95
121
|
/** Botões/ações da mensagem → artefato de resposta de cada um. */
|
|
96
122
|
ctas?: IMedCalendarNotificationCta[] | null;
|
|
97
123
|
}
|
|
@@ -113,6 +113,11 @@ export interface IQuickReplyActionIntent {
|
|
|
113
113
|
url_secret?: string;
|
|
114
114
|
[key: string]: unknown;
|
|
115
115
|
}
|
|
116
|
+
/** feat-165 — Meta Direct Send. `ttl_seconds`: 30..43200 (utility). */
|
|
117
|
+
export interface INotificationDirectSend {
|
|
118
|
+
category: 'utility';
|
|
119
|
+
ttl_seconds?: number;
|
|
120
|
+
}
|
|
116
121
|
export interface INotificationSendPayload {
|
|
117
122
|
kind: "notification.send";
|
|
118
123
|
classification?: string;
|
|
@@ -126,6 +131,12 @@ export interface INotificationSendPayload {
|
|
|
126
131
|
* Mutuamente exclusivo com `template.template_id` para `channel.type === 'whatsapp'`.
|
|
127
132
|
*/
|
|
128
133
|
body_text?: string;
|
|
134
|
+
/**
|
|
135
|
+
* feat-165 — intencao de envio via Meta Direct Send (utilidade, sem template).
|
|
136
|
+
* So e honrada se o canal tiver `direct_send.enabled` e nao estiver restrito;
|
|
137
|
+
* caso contrario o envio segue o comportamento atual.
|
|
138
|
+
*/
|
|
139
|
+
direct_send?: INotificationDirectSend;
|
|
129
140
|
/**
|
|
130
141
|
* Quick-reply actions (actionable WhatsApp buttons / email links).
|
|
131
142
|
* Channel-agnostic intents; the provider renders them per channel.
|
|
@@ -196,6 +196,12 @@ export interface IQuickReplyActionIntent {
|
|
|
196
196
|
// Payload schema for Task Runner (task.auto.kind = "notification.send")
|
|
197
197
|
// ======================================================
|
|
198
198
|
|
|
199
|
+
/** feat-165 — Meta Direct Send. `ttl_seconds`: 30..43200 (utility). */
|
|
200
|
+
export interface INotificationDirectSend {
|
|
201
|
+
category: 'utility';
|
|
202
|
+
ttl_seconds?: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
199
205
|
export interface INotificationSendPayload {
|
|
200
206
|
kind: "notification.send";
|
|
201
207
|
|
|
@@ -217,6 +223,13 @@ export interface INotificationSendPayload {
|
|
|
217
223
|
*/
|
|
218
224
|
body_text?: string;
|
|
219
225
|
|
|
226
|
+
/**
|
|
227
|
+
* feat-165 — intencao de envio via Meta Direct Send (utilidade, sem template).
|
|
228
|
+
* So e honrada se o canal tiver `direct_send.enabled` e nao estiver restrito;
|
|
229
|
+
* caso contrario o envio segue o comportamento atual.
|
|
230
|
+
*/
|
|
231
|
+
direct_send?: INotificationDirectSend;
|
|
232
|
+
|
|
220
233
|
/**
|
|
221
234
|
* Quick-reply actions (actionable WhatsApp buttons / email links).
|
|
222
235
|
* Channel-agnostic intents; the provider renders them per channel.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./fb_collections";
|
|
2
2
|
import type { IFireDoc, IFireGlobalDoc } from "../shared";
|
|
3
3
|
import type { ITenantModuleEntitlement } from "../evo-tenant";
|
|
4
|
+
import type { VirtualCareRecordingMode } from "../evo-med/calendar";
|
|
4
5
|
export declare const EvoTelemedicinePermissions: {
|
|
5
6
|
/** Ver estado e dados operacionais básicos. */
|
|
6
7
|
readonly Read: "evo_telemedicine_read";
|
|
@@ -259,8 +260,22 @@ export declare const TeleconsultationEventTypeEnum: {
|
|
|
259
260
|
readonly RecordingConsentRequested: "recording.consent_requested";
|
|
260
261
|
readonly RecordingConsentAccepted: "recording.consent_accepted";
|
|
261
262
|
readonly RecordingConsentDeclined: "recording.consent_declined";
|
|
263
|
+
/**
|
|
264
|
+
* feat-160 F15 — o paciente RECUSOU a gravação automática ANTES de entrar.
|
|
265
|
+
* Não é `recording.consent_declined`: aquela é a recusa de uma solicitação
|
|
266
|
+
* feita em sala (a consulta segue sem gravar); esta IMPEDE a entrada, porque
|
|
267
|
+
* em `auto_*` o aceite é condição do join (D21).
|
|
268
|
+
*/
|
|
269
|
+
readonly RecordingConsentDeclinedPreJoin: "recording.consent_declined_pre_join";
|
|
262
270
|
readonly RecordingConsentWithdrawn: "recording.consent_withdrawn";
|
|
263
271
|
readonly RecordingStarted: "recording.started";
|
|
272
|
+
/**
|
|
273
|
+
* feat-160 F15 — gravação iniciada pela POLÍTICA da agenda (`auto_audio`/
|
|
274
|
+
* `auto_video`), não por comando do médico. Trilha própria porque
|
|
275
|
+
* `recording.started` sem um `recording.consent_requested` antes pareceria
|
|
276
|
+
* gravação sem solicitação na auditoria.
|
|
277
|
+
*/
|
|
278
|
+
readonly RecordingAutoStarted: "recording.auto_started";
|
|
264
279
|
readonly RecordingStopped: "recording.stopped";
|
|
265
280
|
readonly RecordingFailed: "recording.failed";
|
|
266
281
|
readonly TranscriptionQueued: "transcription.queued";
|
|
@@ -270,6 +285,15 @@ export declare const TeleconsultationEventTypeEnum: {
|
|
|
270
285
|
readonly ConsultationStarted: "consultation.started";
|
|
271
286
|
readonly ConsultationReconnecting: "consultation.reconnecting";
|
|
272
287
|
readonly ConsultationEnded: "consultation.ended";
|
|
288
|
+
/**
|
|
289
|
+
* feat-160 F18 — consulta encerrada e MEDIDA como "não contada" (paciente
|
|
290
|
+
* não atendeu, sem gravação elegível, franquia). Existe porque
|
|
291
|
+
* `usage_metered_at` é carimbado nos DOIS casos: sem este evento a
|
|
292
|
+
* reconciliação "quantas `ended` carimbadas × quantas linhas no BigQuery"
|
|
293
|
+
* acusaria diferença em toda consulta não contada, indistinguível de evento
|
|
294
|
+
* perdido.
|
|
295
|
+
*/
|
|
296
|
+
readonly UsageSkipped: "teleconsultation.usage_skipped";
|
|
273
297
|
readonly ArtifactAccessed: "artifact.accessed";
|
|
274
298
|
readonly ArtifactDeleted: "artifact.deleted";
|
|
275
299
|
readonly EntitlementDenied: "entitlement.denied";
|
|
@@ -834,6 +858,56 @@ export interface IRoomRecordingStateDto {
|
|
|
834
858
|
terms_version?: string;
|
|
835
859
|
/** Código estável, sem PII, quando `status === 'failed'`. */
|
|
836
860
|
failure_code?: string;
|
|
861
|
+
/** feat-160 F15 — presente só nos modos `auto_*` (aviso pré-join). */
|
|
862
|
+
auto?: IRoomRecordingAutoDto;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* feat-160 F15 — aviso PRÉ-JOIN da gravação automática (`auto_audio`/
|
|
866
|
+
* `auto_video`). Presente só nesses modos: é o que o SPA usa para explicar o
|
|
867
|
+
* que vai ser gravado e por quanto tempo ANTES do aceite.
|
|
868
|
+
*/
|
|
869
|
+
export interface IRoomRecordingAutoDto {
|
|
870
|
+
/** `auto_audio` ou `auto_video`; os outros modos não têm este bloco. */
|
|
871
|
+
mode: VirtualCareRecordingMode;
|
|
872
|
+
/**
|
|
873
|
+
* `true` em `auto_audio`. Hoje é INTENÇÃO declarada: o `POST /recordings` do
|
|
874
|
+
* provedor não expõe flag de áudio-only, então o arquivo sai A/V. O SPA usa o
|
|
875
|
+
* campo para o texto do aviso; quando o provedor ganhar a flag, só o adapter
|
|
876
|
+
* muda.
|
|
877
|
+
*/
|
|
878
|
+
audio_only: boolean;
|
|
879
|
+
/** Retenção que o texto mostrado ao paciente promete (`{{retention}}`, D32). */
|
|
880
|
+
retention_days: number;
|
|
881
|
+
/**
|
|
882
|
+
* Versão vigente do texto `recording` que o `POST /consents` tem de
|
|
883
|
+
* referenciar. `null` = não há texto publicado ⇒ sem aceite possível (D21) e
|
|
884
|
+
* a gravação automática NÃO acontece.
|
|
885
|
+
*/
|
|
886
|
+
terms_version: string | null;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* feat-160 F16 — política EFETIVA da agenda nesta sessão (`virtual_care` já
|
|
890
|
+
* com os defaults aplicados). É projeção de decisão, não de config gravada:
|
|
891
|
+
* agenda sem o bloco devolve os defaults.
|
|
892
|
+
*/
|
|
893
|
+
export interface IRoomSessionPolicyDto {
|
|
894
|
+
recording_mode: VirtualCareRecordingMode;
|
|
895
|
+
auto_admit: boolean;
|
|
896
|
+
identity: {
|
|
897
|
+
require_name: boolean;
|
|
898
|
+
require_birth_date: boolean;
|
|
899
|
+
skip: boolean;
|
|
900
|
+
};
|
|
901
|
+
/**
|
|
902
|
+
* Prazo duro da consulta. `end_at`/`warning_at` são `null` quando não há
|
|
903
|
+
* prazo (consulta não iniciada com `allow_late_end`), e `reason` diz qual
|
|
904
|
+
* limite venceu — o MESMO `reason` com que o sweep encerra.
|
|
905
|
+
*/
|
|
906
|
+
deadline: {
|
|
907
|
+
end_at: string | null;
|
|
908
|
+
warning_at: string | null;
|
|
909
|
+
reason: "scheduled_end" | "max_duration" | null;
|
|
910
|
+
};
|
|
837
911
|
}
|
|
838
912
|
/**
|
|
839
913
|
* `GET /api/room/v1/session` — estado SANITIZADO: sem tenant id, sem ids do
|
|
@@ -858,6 +932,12 @@ export interface IRoomSessionDto {
|
|
|
858
932
|
*/
|
|
859
933
|
identity_required_fields: {
|
|
860
934
|
birth_date: boolean;
|
|
935
|
+
/**
|
|
936
|
+
* feat-160 F16 — `virtual_care.identity.require_name`: a agenda pode exigir
|
|
937
|
+
* o nome também. OPCIONAL no contrato porque SPA anterior à F16 não o
|
|
938
|
+
* conhece e deve seguir pedindo só a data (comportamento de antes).
|
|
939
|
+
*/
|
|
940
|
+
name?: boolean;
|
|
861
941
|
};
|
|
862
942
|
/**
|
|
863
943
|
* Contador do lockout, lido do GRANT raiz — e a ÚNICA fonte dele: o erro do
|
|
@@ -870,6 +950,12 @@ export interface IRoomSessionDto {
|
|
|
870
950
|
};
|
|
871
951
|
recording_status: RecordingStatus;
|
|
872
952
|
recording: IRoomRecordingStateDto;
|
|
953
|
+
/**
|
|
954
|
+
* feat-160 F16 — o que a AGENDA decidiu (`calendar.virtual_care` resolvido
|
|
955
|
+
* com os defaults). OPCIONAL: aditivo, SPA que não o conheça mantém o
|
|
956
|
+
* comportamento pré-F16.
|
|
957
|
+
*/
|
|
958
|
+
policy?: IRoomSessionPolicyDto;
|
|
873
959
|
transcription_status: TranscriptionStatus;
|
|
874
960
|
/** Textos vigentes que ainda precisam de aceite antes do join. */
|
|
875
961
|
required_consents: IRoomConsentRefDto[];
|
|
@@ -936,11 +1022,93 @@ export interface ITeleconsultationArtifactDto {
|
|
|
936
1022
|
error_code?: string;
|
|
937
1023
|
created_at: string;
|
|
938
1024
|
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Modo da URL assinada de um artefato (feat-160 F21; D34).
|
|
1027
|
+
*
|
|
1028
|
+
* `attachment` é o default histórico (F8): o navegador BAIXA o arquivo.
|
|
1029
|
+
* `inline` existe para o `<video>` do painel fazer streaming por `Range` sem
|
|
1030
|
+
* baixar — e a única diferença técnica é NÃO emitir `Content-Disposition`.
|
|
1031
|
+
*/
|
|
1032
|
+
export declare const ArtifactDispositionEnum: {
|
|
1033
|
+
readonly Inline: "inline";
|
|
1034
|
+
readonly Attachment: "attachment";
|
|
1035
|
+
};
|
|
1036
|
+
export type ArtifactDisposition = (typeof ArtifactDispositionEnum)[keyof typeof ArtifactDispositionEnum];
|
|
1037
|
+
/**
|
|
1038
|
+
* Teto de validade da URL `inline` (feat-160 F21): 15 min. Playback casa com a
|
|
1039
|
+
* duração de uma consulta; download curto casa com o clique. É TETO, não
|
|
1040
|
+
* default — o use case aplica, e o adapter recusa acima dele.
|
|
1041
|
+
*/
|
|
1042
|
+
export declare const ARTIFACT_INLINE_SIGNED_URL_MAX_SECONDS = 900;
|
|
939
1043
|
/** `POST /v1/teleconsultations/:id/artifacts/:artifactId/signed-url` — URL ≤ 5 min; evento `artifact.accessed`. */
|
|
940
1044
|
export interface ISignedUrlResponseDto {
|
|
941
1045
|
ok: true;
|
|
942
1046
|
url: string;
|
|
943
1047
|
expires_at: string;
|
|
1048
|
+
/** Modo efetivamente aplicado (`attachment` quando o comando omite). */
|
|
1049
|
+
disposition?: ArtifactDisposition;
|
|
1050
|
+
}
|
|
1051
|
+
export type TranscriptSpeakerRole = "doctor" | "patient" | "unknown";
|
|
1052
|
+
export interface ITranscriptSpeakerDto {
|
|
1053
|
+
/** `opaque_custom_participant_id` que amarra a fala ao papel. */
|
|
1054
|
+
key: string;
|
|
1055
|
+
display_name: string;
|
|
1056
|
+
role: TranscriptSpeakerRole;
|
|
1057
|
+
}
|
|
1058
|
+
export interface ITranscriptEntryDto {
|
|
1059
|
+
index: number;
|
|
1060
|
+
speaker_key: string;
|
|
1061
|
+
start_ms: number;
|
|
1062
|
+
end_ms: number;
|
|
1063
|
+
text: string;
|
|
1064
|
+
overlapping?: boolean;
|
|
1065
|
+
}
|
|
1066
|
+
/** Corpo da transcrição de UM artefato (`segment`). */
|
|
1067
|
+
export interface ITranscriptDto {
|
|
1068
|
+
artifact_id: string;
|
|
1069
|
+
segment: number;
|
|
1070
|
+
language?: string;
|
|
1071
|
+
generated_at?: string;
|
|
1072
|
+
speakers: ITranscriptSpeakerDto[];
|
|
1073
|
+
entries: ITranscriptEntryDto[];
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* `GET /v1/teleconsultations/:id/artifacts/:artifactId/transcript` — envelope
|
|
1077
|
+
* da rota: `{ ok: true, ...ITranscriptDto }` (o DTO é espalhado, não aninhado).
|
|
1078
|
+
*/
|
|
1079
|
+
export interface ITranscriptResponseDto extends ITranscriptDto {
|
|
1080
|
+
ok: true;
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Um agendamento que TEM teleconsulta, e o que ela produziu. Id ausente do mapa
|
|
1084
|
+
* = "nunca virou teleconsulta" — é essa diferença que impede a tela de
|
|
1085
|
+
* desenhar três ícones apagados em toda linha comum.
|
|
1086
|
+
*/
|
|
1087
|
+
export interface ITeleconsultationBadgeDto {
|
|
1088
|
+
teleconsultation_id: string;
|
|
1089
|
+
status: TeleconsultationStatus;
|
|
1090
|
+
recording_audio: boolean;
|
|
1091
|
+
recording_video: boolean;
|
|
1092
|
+
transcript: boolean;
|
|
1093
|
+
}
|
|
1094
|
+
/** `GET /v1/appointments/teleconsultation-badges?ids=a,b,c` (máx. 50 ids). */
|
|
1095
|
+
export interface ITeleconsultationBadgesResponseDto {
|
|
1096
|
+
ok: true;
|
|
1097
|
+
/** Keyed por `appointment_id`. */
|
|
1098
|
+
items: Record<string, ITeleconsultationBadgeDto>;
|
|
1099
|
+
}
|
|
1100
|
+
/** Teto de ids por chamada; acima disso a rota responde 400. */
|
|
1101
|
+
export declare const TELECONSULTATION_BADGES_MAX_IDS = 50;
|
|
1102
|
+
/**
|
|
1103
|
+
* Corpo do `POST …/artifacts/:artifactId/signed-url` (feat-160 F21). O zod
|
|
1104
|
+
* espelho é `zArtifactSignedUrlCommandSchema`.
|
|
1105
|
+
*/
|
|
1106
|
+
export interface IArtifactSignedUrlCommand {
|
|
1107
|
+
disposition?: ArtifactDisposition;
|
|
1108
|
+
/** 30..900; o teto REAL depende do modo e é aplicado pelo backend. */
|
|
1109
|
+
ttl_seconds?: number;
|
|
1110
|
+
/** Renova a URL de um artefato já acessado (evento `artifact.accessed`). */
|
|
1111
|
+
refresh?: boolean;
|
|
944
1112
|
}
|
|
945
1113
|
export interface ITeleconsultationEventDto {
|
|
946
1114
|
id: string;
|
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TelemedicineErrorCode = exports.EntitlementAuditActionEnum = exports.TELECONSULTATION_PROVIDER_ONLY_FIELDS = exports.TranscriptionProviderEnum = exports.LegalTextStatusEnum = exports.WebhookEventStatusEnum = exports.TeleconsultationEventTypeEnum = exports.TeleconsultationEventSourceEnum = exports.TeleconsultationEventActorTypeEnum = exports.EndedByTypeEnum = exports.AccessSendChannelKindEnum = exports.AccessGrantStateEnum = exports.AccessGrantKindEnum = exports.ArtifactStatusEnum = exports.ArtifactTypeEnum = exports.ConsentActorTypeEnum = exports.ConsentDecisionEnum = exports.ConsentSubjectEnum = exports.TranscriptionStatusEnum = exports.RecordingStatusEnum = exports.IdentityLevelEnum = exports.PresenceStateEnum = exports.ParticipantStateEnum = exports.ParticipantRoleEnum = exports.TeleconsultationProviderEnum = exports.TeleconsultationModeEnum = exports.WaitingPolicyEnum = exports.TELECONSULTATION_TERMINAL_STATUSES = exports.TeleconsultationStatusEnum = exports.TELEMEDICINE_WINDOW_DEFAULTS = exports.TELEMEDICINE_JOIN_REMINDER_HANDLER = exports.TELEMEDICINE_JOIN_ACTION_TYPE = exports.EvoTelemedicinePermissions = void 0;
|
|
17
|
+
exports.TELECONSULTATION_BADGES_MAX_IDS = exports.ARTIFACT_INLINE_SIGNED_URL_MAX_SECONDS = exports.ArtifactDispositionEnum = exports.TelemedicineErrorCode = exports.EntitlementAuditActionEnum = exports.TELECONSULTATION_PROVIDER_ONLY_FIELDS = exports.TranscriptionProviderEnum = exports.LegalTextStatusEnum = exports.WebhookEventStatusEnum = exports.TeleconsultationEventTypeEnum = exports.TeleconsultationEventSourceEnum = exports.TeleconsultationEventActorTypeEnum = exports.EndedByTypeEnum = exports.AccessSendChannelKindEnum = exports.AccessGrantStateEnum = exports.AccessGrantKindEnum = exports.ArtifactStatusEnum = exports.ArtifactTypeEnum = exports.ConsentActorTypeEnum = exports.ConsentDecisionEnum = exports.ConsentSubjectEnum = exports.TranscriptionStatusEnum = exports.RecordingStatusEnum = exports.IdentityLevelEnum = exports.PresenceStateEnum = exports.ParticipantStateEnum = exports.ParticipantRoleEnum = exports.TeleconsultationProviderEnum = exports.TeleconsultationModeEnum = exports.WaitingPolicyEnum = exports.TELECONSULTATION_TERMINAL_STATUSES = exports.TeleconsultationStatusEnum = exports.TELEMEDICINE_WINDOW_DEFAULTS = exports.TELEMEDICINE_JOIN_REMINDER_HANDLER = exports.TELEMEDICINE_JOIN_ACTION_TYPE = exports.EvoTelemedicinePermissions = void 0;
|
|
18
18
|
__exportStar(require("./fb_collections"), exports);
|
|
19
19
|
// ======================================================
|
|
20
20
|
// evo-telemedicine (feat-160 — Telemedicina integrada)
|
|
@@ -277,8 +277,22 @@ exports.TeleconsultationEventTypeEnum = {
|
|
|
277
277
|
RecordingConsentRequested: "recording.consent_requested",
|
|
278
278
|
RecordingConsentAccepted: "recording.consent_accepted",
|
|
279
279
|
RecordingConsentDeclined: "recording.consent_declined",
|
|
280
|
+
/**
|
|
281
|
+
* feat-160 F15 — o paciente RECUSOU a gravação automática ANTES de entrar.
|
|
282
|
+
* Não é `recording.consent_declined`: aquela é a recusa de uma solicitação
|
|
283
|
+
* feita em sala (a consulta segue sem gravar); esta IMPEDE a entrada, porque
|
|
284
|
+
* em `auto_*` o aceite é condição do join (D21).
|
|
285
|
+
*/
|
|
286
|
+
RecordingConsentDeclinedPreJoin: "recording.consent_declined_pre_join",
|
|
280
287
|
RecordingConsentWithdrawn: "recording.consent_withdrawn",
|
|
281
288
|
RecordingStarted: "recording.started",
|
|
289
|
+
/**
|
|
290
|
+
* feat-160 F15 — gravação iniciada pela POLÍTICA da agenda (`auto_audio`/
|
|
291
|
+
* `auto_video`), não por comando do médico. Trilha própria porque
|
|
292
|
+
* `recording.started` sem um `recording.consent_requested` antes pareceria
|
|
293
|
+
* gravação sem solicitação na auditoria.
|
|
294
|
+
*/
|
|
295
|
+
RecordingAutoStarted: "recording.auto_started",
|
|
282
296
|
RecordingStopped: "recording.stopped",
|
|
283
297
|
RecordingFailed: "recording.failed",
|
|
284
298
|
TranscriptionQueued: "transcription.queued",
|
|
@@ -288,6 +302,15 @@ exports.TeleconsultationEventTypeEnum = {
|
|
|
288
302
|
ConsultationStarted: "consultation.started",
|
|
289
303
|
ConsultationReconnecting: "consultation.reconnecting",
|
|
290
304
|
ConsultationEnded: "consultation.ended",
|
|
305
|
+
/**
|
|
306
|
+
* feat-160 F18 — consulta encerrada e MEDIDA como "não contada" (paciente
|
|
307
|
+
* não atendeu, sem gravação elegível, franquia). Existe porque
|
|
308
|
+
* `usage_metered_at` é carimbado nos DOIS casos: sem este evento a
|
|
309
|
+
* reconciliação "quantas `ended` carimbadas × quantas linhas no BigQuery"
|
|
310
|
+
* acusaria diferença em toda consulta não contada, indistinguível de evento
|
|
311
|
+
* perdido.
|
|
312
|
+
*/
|
|
313
|
+
UsageSkipped: "teleconsultation.usage_skipped",
|
|
291
314
|
ArtifactAccessed: "artifact.accessed",
|
|
292
315
|
ArtifactDeleted: "artifact.deleted",
|
|
293
316
|
EntitlementDenied: "entitlement.denied",
|
|
@@ -385,3 +408,22 @@ exports.TelemedicineErrorCode = {
|
|
|
385
408
|
/** 400 — body/params inválidos. */
|
|
386
409
|
ValidationError: "VALIDATION_ERROR",
|
|
387
410
|
};
|
|
411
|
+
/**
|
|
412
|
+
* Modo da URL assinada de um artefato (feat-160 F21; D34).
|
|
413
|
+
*
|
|
414
|
+
* `attachment` é o default histórico (F8): o navegador BAIXA o arquivo.
|
|
415
|
+
* `inline` existe para o `<video>` do painel fazer streaming por `Range` sem
|
|
416
|
+
* baixar — e a única diferença técnica é NÃO emitir `Content-Disposition`.
|
|
417
|
+
*/
|
|
418
|
+
exports.ArtifactDispositionEnum = {
|
|
419
|
+
Inline: "inline",
|
|
420
|
+
Attachment: "attachment",
|
|
421
|
+
};
|
|
422
|
+
/**
|
|
423
|
+
* Teto de validade da URL `inline` (feat-160 F21): 15 min. Playback casa com a
|
|
424
|
+
* duração de uma consulta; download curto casa com o clique. É TETO, não
|
|
425
|
+
* default — o use case aplica, e o adapter recusa acima dele.
|
|
426
|
+
*/
|
|
427
|
+
exports.ARTIFACT_INLINE_SIGNED_URL_MAX_SECONDS = 900;
|
|
428
|
+
/** Teto de ids por chamada; acima disso a rota responde 400. */
|
|
429
|
+
exports.TELECONSULTATION_BADGES_MAX_IDS = 50;
|