evo360-types 1.3.448 → 1.3.454

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.
@@ -70,7 +70,18 @@ export interface IIntegrationsCredential extends IFireDoc {
70
70
  status: IntegrationCredentialStatus;
71
71
  last_used_at?: Date | null;
72
72
  }
73
- export type SyncWindowType = "hot" | "warm" | "recent_reconcile" | "cold";
73
+ /**
74
+ * `week` (feat-098) é diferente das outras em natureza: as demais derivam de
75
+ * `agora ± N dias`, ela é ANCORADA numa semana escolhida (domingo→sábado, no
76
+ * fuso do tenant). É a janela do read-through do calendário.
77
+ *
78
+ * Existir como tipo próprio importa porque o custo do sync é LINEAR na largura
79
+ * da janela — medido: 8 dias custam 29s de n8n, 22 dias custam 98s. Enquanto o
80
+ * read-through se disfarçava de `hot`, ele pedia o intervalo do FullCalendar
81
+ * (domingo→domingo, 8 dias: um dia a mais, e sobreposto com a semana seguinte,
82
+ * o que impedia cache por semana).
83
+ */
84
+ export type SyncWindowType = "hot" | "warm" | "recent_reconcile" | "cold" | "week";
74
85
  export interface ICoveredWindow {
75
86
  start: Date;
76
87
  end: Date;
@@ -108,6 +119,42 @@ export interface ISyncState extends IFireDoc {
108
119
  */
109
120
  hashes_by_bucket?: Record<string, ISyncedHashes>;
110
121
  last_coveredWindow?: ICoveredWindow | null;
122
+ /**
123
+ * Desfecho da última run (feat-097). Sem isto, `last_sync_at` é indistinguível
124
+ * entre "sincronizou tudo" e "sincronizou e deixou N itens para trás" — o
125
+ * carimbo é gravado nos dois casos, e quem lê passa a jurar um frescor que não
126
+ * existe.
127
+ */
128
+ last_status?: SyncRunStatus;
129
+ /** Quantos itens ficaram para trás na última run. */
130
+ last_error_count?: number;
131
+ /**
132
+ * Timestamp da última run LIMPA por janela. `last_run_by_window` responde
133
+ * apenas "alguém tentou"; é este que responde "a janela está confiável".
134
+ */
135
+ last_success_by_window?: Partial<Record<SyncWindowType, Date>>;
136
+ }
137
+ export interface ISyncWeekState {
138
+ /** Data ISO do domingo (fuso do tenant). Igual ao id do doc. */
139
+ week_key: string;
140
+ /** Quando esta semana foi varrida pela última vez. */
141
+ synced_at: Date;
142
+ /** Desfecho da run que a varreu. */
143
+ status: SyncRunStatus;
144
+ /**
145
+ * Itens desta semana que estão na nossa base e NÃO vieram no payload.
146
+ * Zero é a única afirmação positiva de integridade — é o que autoriza o
147
+ * chip verde na agenda.
148
+ */
149
+ missing_from_payload: number;
150
+ /** Alguém conferiu item a item no sistema de origem? */
151
+ verified: boolean;
152
+ /** Existe na origem e não veio: prova de payload incompleto. */
153
+ still_present_upstream?: number;
154
+ /** Qual run carimbou — para cruzar com `sync_runs` no BigQuery. */
155
+ run_id?: string;
156
+ /** Alimenta a TTL policy do Firestore. */
157
+ expires_at: Date;
111
158
  }
112
159
  export type SyncRunStatus = "success" | "partial" | "error";
113
160
  export interface ISyncRunEventError {
@@ -162,6 +209,13 @@ export interface ISyncConfig {
162
209
  warm?: ISyncWindowConfig;
163
210
  recent_reconcile?: ISyncWindowConfig;
164
211
  cold?: ISyncWindowConfig;
212
+ /**
213
+ * feat-098 — janela do read-through do calendário (domingo→sábado da semana
214
+ * exibida). `window_days` aqui é ignorado: a janela é ancorada na semana, não
215
+ * derivada de `agora ± N dias`. O campo útil é `enabled`, que permite desligar
216
+ * o read-through de um tenant sem tocar em código.
217
+ */
218
+ week?: ISyncWindowConfig;
165
219
  }
166
220
  export interface IMedCalendarIntegration {
167
221
  adapter_id: string;
@@ -152,7 +152,18 @@ export interface IIntegrationsCredential extends IFireDoc {
152
152
  // Path: /tenants/{t}/apps/evo-med/sync-states/{calendar_id}
153
153
  // ======================================================
154
154
 
155
- export type SyncWindowType = "hot" | "warm" | "recent_reconcile" | "cold";
155
+ /**
156
+ * `week` (feat-098) é diferente das outras em natureza: as demais derivam de
157
+ * `agora ± N dias`, ela é ANCORADA numa semana escolhida (domingo→sábado, no
158
+ * fuso do tenant). É a janela do read-through do calendário.
159
+ *
160
+ * Existir como tipo próprio importa porque o custo do sync é LINEAR na largura
161
+ * da janela — medido: 8 dias custam 29s de n8n, 22 dias custam 98s. Enquanto o
162
+ * read-through se disfarçava de `hot`, ele pedia o intervalo do FullCalendar
163
+ * (domingo→domingo, 8 dias: um dia a mais, e sobreposto com a semana seguinte,
164
+ * o que impedia cache por semana).
165
+ */
166
+ export type SyncWindowType = "hot" | "warm" | "recent_reconcile" | "cold" | "week";
156
167
 
157
168
  export interface ICoveredWindow {
158
169
  start: Date;
@@ -193,6 +204,59 @@ export interface ISyncState extends IFireDoc {
193
204
  */
194
205
  hashes_by_bucket?: Record<string, ISyncedHashes>;
195
206
  last_coveredWindow?: ICoveredWindow | null;
207
+ /**
208
+ * Desfecho da última run (feat-097). Sem isto, `last_sync_at` é indistinguível
209
+ * entre "sincronizou tudo" e "sincronizou e deixou N itens para trás" — o
210
+ * carimbo é gravado nos dois casos, e quem lê passa a jurar um frescor que não
211
+ * existe.
212
+ */
213
+ last_status?: SyncRunStatus;
214
+ /** Quantos itens ficaram para trás na última run. */
215
+ last_error_count?: number;
216
+ /**
217
+ * Timestamp da última run LIMPA por janela. `last_run_by_window` responde
218
+ * apenas "alguém tentou"; é este que responde "a janela está confiável".
219
+ */
220
+ last_success_by_window?: Partial<Record<SyncWindowType, Date>>;
221
+ }
222
+
223
+ // ======================================================
224
+ // Sync week state — 1 doc por SEMANA de cada calendar (feat-098).
225
+ // Path: /tenants/{t}/apps/evo-med/sync-states/{calendar_id}/weeks/{week_key}
226
+ //
227
+ // `week_key` = data ISO do DOMINGO da semana no fuso do tenant (ex.: 2026-07-26).
228
+ // Domingo e não ISO-week (que começa na segunda) porque é assim que a agenda é
229
+ // exibida — e usar a data em vez de "2026-W31" elimina a ambiguidade.
230
+ //
231
+ // Por que subcoleção e não um mapa dentro do `sync-states`:
232
+ // - `expires_at` + TTL policy nativa do Firestore dá o descarte automático,
233
+ // que é o que se quer de um cache — sem Redis, sem VPC connector, e sem
234
+ // perder o `onSnapshot` que mantém o chip da agenda vivo sem polling.
235
+ // - o FE assina SÓ a semana visível (~200 B) em vez do doc do calendar, que
236
+ // chega a 40 KB por causa de `hashes_by_bucket`.
237
+ // ======================================================
238
+
239
+ export interface ISyncWeekState {
240
+ /** Data ISO do domingo (fuso do tenant). Igual ao id do doc. */
241
+ week_key: string;
242
+ /** Quando esta semana foi varrida pela última vez. */
243
+ synced_at: Date;
244
+ /** Desfecho da run que a varreu. */
245
+ status: SyncRunStatus;
246
+ /**
247
+ * Itens desta semana que estão na nossa base e NÃO vieram no payload.
248
+ * Zero é a única afirmação positiva de integridade — é o que autoriza o
249
+ * chip verde na agenda.
250
+ */
251
+ missing_from_payload: number;
252
+ /** Alguém conferiu item a item no sistema de origem? */
253
+ verified: boolean;
254
+ /** Existe na origem e não veio: prova de payload incompleto. */
255
+ still_present_upstream?: number;
256
+ /** Qual run carimbou — para cruzar com `sync_runs` no BigQuery. */
257
+ run_id?: string;
258
+ /** Alimenta a TTL policy do Firestore. */
259
+ expires_at: Date;
196
260
  }
197
261
 
198
262
  // ======================================================
@@ -262,6 +326,13 @@ export interface ISyncConfig {
262
326
  warm?: ISyncWindowConfig;
263
327
  recent_reconcile?: ISyncWindowConfig;
264
328
  cold?: ISyncWindowConfig;
329
+ /**
330
+ * feat-098 — janela do read-through do calendário (domingo→sábado da semana
331
+ * exibida). `window_days` aqui é ignorado: a janela é ancorada na semana, não
332
+ * derivada de `agora ± N dias`. O campo útil é `enabled`, que permite desligar
333
+ * o read-through de um tenant sem tocar em código.
334
+ */
335
+ week?: ISyncWindowConfig;
265
336
  }
266
337
 
267
338
  export interface IMedCalendarIntegration {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evo360-types",
3
- "version": "1.3.448",
3
+ "version": "1.3.454",
4
4
  "description": "HREVO360 Shared Types",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",