tzmail 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -1,4873 +1,133 @@
1
- # Mikeprogrammer973/tzMail
1
+ # tzMail
2
2
 
3
- ## Primeiros passos e uso básico/Inicialização SMTP e primeiro fluxo funcional
3
+ A powerful and flexible TypeScript/Node.js email package built on top of Nodemailer, featuring a robust templating system with built-in themes, caching, and easy attachment management.
4
4
 
5
- # Primeiros passos e uso básico - Inicialização SMTP e primeiro fluxo funcional
5
+ ## Features
6
6
 
7
- ## Visão geral
7
+ - 🚀 **Singleton Factory**: Easy initialization and global access.
8
8
 
9
- Este fluxo mostra o caminho mínimo para sair da configuração SMTP e disparar o primeiro email funcional com `tzMail`. O ponto de partida é , onde `dotenv.config()` carrega as credenciais do ambiente, `SMTP_CONFIG` é montado com `IEmailConfig`, e `EmailFactory.initialize()` cria a instância única que passa a coordenar envio, templates e anexos.
9
+ - 🎨 **Themed Templates**: 5 built-in professional themes (Modern, Corporate, Minimal, Monokai, System).
10
10
 
11
- Na prática, o usuário do pacote monta o `SMTP_CONFIG`, obtém `TemplateService` a partir de `EmailFactory`, cria um template com `ThemeType` e `ITemplateConfig`, e envia o email por `emailFactory.sendEmail()`. Quando `template` é informado e `html` não existe, o HTML final é gerado por `TemplateService` e `TemplateBuilder`, e o envio real ocorre via Nodemailer no `EmailService`.
11
+ - 🌓 **Dark Mode Support**: All templates support light and dark variants.
12
12
 
13
- ## Arquitetura do fluxo mínimo
13
+ - **Performance**: In-memory template caching with TTL and version history.
14
14
 
15
- ```mermaid
16
- flowchart TB
17
- subgraph Boot [Bootstrap da demonstracao]
18
- Dotenv[dotenv config]
19
- Index[src index ts]
20
- Config[SMTP_CONFIG]
21
- Route[GET test]
22
- Dotenv --> Config
23
- Index --> Config
24
- Index --> Route
25
- end
15
+ - 📎 **Attachment Service**: Simple helpers for local files and buffers.
26
16
 
27
- subgraph Factory [EmailFactory]
28
- FactoryInit[EmailFactory initialize]
29
- FactoryInstance[Instancia unica]
30
- EmailSvc[EmailService]
31
- TemplateSvc[TemplateService]
32
- AttachSvc[AttachmentService]
33
- FactoryInit --> FactoryInstance
34
- FactoryInstance --> EmailSvc
35
- FactoryInstance --> TemplateSvc
36
- FactoryInstance --> AttachSvc
37
- end
17
+ - **Validation**: Built-in configuration validation for templates.
38
18
 
39
- subgraph Templating [Templates e renderizacao]
40
- TemplateFactory[TemplateFactory]
41
- TemplateBuilder[TemplateBuilder]
42
- ThemeSet[Temas]
43
- TemplateSvc --> TemplateFactory
44
- TemplateFactory --> ThemeSet
45
- TemplateFactory --> TemplateBuilder
46
- end
19
+ ## Installation
47
20
 
48
- subgraph SMTP [Envio SMTP]
49
- Nodemailer[Transporter Nodemailer]
50
- SMTPServer[Servidor SMTP]
51
- EmailSvc --> Nodemailer
52
- Nodemailer --> SMTPServer
53
- end
54
-
55
- Route --> AttachSvc
56
- Route --> FactoryInstance
57
- FactoryInstance --> TemplateSvc
58
- FactoryInstance --> EmailSvc
21
+ ```bash
22
+ npm install tzmail
23
+ # or
24
+ yarn add tzmail
59
25
  ```
60
26
 
61
- ## Configuração SMTP mínima com `IEmailConfig`
62
-
63
- ### `IEmailConfig`
64
-
65
- EmailFactory.initialize() é idempotente: a primeira chamada cria a instância e as chamadas seguintes retornam a mesma instância já configurada. Isso faz com que o SMTP_CONFIG definido no bootstrap seja o ponto único de inicialização do transporte SMTP.
66
-
67
- *`src/core/interfaces/email.interface.ts`*
68
-
69
- `IEmailConfig` define tudo o que `EmailFactory` precisa para montar o `transporter` do Nodemailer e repassar o remetente padrão para `EmailService`.
70
-
71
- | Propriedade | Tipo | Descrição |
72
- | --- | --- | --- |
73
- | `host` | `string` | Host SMTP usado por `nodemailer.createTransport`. |
74
- | `port` | `number` | Porta do servidor SMTP. |
75
- | `secure` | `boolean` | Indica uso de conexão segura no transporte. |
76
- | `auth.user` | `string` | Usuário SMTP lido do ambiente em . |
77
- | `auth.pass` | `string` | Senha SMTP lida do ambiente em . |
78
- | `defaultFrom?` | `string` | Remetente padrão aplicado por `EmailService` quando `options.from` não é informado. |
79
-
80
-
81
- ### Bootstrap do SMTP em
82
-
83
- *`src/index.ts`*
27
+ ## Quick Start
84
28
 
85
- O exemplo de demonstração monta o objeto SMTP com credenciais vindas de variáveis de ambiente e um `defaultFrom` fixo.
29
+ ### 1. Initialize the Factory
86
30
 
87
- ```ts
88
- dotenv.config();
31
+ ```typescript
32
+ import { EmailFactory } from 'tzmail';
89
33
 
90
- const SMTP_CONFIG = {
91
- host: 'smtp.gmail.com',
34
+ const smtpConfig = {
35
+ host: 'smtp.example.com',
92
36
  port: 587,
93
- secure: false,
94
37
  auth: {
95
- user: process.env.SMTP_USER!,
96
- pass: process.env.SMTP_PASS!
38
+ user: 'user@example.com',
39
+ pass: 'password'
97
40
  },
98
- defaultFrom: 'LyraX Corp <lyrax.com@gmail.com>'
41
+ defaultFrom: 'My App <noreply@myapp.com>'
99
42
  };
100
43
 
101
- const emailFactory = EmailFactory.initialize(SMTP_CONFIG);
44
+ const emailFactory = EmailFactory.initialize(smtpConfig);
102
45
  ```
103
46
 
104
- As credenciais `SMTP_USER` e `SMTP_PASS` são lidas antes da criação da fábrica. O valor de `defaultFrom` é repassado para `EmailService`, que o usa como remetente quando `options.from` não é enviado em `sendEmail()`.
105
-
106
- ### Relação entre `EmailFactory`, `TemplateService` e `EmailService`
107
-
108
- - `EmailFactory` é a fachada de entrada do fluxo.
109
- - `EmailFactory.initialize()` cria:- `EmailService`, com o `transporter` do Nodemailer e `defaultFrom`.
110
- - `TemplateService`, com as opções de template.
111
- - `AttachmentService`, para anexos.
112
- - `EmailFactory.getTemplateService()` expõe `TemplateService` para criação e renderização de templates.
113
- - `EmailFactory.sendEmail()` delega o envio para `EmailService.send()`.
114
- - `EmailService.send()` resolve `html` diretamente ou renderiza `options.template` quando `html` não foi informado.
115
-
116
- ## Contratos de email e anexo
117
-
118
- ### `IEmailOptions`
119
-
120
- *`src/core/interfaces/email.interface.ts`*
121
-
122
- `IEmailOptions` representa os dados de envio recebidos por `EmailService.send()` e por `EmailFactory.sendEmail()`.
123
-
124
- | Propriedade | Tipo | Descrição |
125
- | --- | --- | --- |
126
- | `to` | `string` | `string[]` | Destinatário único ou lista de destinatários. |
127
- | `subject` | `string` | Assunto do email. |
128
- | `from?` | `string` | Remetente opcional que sobrescreve `defaultFrom`. |
129
- | `cc?` | `string` | `string[]` | Cópia carbono opcional. |
130
- | `bcc?` | `string` | `string[]` | Cópia oculta opcional. |
131
- | `attachments?` | `IAttachment[]` | Lista de anexos em formato Nodemailer. |
132
- | `template?` | `ITemplate` | Template a ser renderizado quando `html` não existir. |
133
- | `text?` | `string` | Corpo textual opcional. |
134
- | `html?` | `string` | HTML final; tem prioridade sobre `template`. |
135
-
136
-
137
- ### `IAttachment`
138
-
139
- *`src/core/interfaces/email.interface.ts`*
140
-
141
- `IAttachment` é o formato usado em `attachments` por `EmailService.send()` e pelas saídas de `AttachmentService`.
142
-
143
- | Propriedade | Tipo | Descrição |
144
- | --- | --- | --- |
145
- | `filename` | `string` | Nome exibido do arquivo anexado. |
146
- | `content?` | `string` | Buffer | Conteúdo em memória do anexo. |
147
- | `path?` | `string` | Caminho local do arquivo anexado. |
148
- | `contentType?` | `string` | MIME type opcional. |
149
- | `cid?` | `string` | Content ID para uso em imagens embutidas. |
150
-
151
-
152
- ### `EmailService`
153
-
154
- *`src/services/email.service.ts`*
155
-
156
- `EmailService` encapsula o envio real e monta `mailOptions` a partir de `IEmailOptions`.
157
-
158
- #### Propriedades
159
-
160
- | Propriedade | Tipo | Descrição |
161
- | --- | --- | --- |
162
- | `transporter` | `Transporter` | Instância Nodemailer usada em `sendMail()`. |
163
- | `defaultFrom` | `string` | `undefined` | Remetente padrão aplicado quando `options.from` não existe. |
164
-
165
-
166
- #### Dependências do construtor
167
-
168
- | Tipo | Descrição |
169
- | --- | --- |
170
- | `Transporter` | Transporte Nodemailer criado por `EmailFactory`. |
171
- | `string` | `defaultFrom` opcional recebido de `IEmailConfig`. |
172
-
173
-
174
- #### Métodos públicos
175
-
176
- | Método | Descrição |
177
- | --- | --- |
178
- | `send` | Monta `mailOptions`, renderiza `template` quando necessário e chama `transporter.sendMail()`. |
179
-
180
-
181
- #### Comportamento do envio
182
-
183
- - `from` usa `options.from` quando existe; caso contrário, usa `defaultFrom`.
184
- - `to` aceita `string[]` e converte para uma string separada por vírgula.
185
- - `html` tem prioridade absoluta.
186
- - Quando `html` não é informado e `template` existe, `template.render(options)` gera o HTML.
187
- - `attachments`, `cc`, `bcc`, `subject` e `text` são repassados ao `transporter`.
188
-
189
- #### Resultado retornado
190
-
191
- - Sucesso: `{ success: true, messageId, response }`
192
- - Falha: `{ success: false, error }`
193
-
194
- ### `AttachmentService`
195
-
196
- *`src/services/attachment.service.ts`*
197
-
198
- `AttachmentService` transforma arquivos locais ou buffers em `IAttachment` prontos para Nodemailer.
199
-
200
- #### Propriedades
201
-
202
- Não há campos de instância declarados.
203
-
204
- #### Dependências do construtor
205
-
206
- Não possui construtor explícito.
207
-
208
- #### Métodos públicos
209
-
210
- | Método | Descrição |
211
- | --- | --- |
212
- | `addFromPath` | Valida um caminho local e retorna um `IAttachment` com `path`. |
213
- | `addFromBuffer` | Retorna um `IAttachment` com `content` a partir de um `Buffer`. |
214
- | `addFromUrl` | Lança erro de método não implementado. |
215
-
216
-
217
- #### Comportamento de `addFromPath`
218
-
219
- addFromUrl() sempre lança Error('Method not implemented yet'). O fluxo de demonstração que usa anexos só funciona com addFromPath() ou addFromBuffer().
220
-
221
- - Faz `fs.promises.stat(filePath)`.
222
- - Exige que o caminho seja um arquivo.
223
- - Usa `path.basename(filePath)` quando `options.filename` não é informado.
224
- - Retorna `path`, `contentType` e `cid` quando informados.
225
-
226
- ## Contratos e renderização de template
227
-
228
- ### `ITemplate`
229
-
230
- *`src/core/interfaces/template.interface.ts`*
231
-
232
- `ITemplate` representa o objeto de template criado por `TemplateFactory` e consumido por `EmailService`.
233
-
234
- | Propriedade | Tipo | Descrição |
235
- | --- | --- | --- |
236
- | `name` | `string` | Nome do template, como `modern_light`. |
237
- | `theme` | `ThemeType` | Tema associado ao template. |
238
- | `variant` | `'light'` | `'dark'` | Variação visual do template. |
239
- | `config` | `ITemplateConfig` | Configuração estrutural do template. |
240
-
241
-
242
- #### Métodos
243
-
244
- | Método | Descrição |
245
- | --- | --- |
246
- | `render` | Gera o HTML final a partir dos dados recebidos. |
247
-
248
-
249
- ### `ITemplateConfig`
250
-
251
- *`src/core/interfaces/template.interface.ts`*
252
-
253
- | Propriedade | Tipo | Descrição |
254
- | --- | --- | --- |
255
- | `header?` | `IHeaderConfig` | Configuração do cabeçalho. |
256
- | `body?` | `IBodyConfig` | Configuração do corpo. |
257
- | `footer?` | `IFooterConfig` | Configuração do rodapé. |
258
- | `layout?` | `'full'` `'minimal'` | Layout geral do email. |
259
- | `spacing?` | `'compact'` `'normal'` `'relaxed'` | Espaçamento global. |
260
- | `borderRadius?` | `'none'` `'small'` `'medium'` `'large'` | Raio de borda do container. |
261
-
262
-
263
- ### `IBodyConfig`
264
-
265
- *`src/core/interfaces/template.interface.ts`*
266
-
267
- | Propriedade | Tipo | Descrição |
268
- | --- | --- | --- |
269
- | `title?` | `string` | Título principal do corpo. |
270
- | `message?` | `string` | Mensagem principal do corpo. |
271
- | `content?` | `string` | HTML do corpo quando já pronto. |
272
- | `buttonText?` | `string` | Texto do botão. |
273
- | `buttonUrl?` | `string` | URL do botão. |
274
- | `buttonVariant?` | `'primary'` `'secondary'` `'success'` `'danger'` | Variante visual do botão. |
275
- | `alignment?` | `'left'` `'center'` `'right'` | Alinhamento do conteúdo. |
276
- | `backgroundColor?` | `string` | Cor de fundo do bloco. |
277
- | `textColor?` | `string` | Cor do texto do bloco. |
278
- | `fontSize?` | `number` | Tamanho base da fonte em pixels. |
279
-
280
-
281
- ### `IHeaderConfig`
282
-
283
- *`src/core/interfaces/template.interface.ts`*
284
-
285
- | Propriedade | Tipo | Descrição |
286
- | --- | --- | --- |
287
- | `show` | `boolean` | Define se o cabeçalho será renderizado. |
288
- | `logo?` | `{ type: 'text' 'image'; text?; imageUrl?; alt?; size? }` | Dados do logo textual ou em imagem. |
289
- | `backgroundColor?` | `string` | Cor de fundo do cabeçalho. |
290
- | `textColor?` | `string` | Cor do texto do cabeçalho. |
291
-
292
-
293
- ### `IFooterConfig`
294
-
295
- *`src/core/interfaces/template.interface.ts`*
296
-
297
- | Propriedade | Tipo | Descrição |
298
- | --- | --- | --- |
299
- | `show` | `boolean` | Define se o rodapé será renderizado. |
300
- | `links?` | `Array<{ text: string; url: string }>` | Links do rodapé. |
301
- | `socialLinks?` | `Array<{ platform: 'facebook' 'twitter' 'linkedin' 'github'; url: string }>` | Links sociais com ícones. |
302
- | `copyrightText?` | `string` | Texto de copyright. |
303
- | `unsubscribeText?` | `string` | Texto do link de cancelamento. |
304
- | `backgroundColor?` | `string` | Cor de fundo do rodapé. |
305
- | `textColor?` | `string` | Cor do texto do rodapé. |
306
-
307
-
308
- ### `TemplateFactory`
309
-
310
- *`src/factories/template-factory.ts`*
311
-
312
- `TemplateFactory` transforma `ThemeType`, variante e configuração em um `ITemplate` com `render()`.
313
-
314
- #### Propriedades
315
-
316
- | Propriedade | Tipo | Descrição |
317
- | --- | --- | --- |
318
- | `themes` | `Map<ThemeType, ITheme>` | Catálogo estático de temas disponíveis. |
319
-
320
-
321
- #### Métodos públicos
322
-
323
- | Método | Descrição |
324
- | --- | --- |
325
- | `createTemplate` | Cria um template com `name`, `theme`, `variant`, `config` e `render()`. |
326
- | `getTheme` | Recupera a instância do tema pelo `ThemeType`. |
327
- | `listThemes` | Lista os temas disponíveis. |
328
- | `getThemeInfo` | Retorna nome, descrição e features do tema. |
329
-
330
-
331
- #### Como `createTemplate` monta o HTML
332
-
333
- - Lê `data.template.config.body`.
334
- - Usa `body.content` quando existe.
335
- - Caso contrário, monta um bloco padrão com:- `title` ou `Hello!`
336
- - `message` ou `This is an email generated with tzMail.`
337
- - Usa `TemplateBuilder` para montar:- cabeçalho com `buildHeader()`
338
- - corpo com `buildBody()`
339
- - botão opcional com `buildButton()`
340
- - rodapé com `buildFooter()`
341
- - HTML final com `build()`
342
-
343
- ### `TemplateBuilder`
344
-
345
- *`src/templates/base/template-builder.ts`*
346
-
347
- `TemplateBuilder` constrói a estrutura HTML final e aplica variações específicas de tema nas seções de header, body, button e footer.
348
-
349
- #### Propriedades
350
-
351
- | Propriedade | Tipo | Descrição |
352
- | --- | --- | --- |
353
- | `template` | `string` | HTML acumulado durante a construção. |
354
- | `theme` | `ITheme` | Tema ativo na renderização. |
355
- | `config` | `ITemplateConfig` | Configuração do template. |
356
- | `variant` | `'light'` `'dark'` | Variante de cor usada na renderização. |
357
-
358
-
359
- #### Dependências do construtor
360
-
361
- | Tipo | Descrição |
362
- | --- | --- |
363
- | `ITheme` | Tema concreto, como `ModernTheme` ou `MinimalTheme`. |
364
- | `ITemplateConfig` | Configuração de header, body, footer e layout. |
365
- | `'light'` `'dark'` | Variante do template. |
366
-
367
-
368
- #### Métodos públicos
369
-
370
- | Método | Descrição |
371
- | --- | --- |
372
- | `buildHeader` | Adiciona o bloco de cabeçalho ao HTML. |
373
- | `buildBody` | Adiciona o bloco principal do corpo ao HTML. |
374
- | `buildButton` | Adiciona o botão de CTA ao HTML. |
375
- | `buildFooter` | Adiciona o rodapé ao HTML. |
376
- | `build` | Finaliza o documento HTML completo. |
377
-
378
-
379
- #### Comportamento relevante
380
-
381
- - `buildHeader()` retorna cedo quando `config.header.show` é falso.
382
- - `buildBody()` ajusta estilos e processa conteúdo conforme o tema.
383
- - `buildButton()` usa `primary` ou `secondary` e aplica estilos específicos por tema.
384
- - `buildFooter()` inclui `links`, `socialLinks`, `copyrightText` e `unsubscribeText`.
385
- - `build()` define o container central e o `<html>` completo.
386
-
387
- ### `TemplateService`
388
-
389
- *`src/services/template.service.ts`*
390
-
391
- `TemplateService` é a camada central de criação, cache, histórico, renderização e pré-visualização de templates.
392
-
393
- #### Tipos internos
394
-
395
- ##### `TemplateCache`
396
-
397
- *`src/services/template.service.ts`*
398
-
399
- | Propriedade | Tipo | Descrição |
400
- | --- | --- | --- |
401
- | `template` | `ITemplate` | Template armazenado no cache. |
402
- | `createdAt` | `Date` | Data de criação do cache entry. |
403
- | `expiresAt` | `Date` | Data de expiração. |
404
- | `hits` | `number` | Quantidade de acessos ao cache. |
405
-
406
-
407
- ##### `TemplateOptions`
408
-
409
- *`src/services/template.service.ts`*
410
-
411
- | Propriedade | Tipo | Descrição |
412
- | --- | --- | --- |
413
- | `cache?` | `boolean` | Ativa ou desativa o cache. |
414
- | `cacheTTL?` | `number` | TTL em segundos. |
415
- | `validateConfig?` | `boolean` | Ativa validação da configuração. |
416
- | `minify?` | `boolean` | Ativa minificação do HTML. |
417
- | `preview?` | `boolean` | Marca o render como pré-visualização. |
418
-
419
-
420
- #### Propriedades
421
-
422
- | Propriedade | Tipo | Descrição |
423
- | --- | --- | --- |
424
- | `templateCache` | `Map<string, TemplateCache>` | Cache in-memory por template. |
425
- | `defaultTTL` | `number` | TTL padrão em segundos. |
426
- | `templateHistory` | `Map<string, ITemplate[]>` | Histórico de versões por template. |
427
- | `options` | `TemplateOptions` | Configuração global do serviço. |
428
-
429
-
430
- #### Dependências do construtor
431
-
432
- | Tipo | Descrição |
433
- | --- | --- |
434
- | `TemplateOptions` | Opções de cache, validação, minificação e preview. |
435
-
436
-
437
- #### Métodos públicos
438
-
439
- | Método | Descrição |
440
- | --- | --- |
441
- | `createTemplate` | Cria ou reaproveita um template no cache. |
442
- | `cloneTemplate` | Clona um template com modificações parciais. |
443
- | `renderTemplate` | Renderiza um template e adiciona metadados `_meta`. |
444
- | `previewTemplate` | Cria e renderiza um template sem persistir no cache. |
445
- | `getThemeInfo` | Retorna informações detalhadas de tema e configuração padrão. |
446
- | `listThemes` | Lista os `ThemeType` disponíveis. |
447
- | `getTemplateStats` | Retorna métricas do cache e do histórico. |
448
- | `clearCache` | Remove cache globalmente ou por tema. |
449
- | `getTemplateHistory` | Retorna o histórico de versões de um template. |
450
- | `restoreTemplateVersion` | Reconstrói uma versão anterior. |
451
- | `preloadTemplates` | Pré-carrega templates no cache. |
452
- | `exportTemplate` | Exporta o template para JSON. |
453
- | `importTemplate` | Importa um template a partir de JSON. |
454
- | `generateExampleTemplate` | Gera um template de demonstração. |
455
- | `isValidTemplate` | Valida a estrutura de um objeto template. |
456
- | `getTemplateDetails` | Retorna template atual, histórico, cache e uso. |
457
-
458
-
459
- #### Fluxo de estado e cache
460
-
461
- - `createTemplate()` gera um `templateId` com `themeType`, `variant` e hash do JSON da config.
462
- - Se o cache estiver ativo e existir entrada válida, incrementa `hits` e retorna o template cacheado.
463
- - Se não houver cache, cria o template por `TemplateFactory.createTemplate()`.
464
- - O template é enriquecido com métodos dinâmicos:- `getVersion()`
465
- - `getId()`
466
- - `clone()`
467
- - O histórico mantém as últimas 10 versões por `templateId`.
468
- - `cleanExpiredCache()` remove entradas vencidas a cada hora via `setInterval()`.
469
-
470
- #### Validação de configuração
471
-
472
- `validateTemplateConfig()` agrega erros e lança uma única exceção quando encontra problemas em:
473
-
474
- - logo de imagem sem `imageUrl`
475
- - logo textual sem `text`
476
- - links de footer sem `text` ou `url`
477
- - `layout` fora de `full` ou `minimal`
478
- - `spacing` fora de `compact`, `normal` ou `relaxed`
479
- - `borderRadius` fora de `none`, `small`, `medium` ou `large`
480
-
481
- #### Metadados adicionados no render
482
-
483
- `renderTemplate()` injeta `_meta` no payload:
484
-
485
- - `isPreview`
486
- - `renderDate`
487
- - `templateName`
488
- - `theme`
489
- - `variant`
490
-
491
- ### `ThemeType`
492
-
493
- *`src/core/enums/theme.enum.ts`*
494
-
495
- `ThemeType` define os temas usados em `TemplateFactory` e `TemplateService`.
496
-
497
- Valores: `SYSTEM`, `MONOKAI`, `MODERN`, `CORPORATE`, `MINIMAL`.
498
-
499
- ### `TemplatePart`
500
-
501
- *`src/core/enums/template-part.enum.ts`*
502
-
503
- `TemplatePart` descreve as partes estruturais do email renderizado.
504
-
505
- Valores: `HEADER`, `BODY`, `FOOTER`, `BUTTON`.
506
-
507
- ## Temas disponíveis
508
-
509
- ### `ITheme`
510
-
511
- *`src/templates/themes/theme.interface.ts`*
512
-
513
- | Propriedade | Tipo | Descrição |
514
- | --- | --- | --- |
515
- | `id` | `ThemeType` | Identificador do tema. |
516
- | `name` | `string` | Nome humano do tema. |
517
- | `light` | `IThemeColors` | Paleta para variante clara. |
518
- | `dark` | `IThemeColors` | Paleta para variante escura. |
519
- | `typography` | `ITypography` | Tipografia do tema. |
520
- | `spacing` | `ISpacing` | Escala de espaçamento do tema. |
521
-
522
-
523
- ### `IThemeColors`
524
-
525
- *`src/templates/themes/theme.interface.ts`*
526
-
527
- | Propriedade | Tipo | Descrição |
528
- | --- | --- | --- |
529
- | `primary` | `string` | Cor principal. |
530
- | `secondary` | `string` | Cor secundária. |
531
- | `background` | `string` | Cor de fundo. |
532
- | `text` | `string` | Cor de texto principal. |
533
- | `textMuted` | `string` | Cor de texto secundário. |
534
- | `border` | `string` | Cor de borda. |
535
- | `success` | `string` | Cor de sucesso. |
536
- | `error` | `string` | Cor de erro. |
537
- | `warning` | `string` | Cor de aviso. |
538
-
539
-
540
- ### `ITypography`
541
-
542
- *`src/templates/themes/theme.interface.ts`*
543
-
544
- | Propriedade | Tipo | Descrição |
545
- | --- | --- | --- |
546
- | `fontFamily` | `string` | Família tipográfica base. |
547
- | `fontSizes` | `{ small: string; medium: string; large: string; xlarge: string }` | Escala de tamanhos. |
548
- | `fontWeights` | `{ normal: number; medium: number; bold: number }` | Pesos tipográficos. |
549
-
550
-
551
- ### `ISpacing`
552
-
553
- *`src/templates/themes/theme.interface.ts`*
554
-
555
- | Propriedade | Tipo | Descrição |
556
- | --- | --- | --- |
557
- | `xs` | `string` | Espaçamento extra pequeno. |
558
- | `sm` | `string` | Espaçamento pequeno. |
559
- | `md` | `string` | Espaçamento médio. |
560
- | `lg` | `string` | Espaçamento grande. |
561
- | `xl` | `string` | Espaçamento extra grande. |
562
-
563
-
564
- ### `SystemTheme`
565
-
566
- *`src/templates/themes/system.theme.ts`*
567
-
568
- #### Propriedades
569
-
570
- | Propriedade | Tipo | Descrição |
571
- | --- | --- | --- |
572
- | `id` | `ThemeType` | Valor `SYSTEM`. |
573
- | `name` | `string` | Nome `System`. |
574
- | `light` | `{ primary; secondary; background; text; textMuted; border; success; error; warning }` | Paleta clara. |
575
- | `dark` | `{ primary; secondary; background; text; textMuted; border; success; error; warning }` | Paleta escura. |
576
- | `typography` | `{ fontFamily; fontSizes; fontWeights }` | Tipografia base do tema. |
577
- | `spacing` | `{ xs; sm; md; lg; xl }` | Escala de espaçamento. |
578
-
579
-
580
- ### `MonokaiTheme`
581
-
582
- *`src/templates/themes/monokai.theme.ts`*
583
-
584
- #### Propriedades
585
-
586
- | Propriedade | Tipo | Descrição |
587
- | --- | --- | --- |
588
- | `id` | `ThemeType` | Valor `MONOKAI`. |
589
- | `name` | `string` | Nome `Monokai`. |
590
- | `light` | `IThemeColors` | Paleta clara com acentos fortes. |
591
- | `dark` | `IThemeColors` | Paleta escura Monokai. |
592
- | `typography` | `ITypography` | Tipografia monoespaçada. |
593
- | `spacing` | `ISpacing` | Escala compacta. |
594
- | `codeHighlight` | `{ comment; keyword; string; number; function; variable }` | Cores de destaque para blocos de código. |
595
- | `borderStyle` | `{ radius: string; width: string; style: string }` | Estilo de borda do tema. |
596
- | `effects` | `{ glow; shadow; transition }` | Efeitos visuais do tema. |
597
-
598
-
599
- ### `ModernTheme`
600
-
601
- *`src/templates/themes/modern.theme.ts`*
602
-
603
- #### Propriedades
604
-
605
- | Propriedade | Tipo | Descrição |
606
- | --- | --- | --- |
607
- | `id` | `ThemeType` | Valor `MODERN`. |
608
- | `name` | `string` | Nome `Modern`. |
609
- | `light` | `IThemeColors` | Paleta clara contemporânea. |
610
- | `dark` | `IThemeColors` | Paleta escura contemporânea. |
611
- | `typography` | `ITypography` | Tipografia moderna. |
612
- | `spacing` | `ISpacing` | Escala de espaçamento. |
613
- | `gradients` | `{ primary; secondary; accent; dark; light }` | Gradientes usados pelo builder. |
614
- | `borderStyle` | `{ radius: { small; medium; large; full }; width: string; style: string }` | Raio e borda do tema. |
615
- | `glassmorphism` | `{ light; dark; blur }` | Cores e blur para efeito glass. |
616
- | `animations` | `{ hover; fade; slide }` | Transições do tema. |
617
-
618
-
619
- ### `CorporateTheme`
620
-
621
- *`src/templates/themes/corporate.theme.ts`*
622
-
623
- #### Propriedades
624
-
625
- | Propriedade | Tipo | Descrição |
626
- | --- | --- | --- |
627
- | `id` | `ThemeType` | Valor `CORPORATE`. |
628
- | `name` | `string` | Nome `Corporate`. |
629
- | `light` | `IThemeColors` | Paleta clara corporativa. |
630
- | `dark` | `IThemeColors` | Paleta escura corporativa. |
631
- | `typography` | `ITypography` | Tipografia serifada. |
632
- | `spacing` | `ISpacing` | Escala de espaçamento. |
633
- | `corporateColors` | `{ gold; silver; bronze; navy; charcoal; ivory }` | Paleta de apoio corporativa. |
634
- | `borderStyle` | `{ radius: { small; medium; large; pill }; width: { thin; medium; thick }; style: string }` | Bordas do tema. |
635
- | `elevation` | `{ shadow; card; modal; hover }` | Sombras e elevação. |
636
- | `branding` | `{ logoSize; letterSpacing; textTransform }` | Regras de marca. |
637
- | `layout` | `{ maxWidth; contentWidth; sidebarWidth; headerHeight; footerHeight }` | Medidas de layout. |
638
-
639
-
640
- ### `MinimalTheme`
641
-
642
- *`src/templates/themes/minimal.theme.ts`*
643
-
644
- #### Propriedades
645
-
646
- | Propriedade | Tipo | Descrição |
647
- | --- | --- | --- |
648
- | `id` | `ThemeType` | Valor `MINIMAL`. |
649
- | `name` | `string` | Nome `Minimal`. |
650
- | `light` | `IThemeColors` | Paleta clara minimalista. |
651
- | `dark` | `IThemeColors` | Paleta escura minimalista. |
652
- | `typography` | `ITypography` | Tipografia sem serifa. |
653
- | `spacing` | `ISpacing` | Escala expandida. |
654
- | `minimalColors` | `{ white; black; gray100; gray200; gray300; gray400; gray500; gray600; gray700; gray800; gray900 }` | Paleta neutra. |
655
- | `borderStyle` | `{ radius: { none; small; medium; large; full }; width: { thin; medium }; style: string }` | Bordas minimalistas. |
656
- | `effects` | `{ shadow; transition; opacity }` | Efeitos suaves e opacidade. |
657
- | `layout` | `{ maxWidth; contentWidth; spacingMultiplier; lineHeight; paragraphSpacing }` | Regras de layout. |
658
- | `designSystem` | `{ grid; breakpoints; zIndex }` | Grid e breakpoints do tema. |
659
-
660
-
661
- ## Fábrica de email e inicialização do fluxo
662
-
663
- ### `EmailFactory`
664
-
665
- *`src/factories/email-factory.ts`*
666
-
667
- `EmailFactory` centraliza a criação do transporte SMTP, o serviço de email, o serviço de templates e o serviço de anexos. A classe funciona como singleton global do pacote.
668
-
669
- #### Propriedades
670
-
671
- | Propriedade | Tipo | Descrição |
672
- | --- | --- | --- |
673
- | `instance` | `EmailFactory` `undefined` | Instância única mantida pela fábrica. |
674
- | `emailService` | `EmailService` | Serviço de envio usado por `sendEmail()`. |
675
- | `templateService` | `TemplateService` | Serviço de criação e renderização de templates. |
676
- | `attachmentService` | `AttachmentService` | Serviço de anexos criado junto com a fábrica. |
677
-
678
-
679
- #### Dependências do construtor
680
-
681
- | Tipo | Descrição |
682
- | --- | --- |
683
- | `IEmailConfig` | Configuração SMTP e `defaultFrom`. |
684
- | `any` | `templateOptions` repassado para `TemplateService`. |
685
-
686
-
687
- #### Métodos públicos
688
-
689
- | Método | Descrição |
690
- | --- | --- |
691
- | `initialize` | Cria a instância única com SMTP e serviços internos. |
692
- | `getInstance` | Retorna a instância criada ou lança erro se não houver inicialização. |
693
- | `sendEmail` | Encaminha o envio para `EmailService.send()`. |
694
- | `getTemplateService` | Expõe a instância de `TemplateService`. |
695
- | `getAttachmentService` | Expõe a instância de `AttachmentService`. |
696
- | `previewTemplate` | Delegada para `TemplateService.previewTemplate()`. |
697
- | `getThemeInfo` | Delegada para `TemplateService.getThemeInfo()`. |
698
- | `listThemes` | Delegada para `TemplateService.listThemes()`. |
699
- | `getTemplateStats` | Delegada para `TemplateService.getTemplateStats()`. |
700
-
701
-
702
- #### Relação de uso no bootstrap
703
-
704
- 1. `EmailFactory.initialize(SMTP_CONFIG)` cria o `transporter` com `nodemailer.createTransport(config)`.
705
- 2. O `EmailService` recebe o `transporter` e `config.defaultFrom`.
706
- 3. O `TemplateService` é criado com `templateOptions` quando fornecidas.
707
- 4. O `AttachmentService` fica disponível para montagem de anexos.
708
- 5. A aplicação recupera `templateService` com `getTemplateService()` e gera os templates usados no primeiro envio.
709
-
710
- #### Nota sobre reconfiguração
711
-
712
- ## Fluxo funcional do primeiro email
47
+ ### 2. Create and Send an Email
713
48
 
714
- ### Funções de demonstração em
715
-
716
- A fábrica não recria o transporte após a primeira inicialização. Isso significa que mudanças em SMTP_CONFIG só têm efeito antes da primeira chamada de initialize().
717
-
718
- *`src/index.ts`*
719
-
720
- Estas funções mostram como a fábrica é consumida no exemplo de servidor Express.
721
-
722
- | Função | Descrição |
723
- | --- | --- |
724
- | `sendWelcomeEmail` | Envia um email com `modernTemplate` e assunto de boas-vindas. |
725
- | `sendTechNewsletter` | Envia uma newsletter técnica com `monokaiTemplate`. |
726
- | `sendCorporateReport` | Envia um relatório corporativo com `corporateTemplate`. |
727
- | `sendMinimalNewsletter` | Envia uma newsletter minimalista com anexo vindo de `AttachmentService.addFromPath()`. |
728
-
729
-
730
- ### Fluxo mínimo usado no exemplo
731
-
732
- 1. `dotenv.config()` carrega `SMTP_USER` e `SMTP_PASS`.
733
- 2. `SMTP_CONFIG` é montado com `host`, `port`, `secure`, `auth.user`, `auth.pass` e `defaultFrom`.
734
- 3. `EmailFactory.initialize(SMTP_CONFIG)` cria a fábrica.
735
- 4. `emailFactory.getTemplateService()` expõe o serviço de templates.
736
- 5. `templateService.createTemplate(...)` monta um template com tema e configuração.
737
- 6. `emailFactory.sendEmail({ to, subject, template })` envia a mensagem.
738
- 7. `EmailService.send()` resolve `from` com `defaultFrom`, renderiza o template e chama o `transporter`.
739
- 8. O resultado retorna como JSON.
740
-
741
- ### Exemplo mínimo de envio
742
-
743
- ```ts
49
+ ```typescript
744
50
  const templateService = emailFactory.getTemplateService();
745
51
 
746
- const modernTemplate = templateService.createTemplate(
747
- ThemeType.MODERN,
748
- 'light',
52
+ // Create a template
53
+ const welcomeTemplate = templateService.createTemplate(
54
+ 'modern', // ThemeType
55
+ 'light', // Variant
749
56
  {
750
- header: {
751
- show: true,
752
- logo: {
753
- type: 'image',
754
- imageUrl: 'https://talkspace-ten.vercel.app/_next/image?url=%2Flogo%2Ftalkspace-banner.png&w=640&q=75',
755
- size: 'large'
756
- }
757
- },
758
57
  body: {
759
- title: 'Bem-vindo ao LyraX!',
760
- message: 'Estamos felizes em tê-lo conosco.',
761
- buttonText: 'Começar Agora',
762
- buttonUrl: 'https://meuapp.com/get-started',
763
- buttonVariant: 'primary',
764
- alignment: 'center',
765
- fontSize: 16
766
- },
767
- footer: {
768
- show: true,
769
- copyrightText: '© 2024 Meu App'
770
- },
771
- layout: 'full',
772
- spacing: 'normal',
773
- borderRadius: 'medium'
58
+ title: 'Welcome!',
59
+ message: 'Thanks for joining us.',
60
+ buttonText: 'Get Started',
61
+ buttonUrl: 'https://myapp.com'
62
+ }
774
63
  }
775
- );
64
+ );
776
65
 
777
- await emailFactory.sendEmail({
778
- to: 'destinatario@exemplo.com',
779
- subject: 'Bem-vindo ao Meu App!',
780
- template: modernTemplate
66
+ // Send the email
67
+ const result = await emailFactory.sendEmail({
68
+ to: 'user@example.com',
69
+ subject: 'Welcome aboard!',
70
+ template: welcomeTemplate
781
71
  });
782
- ```
783
-
784
- ### Fluxo com anexo no exemplo
785
-
786
- `sendMinimalNewsletter()` cria um `AttachmentService` localmente, chama `addFromPath('uploads/PHOTO.jpg')` e injeta o retorno em `attachments`. O envio segue o mesmo caminho do email comum, mas com o anexo repassado para Nodemailer.
787
-
788
- ```mermaid
789
- sequenceDiagram
790
- participant U as Usuario
791
- participant E as Express
792
- participant S as sendMinimalNewsletter
793
- participant A as AttachmentService
794
- participant F as EmailFactory
795
- participant M as EmailService
796
- participant T as Template
797
- participant B as TemplateBuilder
798
- participant N as Nodemailer
799
- participant Smtp as SMTP
800
-
801
- U->>E: GET test
802
- E->>S: sendMinimalNewsletter
803
- S->>A: addFromPath uploads PHOTO jpg
804
- A-->>S: IAttachment
805
- S->>F: sendEmail
806
- F->>M: send
807
- M->>T: render
808
- T->>B: buildHeader buildBody buildFooter build
809
- B-->>T: HTML
810
- T-->>M: HTML final
811
- M->>N: sendMail
812
- N->>Smtp: entregar email
813
- Smtp-->>N: resposta SMTP
814
- N-->>M: info
815
- M-->>F: { success, messageId, response }
816
- F-->>E: JSON
817
- E-->>U: resposta do endpoint
818
- ```
819
-
820
- ## Servidor de demonstração e ponto de entrada
821
-
822
- ### Endpoint de teste
823
-
824
- #### Executar envio de teste
825
72
 
826
- *`src/index.ts`*
827
-
828
- ```api
829
- {
830
- "title": "Executar envio de teste",
831
- "description": "Dispara o fluxo de demonstra\u00e7\u00e3o que cria um anexo a partir de uploads/PHOTO.jpg, envia um email com o tema Minimal em modo dark e retorna o resultado do envio em JSON.",
832
- "method": "GET",
833
- "baseUrl": "<DemoServerBaseUrl>",
834
- "endpoint": "/test",
835
- "headers": [],
836
- "queryParams": [],
837
- "pathParams": [],
838
- "bodyType": "none",
839
- "requestBody": "",
840
- "formData": [],
841
- "rawBody": "",
842
- "responses": {
843
- "200": {
844
- "description": "Resultado retornado diretamente por res.json(result).",
845
- "body": "{\n \"success\": true,\n \"messageId\": \"5f8a1d3c4b2a@example.com\",\n \"response\": \"250 2.0.0 OK\"\n}"
846
- }
847
- }
848
- }
73
+ console.log(result.success ? 'Sent!' : 'Failed');
849
74
  ```
850
75
 
851
- ### Comportamento real do endpoint
76
+ ## Core Components
852
77
 
853
- - O endpoint é `GET /test`.
854
- - Ele chama `sendMinimalNewsletter('antiquesclub007@gmail.com')`.
855
- - O retorno de `emailFactory.sendEmail()` é enviado diretamente com `res.json(result)`.
856
- - Não há middleware de autenticação nem validação adicional além dos middlewares globais `express.json()` e `express.urlencoded()` montados no bootstrap.
78
+ ### Themes
857
79
 
858
- ### Inicialização do servidor
859
-
860
- sendMinimalNewsletter() não possui try/catch. Se addFromPath('uploads/PHOTO.jpg') falhar ou se o envio SMTP lançar exceção antes de retornar, a requisição deixa de responder com o objeto de sucesso e a exceção sobe para o fluxo do Express.
861
-
862
- também define:
80
+ | Theme | Best For | Features |
81
+ | --- | --- | --- |
82
+ | `MODERN` | Modern UI apps | Gradients, glassmorphism, rounded corners. |
83
+ | `CORPORATE` | Business/Enterprise | Serif typography, gold accents, structured layout. |
84
+ | `MINIMAL` | Clean newsletters | High whitespace, focused content, neutral colors. |
85
+ | `MONOKAI` | Technical content | Syntax highlighting for code blocks, vibrant colors. |
86
+ | `SYSTEM` | General purpose | Clean, accessible, system-native look. |
863
87
 
864
- - `PORT = 3001`
865
- - `app.use(express.json())`
866
- - `app.use(express.urlencoded({ extended: true }))`
867
- - `app.listen(PORT, ...)` com banner de inicialização no console
88
+ ### Attachment Service
868
89
 
869
- ## Estado, cache e tratamento de erros
90
+ Easily add attachments from paths or buffers:
870
91
 
871
- ### Estado de inicialização
92
+ ```typescript
93
+ const attachmentService = emailFactory.getAttachmentService();
94
+ const file = await attachmentService.addFromPath('path/to/report.pdf');
872
95
 
873
- - `EmailFactory` mantém estado global por meio de `private static instance`.
874
- - `TemplateService` mantém estado em memória por `templateCache` e `templateHistory`.
875
- - `TemplateService` agenda limpeza automática com `setInterval(..., 3600000)`.
96
+ await emailFactory.sendEmail({
97
+ to: 'user@example.com',
98
+ subject: 'Monthly Report',
99
+ attachments: [file],
100
+ html: '<p>Please find the report attached.</p>'
101
+ });
102
+ ```
876
103
 
877
- ### Cache de templates
104
+ ## Configuration Reference
878
105
 
879
- | Elemento | Valor |
880
- | --- | --- |
881
- | Chave do cache | `${themeType}_${variant}_${hash}` |
882
- | Dado armazenado | `ITemplate` enriquecido |
883
- | Contador de uso | `hits` |
884
- | Expiração | `expiresAt` calculado em segundos e convertido para milissegundos |
885
- | Limpeza automática | `cleanExpiredCache()` a cada hora |
886
- | Limpeza manual | `clearCache()` |
887
- | Histórico | Últimas 10 versões por `templateId` |
106
+ ### `ITemplateConfig`
888
107
 
108
+ Customize your email structure:
889
109
 
890
- ### Tratamento de erros por componente
110
+ - **header**: `{ show: boolean, logo: { type: 'text' | 'image', ... } }`
891
111
 
892
- - `EmailFactory.getInstance()` lança erro se `initialize()` ainda não foi chamado.
893
- - `TemplateFactory.createTemplate()` lança erro quando o tema não existe no mapa `themes`.
894
- - `TemplateService.validateTemplateConfig()` lança um único erro com todos os problemas encontrados.
895
- - `TemplateService.renderTemplate()` captura falhas e relança com contexto: `Failed to render template: ...`
896
- - `EmailService.send()` nunca lança erro diretamente; retorna `success: false` com o objeto de erro.
897
- - `AttachmentService.addFromPath()` lança erro se o caminho não for arquivo.
898
- - `AttachmentService.addFromUrl()` lança erro fixo de método não implementado.
112
+ - **body**: `{ title, message, buttonText, buttonUrl, alignment, ... }`
899
113
 
900
- ## Dependências e integração
114
+ - **footer**: `{ show: boolean, links: [], socialLinks: [], copyrightText }`
901
115
 
902
- ### Dependências externas
116
+ - **layout**: `'full'` | `'minimal'`
903
117
 
904
- - `express`
905
- - `nodemailer`
906
- - `dotenv`
907
- - `fs`
908
- - `path`
118
+ - **spacing**: `'compact'` | `'normal'` | `'relaxed'`
909
119
 
910
- ### Entradas de ambiente usadas no bootstrap
120
+ ## Error Handling
911
121
 
912
- - `SMTP_USER`
913
- - `SMTP_PASS`
122
+ The `sendEmail` method returns a result object:
914
123
 
915
- ### Integrações internas
916
-
917
- - consome `EmailFactory` e `TemplateService`.
918
- - `EmailFactory` instancia `EmailService`, `TemplateService` e `AttachmentService`.
919
- - `TemplateService` depende de `TemplateFactory`.
920
- - `TemplateFactory` depende das classes de tema e de `TemplateBuilder`.
921
- - `EmailService` depende do `Transporter` do Nodemailer.
922
- - `AttachmentService` é usado tanto no exemplo de anexo quanto como serviço exposto pela fábrica.
923
-
924
- ## Considerações de teste
925
-
926
- - Validar que `EmailFactory.initialize()` foi chamado antes de qualquer `getInstance()`.
927
- - Verificar se `SMTP_USER` e `SMTP_PASS` estão definidos antes do bootstrap.
928
- - Confirmar que `defaultFrom` aparece no envelope do email quando `options.from` não é enviado.
929
- - Testar `sendEmail()` com:- `template` apenas
930
- - `html` apenas
931
- - `template` e `html` juntos
932
- - `attachments` com arquivo válido
933
- - Confirmar que `addFromPath()` falha para diretório ou caminho inexistente.
934
- - Confirmar que `GET /test` retorna JSON com o formato devolvido por `sendEmail()`.
935
-
936
- ## Referência rápida das classes-chave
937
-
938
- | Class | Responsibility |
939
- | --- | --- |
940
- | `email-factory.ts` | Centraliza a inicialização SMTP e expõe `EmailService`, `TemplateService` e `AttachmentService`. |
941
- | `email.service.ts` | Constrói `mailOptions` e envia emails via Nodemailer. |
942
- | `template.service.ts` | Cria, renderiza, cacheia e versiona templates. |
943
- | `template-factory.ts` | Transforma tema e configuração em um `ITemplate` renderizável. |
944
- | `template-builder.ts` | Monta o HTML final do email com header, body, button e footer. |
945
- | `attachment.service.ts` | Converte arquivos e buffers em anexos Nodemailer. |
946
- | `system.theme.ts` | Define o tema base `SYSTEM`. |
947
- | `monokai.theme.ts` | Define o tema `MONOKAI` com destaque de código. |
948
- | `modern.theme.ts` | Define o tema `MODERN` com gradientes e glassmorphism. |
949
- | `corporate.theme.ts` | Define o tema `CORPORATE` com linguagem visual executiva. |
950
- | `minimal.theme.ts` | Define o tema `MINIMAL` com layout enxuto e neutro. |
951
-
952
-
953
- ---
954
-
955
- ## Gerenciamento de Templates/Temas concretos: System, Monokai, Modern, Corporate e Minimal
956
-
957
- # Gerenciamento de Templates - Temas concretos
958
-
959
- ## Visão geral
960
-
961
- Este recorte concentra os cinco temas concretos do mecanismo de templates de email do projeto: `System`, `Monokai`, `Modern`, `Corporate` e `Minimal`. Eles formam a camada visual base que define cores, tipografia, espaçamento e extensões temáticas usadas na composição final do HTML.
962
-
963
- O fluxo visível no código parte do contrato `ITheme`, passa pelo registro de temas em `TemplateFactory` e chega à montagem visual em `TemplateBuilder`. Na prática, o tema selecionado determina como cabeçalho, corpo, botão e rodapé são estilizados, além de habilitar comportamentos especiais como realce de código, gradientes, glassmorphism, branding corporativo e layout minimalista.
964
-
965
- ### Comparação rápida dos temas
966
-
967
- | Tema | Paleta visual | Tipografia | Espaçamento | Extensões específicas |
968
- | --- | --- | --- | --- | --- |
969
- | `System` | Azul padrão e neutros claros/escuros | Sans system default | Compacto a normal | Nenhuma extensão extra |
970
- | `Monokai` | Paleta técnica com magenta, verde e roxo | Monospace | Compacto | `codeHighlight`, `effects`, `borderStyle` |
971
- | `Modern` | Neutros com azul e gradientes | Inter com suporte a UI moderna | Médio a relaxado | `gradients`, `glassmorphism`, `animations`, `borderStyle` |
972
- | `Corporate` | Azul executivo com dourado e tons institucionais | Serifada | Médio | `corporateColors`, `branding`, `elevation`, `layout`, `borderStyle` |
973
- | `Minimal` | Preto, branco e cinzas | Inter limpa | Generoso | `minimalColors`, `effects`, `layout`, `designSystem`, `borderStyle` |
974
-
975
-
976
- ## Arquitetura de composição dos temas
977
-
978
- ```mermaid
979
- flowchart LR
980
- subgraph Contratos[Contratos]
981
- ThemeType[ThemeType]
982
- ITheme[ITheme]
983
- IThemeColors[IThemeColors]
984
- ITypography[ITypography]
985
- ISpacing[ISpacing]
986
- end
987
-
988
- subgraph TemasConcretos[Temas concretos]
989
- SystemTheme[SystemTheme]
990
- MonokaiTheme[MonokaiTheme]
991
- ModernTheme[ModernTheme]
992
- CorporateTheme[CorporateTheme]
993
- MinimalTheme[MinimalTheme]
994
- end
995
-
996
- subgraph Composicao[Composição]
997
- TemplateFactory[TemplateFactory]
998
- TemplateBuilder[TemplateBuilder]
999
- end
1000
-
1001
- ThemeType --> TemplateFactory
1002
- ITheme --> SystemTheme
1003
- ITheme --> MonokaiTheme
1004
- ITheme --> ModernTheme
1005
- ITheme --> CorporateTheme
1006
- ITheme --> MinimalTheme
1007
-
1008
- TemplateFactory --> SystemTheme
1009
- TemplateFactory --> MonokaiTheme
1010
- TemplateFactory --> ModernTheme
1011
- TemplateFactory --> CorporateTheme
1012
- TemplateFactory --> MinimalTheme
1013
-
1014
- TemplateBuilder --> SystemTheme
1015
- TemplateBuilder --> MonokaiTheme
1016
- TemplateBuilder --> ModernTheme
1017
- TemplateBuilder --> CorporateTheme
1018
- TemplateBuilder --> MinimalTheme
1019
- ```
1020
-
1021
- O contrato `ITheme` padroniza os tokens visuais obrigatórios. `TemplateFactory` mantém a instância concreta em um `Map<ThemeType, ITheme>`, enquanto `TemplateBuilder` lê esses tokens e monta as variações de HTML conforme `variant` e `theme.id`.
1022
-
1023
- ## Contratos compartilhados
1024
-
1025
- ### `theme.interface.ts`
1026
-
1027
- *`src/templates/themes/theme.interface.ts`*
1028
-
1029
- #### `ITheme`
1030
-
1031
- | Propriedade | Tipo | Descrição |
1032
- | --- | --- | --- |
1033
- | `id` | `ThemeType` | Identificador do tema |
1034
- | `name` | `string` | Nome legível do tema |
1035
- | `light` | `IThemeColors` | Paleta para modo claro |
1036
- | `dark` | `IThemeColors` | Paleta para modo escuro |
1037
- | `typography` | `ITypography` | Sistema tipográfico do tema |
1038
- | `spacing` | `ISpacing` | Escala de espaçamento do tema |
1039
-
1040
-
1041
- #### `IThemeColors`
1042
-
1043
- | Propriedade | Tipo |
1044
- | --- | --- |
1045
- | `primary` | `string` |
1046
- | `secondary` | `string` |
1047
- | `background` | `string` |
1048
- | `text` | `string` |
1049
- | `textMuted` | `string` |
1050
- | `border` | `string` |
1051
- | `success` | `string` |
1052
- | `error` | `string` |
1053
- | `warning` | `string` |
1054
-
1055
-
1056
- #### `ITypography`
1057
-
1058
- | Propriedade | Tipo |
1059
- | --- | --- |
1060
- | `fontFamily` | `string` |
1061
- | `fontSizes.small` | `string` |
1062
- | `fontSizes.medium` | `string` |
1063
- | `fontSizes.large` | `string` |
1064
- | `fontSizes.xlarge` | `string` |
1065
- | `fontWeights.normal` | `number` |
1066
- | `fontWeights.medium` | `number` |
1067
- | `fontWeights.bold` | `number` |
1068
-
1069
-
1070
- #### `ISpacing`
1071
-
1072
- | Propriedade | Tipo |
1073
- | --- | --- |
1074
- | `xs` | `string` |
1075
- | `sm` | `string` |
1076
- | `md` | `string` |
1077
- | `lg` | `string` |
1078
- | `xl` | `string` |
1079
-
1080
-
1081
- #### `ThemeType`
1082
-
1083
- Valores definidos: `system`, `monokai`, `modern`, `corporate`, `minimal`.
1084
-
1085
- ### `TemplateFactory`
1086
-
1087
- *`src/factories/template-factory.ts`*
1088
-
1089
- A fábrica registra os cinco temas concretos em um `Map<ThemeType, ITheme>` e materializa um `ITemplate` com `name`, `theme`, `variant`, `config` e `render`.
1090
-
1091
- #### Métodos públicos
1092
-
1093
- | Método | Descrição |
1094
- | --- | --- |
1095
- | `createTemplate` | Resolve o tema pelo `ThemeType`, cria um `ITemplate` e associa o `render` à montagem via `TemplateBuilder` |
1096
- | `getTheme` | Retorna a instância concreta do tema para um `ThemeType` |
1097
- | `listThemes` | Lista os temas registrados no mapa interno |
1098
- | `getThemeInfo` | Expõe nome, descrição e lista de recursos do tema |
1099
-
1100
-
1101
- #### Metadados de tema expostos por `getThemeInfo`
1102
-
1103
- | Tema | Nome | Descrição | Recursos |
1104
- | --- | --- | --- | --- |
1105
- | `SYSTEM` | `System` | Tema limpo e profissional com cores adaptativas | Design minimalista, alta acessibilidade, compatibilidade total |
1106
- | `MONOKAI` | `Monokai` | Inspirado no tema de código, ideal para conteúdo técnico | Cores vibrantes, destaque de sintaxe, efeitos glow |
1107
- | `MODERN` | `Modern` | Design contemporâneo com gradientes e efeitos modernos | Gradientes elegantes, glassmorphism, animações suaves |
1108
- | `CORPORATE` | `Corporate` | Design profissional e elegante para empresas | Tipografia serifada, detalhes em dourado, layout estruturado |
1109
- | `MINIMAL` | `Minimal` | Design clean e focado no conteúdo | Sem distrações, espaçamento generoso, tipografia limpa |
1110
-
1111
-
1112
- ### `TemplateBuilder`
1113
-
1114
- *`src/templates/base/template-builder.ts`*
1115
-
1116
- O `TemplateBuilder` consome o tema concreto em cada etapa da composição do email. Ele aplica estilos de cabeçalho, corpo, botão, rodapé e container final com ramificações específicas para `monokai`, `modern`, `corporate` e `minimal`.
1117
-
1118
- #### Propriedades
1119
-
1120
- | Propriedade | Tipo | Descrição |
1121
- | --- | --- | --- |
1122
- | `template` | `string` | HTML acumulado durante a construção |
1123
- | `theme` | `ITheme` | Tema concreto usado na renderização |
1124
- | `config` | `ITemplateConfig` | Configuração visual do template |
1125
- | `variant` | `'light'` `'dark'` | Variante visual ativa |
1126
-
1127
-
1128
- #### Métodos públicos
1129
-
1130
- | Método | Descrição |
1131
- | --- | --- |
1132
- | `buildHeader` | Monta o cabeçalho e aplica ajustes específicos por tema |
1133
- | `buildBody` | Monta o corpo do email e processa conteúdo especial por tema |
1134
- | `buildButton` | Monta o botão de CTA com variações visuais por tema |
1135
- | `buildFooter` | Monta o rodapé com links, redes sociais e texto institucional |
1136
- | `build` | Finaliza o HTML completo do template |
1137
-
1138
-
1139
- #### Extensões específicas aplicadas por tema
1140
-
1141
- | Tema | Propriedades consumidas | Efeito gerado |
1142
- | --- | --- | --- |
1143
- | `System` | `light`, `dark`, `typography`, `spacing` | Estilo base com bordas e espaçamentos padrão |
1144
- | `Monokai` | `codeHighlight`, `effects`, `borderStyle` | Realce de código, brilho, transições e borda técnica |
1145
- | `Modern` | `gradients`, `glassmorphism`, `animations`, `borderStyle` | Botões com gradiente, blur e cantos arredondados |
1146
- | `Corporate` | `corporateColors`, `branding`, `elevation`, `borderStyle` | Dourado institucional, caixa com sombra e tipografia serifada |
1147
- | `Minimal` | `layout`, `designSystem`, `effects`, `borderStyle` | Layout centralizado, conteúdo arejado e aparência sem distrações |
1148
-
1149
-
1150
- #### Helpers internos relevantes
1151
-
1152
- | Método | Função |
1153
- | --- | --- |
1154
- | `buildLogo` | Renderiza logo em texto ou imagem com ajustes por tema |
1155
- | `formatCorporateContent` | Adiciona estilos corporativos a `blockquote` e `highlight` |
1156
- | `formatMinimalContent` | Simplifica títulos e parágrafos para o tema minimalista |
1157
- | `highlightCode` | Converte blocos `<code>` em `<pre>` com estilização Monokai |
1158
- | `applySyntaxHighlighting` | Aplica coloração por palavra-chave, string, número e função |
1159
- | `buildFooterLinks` | Monta links do rodapé com variações por tema |
1160
- | `buildSocialLinks` | Monta ícones sociais a partir de URLs fixas |
1161
- | `getSocialIcon` | Resolve o ícone do serviço social pela plataforma |
1162
-
1163
-
1164
- ## Fluxo de criação e renderização de um tema
1165
-
1166
- ```mermaid
1167
- sequenceDiagram
1168
- participant Dev as Desenvolvedor
1169
- participant TemplateFactory as TemplateFactory
1170
- participant ITemplate as ITemplate
1171
- participant TemplateBuilder as TemplateBuilder
1172
-
1173
- Dev->>TemplateFactory: createTemplate
1174
- TemplateFactory->>TemplateFactory: resolve tema por ThemeType
1175
- TemplateFactory-->>Dev: ITemplate
1176
- Dev->>ITemplate: render
1177
- ITemplate->>TemplateBuilder: buildHeader
1178
- ITemplate->>TemplateBuilder: buildBody
1179
- ITemplate->>TemplateBuilder: buildButton
1180
- ITemplate->>TemplateBuilder: buildFooter
1181
- ITemplate->>TemplateBuilder: build
1182
- TemplateBuilder-->>ITemplate: HTML final
1183
- ITemplate-->>Dev: HTML renderizado
1184
- ```
1185
-
1186
- Os blocos de estilo criados em buildButton, buildFooterLinks e trechos similares incluem &:hover dentro de atributos style. O HTML inline gerado por build() preserva esse texto, mas pseudo-classes não são interpretadas como CSS ativo no markup final.
1187
-
1188
- Esse fluxo é o mesmo para os cinco temas concretos; o que muda é o conjunto de tokens expostos pelo tema e as ramificações internas que `TemplateBuilder` ativa com base em `theme.id`.
1189
-
1190
- ## Temas concretos
1191
-
1192
- ### `SystemTheme`
1193
-
1194
- *`src/templates/themes/system.theme.ts`*
1195
-
1196
- Tema base com visual neutro e suporte direto a modos claro e escuro. Ele usa azul como cor primária e neutros para texto, borda e superfícies, com tipografia sans-serif do sistema.
1197
-
1198
- #### Propriedades
1199
-
1200
- | Propriedade | Tipo |
1201
- | --- | --- |
1202
- | `id` | `ThemeType.SYSTEM` |
1203
- | `name` | `string` |
1204
- | `light` | `IThemeColors` |
1205
- | `dark` | `IThemeColors` |
1206
- | `typography` | `ITypography` |
1207
- | `spacing` | `ISpacing` |
1208
-
1209
-
1210
- #### Paleta
1211
-
1212
- | Token | Light | Dark |
1213
- | --- | --- | --- |
1214
- | `primary` | `#3b82f6` | `#3b82f6` |
1215
- | `secondary` | `#6b7280` | `#9ca3af` |
1216
- | `background` | `#ffffff` | `#111827` |
1217
- | `text` | `#111827` | `#f9fafb` |
1218
- | `textMuted` | `#6b7280` | `#9ca3af` |
1219
- | `border` | `#e5e7eb` | `#374151` |
1220
- | `success` | `#10b981` | `#10b981` |
1221
- | `error` | `#ef4444` | `#ef4444` |
1222
- | `warning` | `#f59e0b` | `#f59e0b` |
1223
-
1224
-
1225
- #### Tipografia
1226
-
1227
- | Propriedade | Valor |
1228
- | --- | --- |
1229
- | `fontFamily` | `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif` |
1230
- | `fontSizes.small` | `12px` |
1231
- | `fontSizes.medium` | `14px` |
1232
- | `fontSizes.large` | `16px` |
1233
- | `fontSizes.xlarge` | `20px` |
1234
- | `fontWeights.normal` | `400` |
1235
- | `fontWeights.medium` | `500` |
1236
- | `fontWeights.bold` | `700` |
1237
-
1238
-
1239
- #### Espaçamento
1240
-
1241
- | Propriedade | Valor |
1242
- | --- | --- |
1243
- | `xs` | `4px` |
1244
- | `sm` | `8px` |
1245
- | `md` | `16px` |
1246
- | `lg` | `24px` |
1247
- | `xl` | `32px` |
1248
-
1249
-
1250
- #### Leitura visual
1251
-
1252
- - Cabeçalho e rodapé usam os tokens base de fundo, borda e texto.
1253
- - Não há propriedades extras além do contrato `ITheme`.
1254
- - A aplicação em `TemplateBuilder` segue o caminho padrão, sem ramificações visuais adicionais.
1255
-
1256
- ### `MonokaiTheme`
1257
-
1258
- *`src/templates/themes/monokai.theme.ts`*
1259
-
1260
- Tema voltado para conteúdo técnico, com identidade inspirada em editores de código. A paleta mantém magenta e verde como destaques, e o tema adiciona realce semântico para blocos de código.
1261
-
1262
- #### Propriedades
1263
-
1264
- | Propriedade | Tipo |
1265
- | --- | --- |
1266
- | `id` | `ThemeType.MONOKAI` |
1267
- | `name` | `string` |
1268
- | `light` | `IThemeColors` |
1269
- | `dark` | `IThemeColors` |
1270
- | `typography` | `ITypography` |
1271
- | `spacing` | `ISpacing` |
1272
- | `codeHighlight` | `{ comment: string; keyword: string; string: string; number: string; function: string; variable: string }` |
1273
- | `borderStyle` | `{ radius: string; width: string; style: string }` |
1274
- | `effects` | `{ glow: string; shadow: string; transition: string }` |
1275
-
1276
-
1277
- #### Paleta
1278
-
1279
- | Token | Light | Dark |
1280
- | --- | --- | --- |
1281
- | `primary` | `#f92672` | `#f92672` |
1282
- | `secondary` | `#a6e22e` | `#a6e22e` |
1283
- | `background` | `#f9f9f9` | `#272822` |
1284
- | `text` | `#272822` | `#f8f8f2` |
1285
- | `textMuted` | `#75715e` | `#75715e` |
1286
- | `border` | `#e5e5e5` | `#3e3d32` |
1287
- | `success` | `#a6e22e` | `#a6e22e` |
1288
- | `error` | `#f92672` | `#f92672` |
1289
- | `warning` | `#fd971f` | `#fd971f` |
1290
-
1291
-
1292
- #### Tipografia
1293
-
1294
- | Propriedade | Valor |
1295
- | --- | --- |
1296
- | `fontFamily` | `SF Mono, Monaco, Inconsolata, Fira Code, monospace` |
1297
- | `fontSizes.small` | `12px` |
1298
- | `fontSizes.medium` | `14px` |
1299
- | `fontSizes.large` | `16px` |
1300
- | `fontSizes.xlarge` | `20px` |
1301
- | `fontWeights.normal` | `400` |
1302
- | `fontWeights.medium` | `500` |
1303
- | `fontWeights.bold` | `700` |
1304
-
1305
-
1306
- #### Espaçamento
1307
-
1308
- | Propriedade | Valor |
1309
- | --- | --- |
1310
- | `xs` | `4px` |
1311
- | `sm` | `8px` |
1312
- | `md` | `16px` |
1313
- | `lg` | `24px` |
1314
- | `xl` | `32px` |
1315
-
1316
-
1317
- #### Extensões específicas
1318
-
1319
- ##### `codeHighlight`
1320
-
1321
- | Token | Cor |
1322
- | --- | --- |
1323
- | `comment` | `#75715e` |
1324
- | `keyword` | `#f92672` |
1325
- | `string` | `#e6db74` |
1326
- | `number` | `#ae81ff` |
1327
- | `function` | `#a6e22e` |
1328
- | `variable` | `#fd971f` |
1329
-
1330
-
1331
- ##### `borderStyle`
1332
-
1333
- | Propriedade | Valor |
1334
- | --- | --- |
1335
- | `radius` | `4px` |
1336
- | `width` | `2px` |
1337
- | `style` | `solid` |
1338
-
1339
-
1340
- ##### `effects`
1341
-
1342
- | Propriedade | Valor |
1343
- | --- | --- |
1344
- | `glow` | `0 0 10px rgba(249, 38, 114, 0.3)` |
1345
- | `shadow` | `0 4px 6px rgba(0, 0, 0, 0.1)` |
1346
- | `transition` | `all 0.3s ease` |
1347
-
1348
-
1349
- #### Leitura visual
1350
-
1351
- - `TemplateBuilder.highlightCode` usa `codeHighlight` para colorir keywords, strings, números e nomes de função.
1352
- - O cabeçalho e os botões recebem brilho e transição via `effects`.
1353
- - O layout privilegia blocos com borda técnica e acento visual marcante.
1354
-
1355
- ### `ModernTheme`
1356
-
1357
- *`src/templates/themes/modern.theme.ts`*
1358
-
1359
- Tema contemporâneo com uso de gradientes, blur e transições suaves. O conjunto de tokens foi desenhado para dar mais profundidade visual a botões, contêineres e cabeçalhos.
1360
-
1361
- #### Propriedades
1362
-
1363
- | Propriedade | Tipo |
1364
- | --- | --- |
1365
- | `id` | `ThemeType.MODERN` |
1366
- | `name` | `string` |
1367
- | `light` | `IThemeColors` |
1368
- | `dark` | `IThemeColors` |
1369
- | `typography` | `ITypography` |
1370
- | `spacing` | `ISpacing` |
1371
- | `gradients` | `{ primary: string; secondary: string; accent: string; dark: string; light: string }` |
1372
- | `borderStyle` | `{ radius: { small: string; medium: string; large: string; full: string }; width: string; style: string }` |
1373
- | `glassmorphism` | `{ light: string; dark: string; blur: string }` |
1374
- | `animations` | `{ hover: string; fade: string; slide: string }` |
1375
-
1376
-
1377
- #### Paleta
1378
-
1379
- | Token | Light | Dark |
1380
- | --- | --- | --- |
1381
- | `primary` | `#0f172a` | `#38bdf8` |
1382
- | `secondary` | `#64748b` | `#94a3b8` |
1383
- | `background` | `#ffffff` | `#0f172a` |
1384
- | `text` | `#0f172a` | `#f1f5f9` |
1385
- | `textMuted` | `#64748b` | `#94a3b8` |
1386
- | `border` | `#e2e8f0` | `#1e293b` |
1387
- | `success` | `#10b981` | `#34d399` |
1388
- | `error` | `#ef4444` | `#f87171` |
1389
- | `warning` | `#f59e0b` | `#fbbf24` |
1390
-
1391
-
1392
- #### Tipografia
1393
-
1394
- | Propriedade | Valor |
1395
- | --- | --- |
1396
- | `fontFamily` | `Inter, SF Pro Display, Segoe UI, system-ui, sans-serif` |
1397
- | `fontSizes.small` | `13px` |
1398
- | `fontSizes.medium` | `15px` |
1399
- | `fontSizes.large` | `17px` |
1400
- | `fontSizes.xlarge` | `24px` |
1401
- | `fontWeights.normal` | `400` |
1402
- | `fontWeights.medium` | `500` |
1403
- | `fontWeights.bold` | `600` |
1404
-
1405
-
1406
- #### Espaçamento
1407
-
1408
- | Propriedade | Valor |
1409
- | --- | --- |
1410
- | `xs` | `6px` |
1411
- | `sm` | `12px` |
1412
- | `md` | `20px` |
1413
- | `lg` | `32px` |
1414
- | `xl` | `48px` |
1415
-
1416
-
1417
- #### Extensões específicas
1418
-
1419
- ##### `gradients`
1420
-
1421
- | Token | Valor |
1422
- | --- | --- |
1423
- | `primary` | `linear-gradient(135deg, #0f172a 0%, #1e293b 100%)` |
1424
- | `secondary` | `linear-gradient(135deg, #64748b 0%, #94a3b8 100%)` |
1425
- | `accent` | `linear-gradient(135deg, #38bdf8 0%, #0f172a 100%)` |
1426
- | `dark` | `linear-gradient(135deg, #0f172a 0%, #020617 100%)` |
1427
- | `light` | `linear-gradient(135deg, #f8fafc 0%, #ffffff 100%)` |
1428
-
1429
-
1430
- ##### `borderStyle`
1431
-
1432
- | Propriedade | Valor |
1433
- | --- | --- |
1434
- | `radius.small` | `8px` |
1435
- | `radius.medium` | `12px` |
1436
- | `radius.large` | `16px` |
1437
- | `radius.full` | `9999px` |
1438
- | `width` | `1px` |
1439
- | `style` | `solid` |
1440
-
1441
-
1442
- ##### `glassmorphism`
1443
-
1444
- | Propriedade | Valor |
1445
- | --- | --- |
1446
- | `light` | `rgba(255, 255, 255, 0.8)` |
1447
- | `dark` | `rgba(15, 23, 42, 0.8)` |
1448
- | `blur` | `12px` |
1449
-
1450
-
1451
- ##### `animations`
1452
-
1453
- | Propriedade | Valor |
1454
- | --- | --- |
1455
- | `hover` | `transform 0.2s ease, box-shadow 0.2s ease` |
1456
- | `fade` | `opacity 0.3s ease` |
1457
- | `slide` | `transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)` |
1458
-
1459
-
1460
- #### Leitura visual
1461
-
1462
- - `TemplateBuilder` usa `gradients.primary` no botão principal e no texto do logo.
1463
- - `glassmorphism.blur` entra no cabeçalho e no rodapé para criar profundidade.
1464
- - `animations.hover` é aplicado a botões e links de navegação do tema.
1465
-
1466
- ### `CorporateTheme`
1467
-
1468
- *`src/templates/themes/corporate.theme.ts`*
1469
-
1470
- Tema voltado para comunicação empresarial, com base serifada, tons institucionais e acentos dourados. O tema expande o contrato base com tokens de marca, elevação e layout.
1471
-
1472
- #### Propriedades
1473
-
1474
- | Propriedade | Tipo |
1475
- | --- | --- |
1476
- | `id` | `ThemeType.CORPORATE` |
1477
- | `name` | `string` |
1478
- | `light` | `IThemeColors` |
1479
- | `dark` | `IThemeColors` |
1480
- | `typography` | `ITypography` |
1481
- | `spacing` | `ISpacing` |
1482
- | `corporateColors` | `{ gold: string; silver: string; bronze: string; navy: string; charcoal: string; ivory: string }` |
1483
- | `borderStyle` | `{ radius: { small: string; medium: string; large: string; pill: string }; width: { thin: string; medium: string; thick: string }; style: string }` |
1484
- | `elevation` | `{ shadow: string; card: string; modal: string; hover: string }` |
1485
- | `branding` | `{ logoSize: { small: string; medium: string; large: string }; letterSpacing: { tight: string; normal: string; wide: string; wider: string }; textTransform: { uppercase: string; lowercase: string; capitalize: string; normal: string } }` |
1486
- | `layout` | `{ maxWidth: string; contentWidth: string; sidebarWidth: string; headerHeight: string; footerHeight: string }` |
1487
-
1488
-
1489
- #### Paleta
1490
-
1491
- | Token | Light | Dark |
1492
- | --- | --- | --- |
1493
- | `primary` | `#1e40af` | `#3b82f6` |
1494
- | `secondary` | `#334155` | `#64748b` |
1495
- | `background` | `#ffffff` | `#0f172a` |
1496
- | `text` | `#0f172a` | `#f1f5f9` |
1497
- | `textMuted` | `#475569` | `#94a3b8` |
1498
- | `border` | `#e2e8f0` | `#1e293b` |
1499
- | `success` | `#059669` | `#10b981` |
1500
- | `error` | `#dc2626` | `#ef4444` |
1501
- | `warning` | `#d97706` | `#f59e0b` |
1502
-
1503
-
1504
- #### Tipografia
1505
-
1506
- | Propriedade | Valor |
1507
- | --- | --- |
1508
- | `fontFamily` | `"Playfair Display", "Georgia", "Times New Roman", serif` |
1509
- | `fontSizes.small` | `12px` |
1510
- | `fontSizes.medium` | `14px` |
1511
- | `fontSizes.large` | `16px` |
1512
- | `fontSizes.xlarge` | `24px` |
1513
- | `fontWeights.normal` | `400` |
1514
- | `fontWeights.medium` | `500` |
1515
- | `fontWeights.bold` | `700` |
1516
-
1517
-
1518
- #### Espaçamento
1519
-
1520
- | Propriedade | Valor |
1521
- | --- | --- |
1522
- | `xs` | `4px` |
1523
- | `sm` | `8px` |
1524
- | `md` | `16px` |
1525
- | `lg` | `24px` |
1526
- | `xl` | `32px` |
1527
-
1528
-
1529
- #### Extensões específicas
1530
-
1531
- ##### `corporateColors`
1532
-
1533
- | Token | Valor |
1534
- | --- | --- |
1535
- | `gold` | `#d4af37` |
1536
- | `silver` | `#c0c0c0` |
1537
- | `bronze` | `#cd7f32` |
1538
- | `navy` | `#0a2540` |
1539
- | `charcoal` | `#36454f` |
1540
- | `ivory` | `#fffff0` |
1541
-
1542
-
1543
- ##### `borderStyle`
1544
-
1545
- | Propriedade | Valor |
1546
- | --- | --- |
1547
- | `radius.small` | `2px` |
1548
- | `radius.medium` | `4px` |
1549
- | `radius.large` | `8px` |
1550
- | `radius.pill` | `20px` |
1551
- | `width.thin` | `1px` |
1552
- | `width.medium` | `2px` |
1553
- | `width.thick` | `3px` |
1554
- | `style` | `solid` |
1555
-
1556
-
1557
- ##### `elevation`
1558
-
1559
- | Propriedade | Valor |
1560
- | --- | --- |
1561
- | `shadow` | `0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04)` |
1562
- | `card` | `0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)` |
1563
- | `modal` | `0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.02)` |
1564
- | `hover` | `0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)` |
1565
-
1566
-
1567
- ##### `branding`
1568
-
1569
- | Propriedade | Valor |
1570
- | --- | --- |
1571
- | `logoSize.small` | `32px` |
1572
- | `logoSize.medium` | `48px` |
1573
- | `logoSize.large` | `64px` |
1574
- | `letterSpacing.tight` | `-0.5px` |
1575
- | `letterSpacing.normal` | `0px` |
1576
- | `letterSpacing.wide` | `0.5px` |
1577
- | `letterSpacing.wider` | `1px` |
1578
- | `textTransform.uppercase` | `uppercase` |
1579
- | `textTransform.lowercase` | `lowercase` |
1580
- | `textTransform.capitalize` | `capitalize` |
1581
- | `textTransform.normal` | `none` |
1582
-
1583
-
1584
- ##### `layout`
1585
-
1586
- | Propriedade | Valor |
1587
- | --- | --- |
1588
- | `maxWidth` | `600px` |
1589
- | `contentWidth` | `560px` |
1590
- | `sidebarWidth` | `200px` |
1591
- | `headerHeight` | `80px` |
1592
- | `footerHeight` | `120px` |
1593
-
1594
-
1595
- #### Leitura visual
1596
-
1597
- - O cabeçalho recebe dourado corporativo, `uppercase` e tracking mais largo.
1598
- - `buildBody` adiciona borda lateral dourada e sombra de cartão.
1599
- - O rodapé usa fonte menor, `letterSpacing.normal` e borda superior mais forte.
1600
-
1601
- ### `MinimalTheme`
1602
-
1603
- *`src/templates/themes/minimal.theme.ts`*
1604
-
1605
- Tema orientado ao conteúdo, com menos elementos decorativos e maior respiro entre blocos. A superfície visual é reduzida ao essencial, com um sistema de layout e design próprio.
1606
-
1607
- #### Propriedades
1608
-
1609
- | Propriedade | Tipo |
1610
- | --- | --- |
1611
- | `id` | `ThemeType.MINIMAL` |
1612
- | `name` | `string` |
1613
- | `light` | `IThemeColors` |
1614
- | `dark` | `IThemeColors` |
1615
- | `typography` | `ITypography` |
1616
- | `spacing` | `ISpacing` |
1617
- | `minimalColors` | `{ white: string; black: string; gray100: string; gray200: string; gray300: string; gray400: string; gray500: string; gray600: string; gray700: string; gray800: string; gray900: string }` |
1618
- | `borderStyle` | `{ radius: { none: string; small: string; medium: string; large: string; full: string }; width: { thin: string; medium: string }; style: string }` |
1619
- | `effects` | `{ shadow: string; transition: string; opacity: { hover: string; disabled: string } }` |
1620
- | `layout` | `{ maxWidth: string; contentWidth: string; spacingMultiplier: number; lineHeight: number; paragraphSpacing: string }` |
1621
- | `designSystem` | `{ grid: { columns: number; gutter: string; margin: string }; breakpoints: { mobile: string; tablet: string; desktop: string }; zIndex: { base: number; overlay: number; modal: number } }` |
1622
-
1623
-
1624
- #### Paleta
1625
-
1626
- | Token | Light | Dark |
1627
- | --- | --- | --- |
1628
- | `primary` | `#000000` | `#ffffff` |
1629
- | `secondary` | `#404040` | `#a3a3a3` |
1630
- | `background` | `#ffffff` | `#000000` |
1631
- | `text` | `#111111` | `#ffffff` |
1632
- | `textMuted` | `#666666` | `#737373` |
1633
- | `border` | `#e5e5e5` | `#262626` |
1634
- | `success` | `#22c55e` | `#22c55e` |
1635
- | `error` | `#ef4444` | `#ef4444` |
1636
- | `warning` | `#f97316` | `#f97316` |
1637
-
1638
-
1639
- #### Tipografia
1640
-
1641
- | Propriedade | Valor |
1642
- | --- | --- |
1643
- | `fontFamily` | `Inter, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif` |
1644
- | `fontSizes.small` | `13px` |
1645
- | `fontSizes.medium` | `15px` |
1646
- | `fontSizes.large` | `17px` |
1647
- | `fontSizes.xlarge` | `21px` |
1648
- | `fontWeights.normal` | `400` |
1649
- | `fontWeights.medium` | `500` |
1650
- | `fontWeights.bold` | `600` |
1651
-
1652
-
1653
- #### Espaçamento
1654
-
1655
- | Propriedade | Valor |
1656
- | --- | --- |
1657
- | `xs` | `8px` |
1658
- | `sm` | `16px` |
1659
- | `md` | `24px` |
1660
- | `lg` | `32px` |
1661
- | `xl` | `48px` |
1662
-
1663
-
1664
- #### Extensões específicas
1665
-
1666
- ##### `minimalColors`
1667
-
1668
- | Token | Valor |
1669
- | --- | --- |
1670
- | `white` | `#ffffff` |
1671
- | `black` | `#000000` |
1672
- | `gray100` | `#f5f5f5` |
1673
- | `gray200` | `#e5e5e5` |
1674
- | `gray300` | `#d4d4d4` |
1675
- | `gray400` | `#a3a3a3` |
1676
- | `gray500` | `#737373` |
1677
- | `gray600` | `#525252` |
1678
- | `gray700` | `#404040` |
1679
- | `gray800` | `#262626` |
1680
- | `gray900` | `#171717` |
1681
-
1682
-
1683
- ##### `borderStyle`
1684
-
1685
- | Propriedade | Valor |
1686
- | --- | --- |
1687
- | `radius.none` | `0px` |
1688
- | `radius.small` | `2px` |
1689
- | `radius.medium` | `4px` |
1690
- | `radius.large` | `8px` |
1691
- | `radius.full` | `9999px` |
1692
- | `width.thin` | `1px` |
1693
- | `width.medium` | `2px` |
1694
- | `style` | `solid` |
1695
-
1696
-
1697
- ##### `effects`
1698
-
1699
- | Propriedade | Valor |
1700
- | --- | --- |
1701
- | `shadow` | `none` |
1702
- | `transition` | `all 0.2s ease` |
1703
- | `opacity.hover` | `0.7` |
1704
- | `opacity.disabled` | `0.5` |
1705
-
1706
-
1707
- ##### `layout`
1708
-
1709
- | Propriedade | Valor |
1710
- | --- | --- |
1711
- | `maxWidth` | `640px` |
1712
- | `contentWidth` | `560px` |
1713
- | `spacingMultiplier` | `1.5` |
1714
- | `lineHeight` | `1.6` |
1715
- | `paragraphSpacing` | `1.5em` |
1716
-
1717
-
1718
- ##### `designSystem`
1719
-
1720
- | Bloco | Propriedade | Valor |
1721
- | --- | --- | --- |
1722
- | `grid` | `columns` | `12` |
1723
- | `grid` | `gutter` | `20px` |
1724
- | `grid` | `margin` | `20px` |
1725
- | `breakpoints` | `mobile` | `480px` |
1726
- | `breakpoints` | `tablet` | `768px` |
1727
- | `breakpoints` | `desktop` | `1024px` |
1728
- | `zIndex` | `base` | `1` |
1729
- | `zIndex` | `overlay` | `10` |
1730
- | `zIndex` | `modal` | `100` |
1731
-
1732
-
1733
- #### Leitura visual
1734
-
1735
- - `buildBody` centraliza o conteúdo em `contentWidth` e amplia o respiro lateral.
1736
- - `build` ajusta a largura máxima para `640px` e remove bordas no contêiner final.
1737
- - O sistema `designSystem` formaliza grid, breakpoints e camadas visuais para uso do tema.
1738
-
1739
- ## Referência rápida das decisões por tema
1740
-
1741
- | Tema | Cabeçalho | Corpo | Botão | Rodapé |
1742
- | --- | --- | --- | --- | --- |
1743
- | `SystemTheme` | Borda simples e cores base | Texto e fundo do contrato padrão | Botão padrão | Links e textos padrão |
1744
- | `MonokaiTheme` | Borda técnica, sombra e transição | `codeHighlight` e borda lateral magenta | Borda magenta e glow | Borda superior destacada |
1745
- | `ModernTheme` | Blur e borda suave | Margem e raio moderados | Gradiente e sombra leve | Glassmorphism e radius |
1746
- | `CorporateTheme` | Dourado, uppercase e tracking | Borda lateral dourada e sombra de cartão | Letras em uppercase e hover com elevação | Borda superior dourada |
1747
- | `MinimalTheme` | Borda fina e peso tipográfico contido | Max width e layout centralizado | Botão contornado e sem preenchimento | Rodapé enxuto e espaçado |
1748
-
1749
-
1750
- ## Key Classes Reference
1751
-
1752
- | Class | Responsibility |
1753
- | --- | --- |
1754
- | `theme.interface.ts` | Define o contrato comum `ITheme` e os tokens de cor, tipografia e espaçamento |
1755
- | `system.theme.ts` | Implementa o tema base com paleta neutra e tipografia do sistema |
1756
- | `monokai.theme.ts` | Implementa o tema técnico com realce de código e efeitos visuais |
1757
- | `modern.theme.ts` | Implementa o tema contemporâneo com gradientes, blur e animações |
1758
- | `corporate.theme.ts` | Implementa o tema corporativo com branding, dourado e layout executivo |
1759
- | `minimal.theme.ts` | Implementa o tema minimalista com layout enxuto e design system próprio |
1760
- | `template-factory.ts` | Registra e instancia os temas concretos por `ThemeType` |
1761
- | `template-builder.ts` | Aplica os tokens dos temas na construção final do HTML do email |
1762
-
1763
-
1764
- ---
1765
-
1766
- ## Primeiros passos e uso básico/Instalação, scripts de execução e artefatos publicados
1767
-
1768
- # Primeiros passos e uso básico
1769
-
1770
- *`package.json`, `tsconfig.json`, `src/index.ts`, `dist/index.js`, `dist/index.d.ts`*
1771
-
1772
- ## Visão geral
1773
-
1774
- A biblioteca é publicada como um pacote TypeScript centrado em **Node.js + SMTP/Nodemailer**, com artefatos prontos para consumo em `dist/`. O objetivo prático do primeiro uso é simples: instalar as dependências, compilar o projeto e consumir o ponto de entrada publicado sem depender do código-fonte em `src/`.
1775
-
1776
- O pacote declara `next` e `nodemailer` em `peerDependencies`, então o projeto que instala a biblioteca precisa resolver essas dependências por conta própria. Isso é relevante tanto para consumidores quanto para contribuidores, porque a saída compilada e os tipos publicados são o contrato real do pacote.
1777
-
1778
- ## Arquitetura de publicação
1779
-
1780
- ```mermaid
1781
- flowchart TB
1782
- subgraph Repo [tzMail]
1783
- Pkg[package json]
1784
- TsConfig[tsconfig json]
1785
- SrcIndex[src index ts]
1786
- Build[build]
1787
- Dev[dev]
1788
- Start[start]
1789
- Test[test]
1790
- Lint[lint]
1791
- DistJS[dist index js]
1792
- DistDTS[dist index d ts]
1793
- end
1794
-
1795
- subgraph Consumer [Projeto consumidor]
1796
- App[Aplicação Node.js ou Next.js]
1797
- NextDep[next peer dependency]
1798
- NodemailerDep[nodemailer peer dependency]
1799
- end
1800
-
1801
- Pkg --> Build
1802
- Pkg --> Dev
1803
- Pkg --> Start
1804
- Pkg --> Test
1805
- Pkg --> Lint
1806
-
1807
- TsConfig --> Build
1808
- SrcIndex --> Build
1809
-
1810
- Build --> DistJS
1811
- Build --> DistDTS
1812
-
1813
- App --> DistJS
1814
- App --> DistDTS
1815
- App --> NextDep
1816
- App --> NodemailerDep
1817
- ```
1818
-
1819
- ## Instalação
1820
-
1821
-
1822
- ```bash
1823
- npm install tzmail
1824
- ```
1825
-
1826
- ---
1827
-
1828
- ## Gerenciamento de Templates/Catálogo de temas e seleção por metadados
1829
-
1830
- # Gerenciamento de Templates - Catálogo de temas e seleção por metadados
1831
-
1832
- ## Visão geral
1833
-
1834
- Esta parte do projeto concentra o registro dos temas visuais disponíveis e a descoberta guiada por metadados para que a escolha do template seja feita antes da renderização. O fluxo começa em `TemplateFactory`, que mantém o catálogo concreto de temas, e continua em `TemplateService`, que expõe uma visão pronta para consumo com nome amigável, descrição, recursos, variantes suportadas e configuração padrão por tema.
1835
-
1836
- Na prática, esse catálogo permite que a aplicação apresente opções visuais coerentes ao usuário, sem exigir que ele conheça os detalhes internos de cada tema. O resultado é uma seleção mais previsível de `ThemeType`, `variant` e `ITemplateConfig`, com defaults específicos que orientam a composição correta do email.
1837
-
1838
- ## Arquitetura do catálogo de temas
1839
-
1840
- ```mermaid
1841
- flowchart TB
1842
- subgraph DemoApp [Servidor de Demonstração]
1843
- Demo[src index ts]
1844
- end
1845
-
1846
- subgraph Catalog [Catálogo de Temas]
1847
- Service[TemplateService]
1848
- Factory[TemplateFactory]
1849
- Registry[Map ThemeType to ITheme]
1850
- SystemTheme[SystemTheme]
1851
- MonokaiTheme[MonokaiTheme]
1852
- ModernTheme[ModernTheme]
1853
- CorporateTheme[CorporateTheme]
1854
- MinimalTheme[MinimalTheme]
1855
- Builder[TemplateBuilder]
1856
- end
1857
-
1858
- subgraph Metadata [Metadados para seleção]
1859
- ThemeInfo[getThemeInfo]
1860
- ThemeList[listThemes]
1861
- DefaultConfig[defaultConfig]
1862
- Variants[availableVariants]
1863
- end
1864
-
1865
- Demo -->|createTemplate| Service
1866
- Demo -->|getThemeInfo| Service
1867
- Demo -->|listThemes| Service
1868
-
1869
- Service -->|delegates| Factory
1870
- Service -->|adds metadata| Metadata
1871
-
1872
- Factory -->|resolves| Registry
1873
- Registry --> SystemTheme
1874
- Registry --> MonokaiTheme
1875
- Registry --> ModernTheme
1876
- Registry --> CorporateTheme
1877
- Registry --> MinimalTheme
1878
- Factory -->|builds template| Builder
1879
-
1880
- Factory --> ThemeInfo
1881
- Factory --> ThemeList
1882
- Service --> DefaultConfig
1883
- Service --> Variants
1884
- ```
1885
-
1886
- ## Componentes principais
1887
-
1888
- ### TemplateFactory
1889
-
1890
- *`src/factories/template-factory.ts`*
1891
-
1892
- `TemplateFactory` é o registro estático do catálogo de temas. Ela associa cada `ThemeType` a uma instância concreta de `ITheme`, resolve o tema solicitado, lista os temas cadastrados e produz o objeto de template usado pelo restante do fluxo.
1893
-
1894
- #### Propriedades
1895
-
1896
- | Propriedade | Tipo | Descrição |
1897
- | --- | --- | --- |
1898
- | `themes` | `Map<ThemeType, ITheme>` | Catálogo estático com `SystemTheme`, `MonokaiTheme`, `ModernTheme`, `CorporateTheme` e `MinimalTheme`. |
1899
-
1900
-
1901
- #### Métodos públicos
1902
-
1903
- | Método | Descrição |
1904
- | --- | --- |
1905
- | `createTemplate` | Resolve o tema pelo `ThemeType`, valida a existência no catálogo e retorna um `ITemplate` com `name`, `theme`, `variant`, `config` e `render`. |
1906
- | `getTheme` | Retorna a instância concreta de `ITheme` associada ao `ThemeType` solicitado. |
1907
- | `listThemes` | Retorna a lista de `ThemeType` atualmente registrados no catálogo. |
1908
- | `getThemeInfo` | Retorna metadados estáticos do tema: `name`, `description` e `features`. |
1909
-
1910
-
1911
- #### Registro de temas
1912
-
1913
- A ordem de `listThemes()` segue a ordem de inserção do `Map`:
1914
-
1915
- - `system`
1916
- - `monokai`
1917
- - `modern`
1918
- - `corporate`
1919
- - `minimal`
1920
-
1921
- #### Como o template é montado
1922
-
1923
- `createTemplate` produz um objeto com:
1924
-
1925
- - `name`: `${themeType}_${variant}`
1926
- - `theme`: o valor de `ThemeType`
1927
- - `variant`: `light` ou `dark`
1928
- - `config`: `ITemplateConfig`
1929
- - `render(data)`: função assíncrona que instancia `TemplateBuilder` e compõe o HTML final
1930
-
1931
- createTemplate lança Error('Theme ${themeType} not found') quando o ThemeType não está registrado no Map.
1932
-
1933
- ---
1934
-
1935
- ### TemplateService
1936
-
1937
- *`src/services/template.service.ts`*
1938
-
1939
- `TemplateService` é a fachada de uso principal para descoberta, criação, clonagem, pré-visualização, cache, histórico e exportação/importação de templates. É aqui que o catálogo da `TemplateFactory` ganha metadados adicionais para orientar a escolha visual correta.
1940
-
1941
- #### Propriedades
1942
-
1943
- | Propriedade | Tipo | Descrição |
1944
- | --- | --- | --- |
1945
- | `templateCache` | `Map<string, TemplateCache>` | Cache em memória dos templates criados. A chave é o identificador derivado de tema, variante e configuração. |
1946
- | `defaultTTL` | `number` | TTL padrão em segundos para entradas do cache. |
1947
- | `templateHistory` | `Map<string, ITemplate[]>` | Histórico de versões por identificador de template. |
1948
- | `options` | `TemplateOptions` | Opções efetivas da instância, mescladas com os padrões do construtor. |
1949
-
1950
-
1951
- #### Dependências do construtor
1952
-
1953
- | Type | Description |
1954
- | --- | --- |
1955
- | `TemplateOptions` | Configuração inicial da instância para cache, TTL, validação, minificação e modo de preview. |
1956
-
1957
-
1958
- #### Métodos públicos
1959
-
1960
- | Método | Descrição |
1961
- | --- | --- |
1962
- | `createTemplate` | Valida a configuração, calcula o identificador do template, reutiliza cache quando aplicável, cria o template pela `TemplateFactory` e adiciona extensões de metadados. |
1963
- | `cloneTemplate` | Cria um novo template a partir de um template existente aplicando `modifications` por spread superficial em `config`. |
1964
- | `renderTemplate` | Injeta metadados de renderização em `_meta`, renderiza o template, minifica o HTML e encapsula erros com mensagem contextual. |
1965
- | `previewTemplate` | Cria um template sem cache e renderiza em modo de pré-visualização. |
1966
- | `getThemeInfo` | Combina os metadados estáticos do tema com `availableVariants` e `defaultConfig`. |
1967
- | `listThemes` | Expõe a lista de `ThemeType` do catálogo. |
1968
- | `getTemplateStats` | Consolida estatísticas de uso: total de templates, cache, hits, distribuição por tema e taxa de acerto. |
1969
- | `clearCache` | Limpa todo o cache ou apenas as entradas de um `ThemeType`. |
1970
- | `getTemplateHistory` | Retorna o histórico de versões de um template por `templateId`. |
1971
- | `restoreTemplateVersion` | Restaura uma versão anterior a partir do histórico. |
1972
- | `preloadTemplates` | Pré-carrega vários templates em paralelo para popular o cache. |
1973
- | `exportTemplate` | Serializa um template em JSON com `name`, `theme`, `variant`, `config`, `exportedAt` e `version`. |
1974
- | `importTemplate` | Reconstrói um template a partir de JSON validando campos obrigatórios. |
1975
- | `generateExampleTemplate` | Gera um template demonstrativo com defaults coerentes com o tema e a variante. |
1976
- | `isValidTemplate` | Valida a forma estrutural de um objeto candidato a template. |
1977
- | `getTemplateDetails` | Retorna detalhes consolidados de cache, histórico e uso para um `templateId`. |
1978
-
1979
-
1980
- #### Extensões adicionadas ao template criado
1981
-
1982
- O objeto retornado por `createTemplate` é enriquecido em runtime com estes métodos:
1983
-
1984
- | Método adicionado | Descrição |
1985
- | --- | --- |
1986
- | `getVersion` | Retorna o número de versões registradas no histórico daquele `templateId`. |
1987
- | `getId` | Retorna o identificador gerado para o template. |
1988
- | `clone` | Cria uma nova versão do template com modificações parciais de configuração. |
1989
-
1990
-
1991
- #### Regras de validação aplicadas por `createTemplate`
1992
-
1993
- A validação é executada quando `validateConfig` está ativo nas opções da instância ou da chamada:
1994
-
1995
- - `header.logo.type === 'image'` exige `imageUrl`
1996
- - `header.logo.type === 'text'` exige `text`
1997
- - `footer.links` exige `text` e `url` em cada item
1998
- - `layout` aceita `full` ou `minimal`
1999
- - `spacing` aceita `compact`, `normal` ou `relaxed`
2000
- - `borderRadius` aceita `none`, `small`, `medium` ou `large`
2001
-
2002
- #### Configuração padrão do serviço
2003
-
2004
- `TemplateOptions` aceita:
2005
-
2006
- | Propriedade | Tipo | Descrição |
2007
- | --- | --- | --- |
2008
- | `cache?` | `boolean` | Liga ou desliga o cache de templates. |
2009
- | `cacheTTL?` | `number` | TTL em segundos para as entradas do cache. |
2010
- | `validateConfig?` | `boolean` | Ativa a validação da configuração do template. |
2011
- | `minify?` | `boolean` | Ativa a minificação do HTML final. |
2012
- | `preview?` | `boolean` | Marca a renderização como prévia. |
2013
-
2014
-
2015
- Os valores aplicados pelo construtor são:
2016
-
2017
- - `cache: true`
2018
- - `cacheTTL: 3600`
2019
- - `validateConfig: true`
2020
- - `minify: true`
2021
- - `preview: false`
2022
-
2023
- ---
2024
-
2025
- ### TemplateCache
2026
-
2027
- *`src/services/template.service.ts`*
2028
-
2029
- Interface interna usada pelo cache em memória.
2030
-
2031
- | Propriedade | Tipo | Descrição |
2032
- | --- | --- | --- |
2033
- | `template` | `ITemplate` | Template armazenado no cache. |
2034
- | `createdAt` | `Date` | Data de criação da entrada. |
2035
- | `expiresAt` | `Date` | Momento em que a entrada expira. |
2036
- | `hits` | `number` | Contador de acessos ao template em cache. |
2037
-
2038
-
2039
- ---
2040
-
2041
- ### ThemeType
2042
-
2043
- *`src/core/enums/theme.enum.ts`*
2044
-
2045
- Enumeração do catálogo de temas.
2046
-
2047
- Valores: `system`, `monokai`, `modern`, `corporate`, `minimal`.
2048
-
2049
- ---
2050
-
2051
- ### ITheme
2052
-
2053
- *`src/templates/themes/theme.interface.ts`*
2054
-
2055
- Contrato implementado pelos temas concretos registrados no catálogo.
2056
-
2057
- | Propriedade | Tipo | Descrição |
2058
- | --- | --- | --- |
2059
- | `id` | `ThemeType` | Identificador do tema. |
2060
- | `name` | `string` | Nome legível do tema. |
2061
- | `light` | `IThemeColors` | Paleta para variante clara. |
2062
- | `dark` | `IThemeColors` | Paleta para variante escura. |
2063
- | `typography` | `ITypography` | Tipografia base do tema. |
2064
- | `spacing` | `ISpacing` | Sistema de espaçamento do tema. |
2065
-
2066
-
2067
- ### IThemeColors
2068
-
2069
- *`src/templates/themes/theme.interface.ts`*
2070
-
2071
- | Propriedade | Tipo | Descrição |
2072
- | --- | --- | --- |
2073
- | `primary` | `string` | Cor primária do tema. |
2074
- | `secondary` | `string` | Cor secundária do tema. |
2075
- | `background` | `string` | Cor de fundo. |
2076
- | `text` | `string` | Cor principal do texto. |
2077
- | `textMuted` | `string` | Cor para texto secundário ou suavizado. |
2078
- | `border` | `string` | Cor de bordas. |
2079
- | `success` | `string` | Cor de sucesso. |
2080
- | `error` | `string` | Cor de erro. |
2081
- | `warning` | `string` | Cor de aviso. |
2082
-
2083
-
2084
- ### ITypography
2085
-
2086
- *`src/templates/themes/theme.interface.ts`*
2087
-
2088
- | Propriedade | Tipo | Descrição |
2089
- | --- | --- | --- |
2090
- | `fontFamily` | `string` | Família tipográfica base. |
2091
- | `fontSizes.small` | `string` | Tamanho pequeno. |
2092
- | `fontSizes.medium` | `string` | Tamanho médio. |
2093
- | `fontSizes.large` | `string` | Tamanho grande. |
2094
- | `fontSizes.xlarge` | `string` | Tamanho extra grande. |
2095
- | `fontWeights.normal` | `number` | Peso normal. |
2096
- | `fontWeights.medium` | `number` | Peso médio. |
2097
- | `fontWeights.bold` | `number` | Peso negrito. |
2098
-
2099
-
2100
- ### ISpacing
2101
-
2102
- *`src/templates/themes/theme.interface.ts`*
2103
-
2104
- | Propriedade | Tipo | Descrição |
2105
- | --- | --- | --- |
2106
- | `xs` | `string` | Espaçamento extra pequeno. |
2107
- | `sm` | `string` | Espaçamento pequeno. |
2108
- | `md` | `string` | Espaçamento médio. |
2109
- | `lg` | `string` | Espaçamento grande. |
2110
- | `xl` | `string` | Espaçamento extra grande. |
2111
-
2112
-
2113
- ---
2114
-
2115
- ### ITemplate
2116
-
2117
- *`src/core/interfaces/template.interface.ts`*
2118
-
2119
- Contrato do objeto retornado por `TemplateFactory.createTemplate` e `TemplateService.createTemplate`.
2120
-
2121
- | Propriedade | Tipo | Descrição |
2122
- | --- | --- | --- |
2123
- | `name` | `string` | Nome do template, gerado como `${themeType}_${variant}`. |
2124
- | `theme` | `ThemeType` | Tema associado ao template. |
2125
- | `variant` | `'light` `'dark'` | Variante visual aplicada. |
2126
- | `config` | `ITemplateConfig` | Configuração estrutural do template. |
2127
- | `render` | `(data: any) => Promise<string>` | Função assíncrona que produz o HTML final. |
2128
-
2129
-
2130
- ### ITemplateConfig
2131
-
2132
- *`src/core/interfaces/template.interface.ts`*
2133
-
2134
- | Propriedade | Tipo | Descrição |
2135
- | --- | --- | --- |
2136
- | `header?` | `IHeaderConfig` | Configuração do cabeçalho. |
2137
- | `body?` | `IBodyConfig` | Configuração do conteúdo principal. |
2138
- | `footer?` | `IFooterConfig` | Configuração do rodapé. |
2139
- | `layout?` | `'full'` `'minimal'` | Layout do email. |
2140
- | `spacing?` | `'compact'` `'normal'` `'relaxed'` | Densidade visual. |
2141
- | `borderRadius?` | `'none'` `'small` `'medium'` `'large'` | Raio de borda aplicado ao layout. |
2142
-
2143
-
2144
- ### IHeaderConfig
2145
-
2146
- *`src/core/interfaces/template.interface.ts`*
2147
-
2148
- | Propriedade | Tipo | Descrição |
2149
- | --- | --- | --- |
2150
- | `show` | `boolean` | Controla a exibição do cabeçalho. |
2151
- | `logo?` | `{ type: 'text' 'image'; text?: string; imageUrl?: string; alt?: string; size?: 'small' 'medium' 'large' }` | Configuração do logo. |
2152
- | `backgroundColor?` | `string` | Cor de fundo do cabeçalho. |
2153
- | `textColor?` | `string` | Cor do texto do cabeçalho. |
2154
-
2155
-
2156
- ### IBodyConfig
2157
-
2158
- *`src/core/interfaces/template.interface.ts`*
2159
-
2160
- | Propriedade | Tipo | Descrição |
2161
- | --- | --- | --- |
2162
- | `title?` | `string` | Título exibido no corpo. |
2163
- | `message?` | `string` | Mensagem principal. |
2164
- | `content?` | `string` | Conteúdo HTML bruto, quando fornecido. |
2165
- | `buttonText?` | `string` | Texto do botão principal. |
2166
- | `buttonUrl?` | `string` | URL do botão principal. |
2167
- | `buttonVariant?` | `'primary'` `'secondary'` `'success'` `'danger'` | Variante visual do botão. |
2168
- | `alignment?` | `'left'` `center'` `'right'` | Alinhamento do conteúdo. |
2169
- | `backgroundColor?` | `string` | Cor de fundo do corpo. |
2170
- | `textColor?` | `string` | Cor do texto do corpo. |
2171
- | `fontSize?` | `number` | Tamanho base da fonte. |
2172
-
2173
-
2174
- ### IFooterConfig
2175
-
2176
- *`src/core/interfaces/template.interface.ts`*
2177
-
2178
- | Propriedade | Tipo | Descrição |
2179
- | --- | --- | --- |
2180
- | `show` | `boolean` | Controla a exibição do rodapé. |
2181
- | `links?` | `Array<{ text: string; url: string }>` | Links institucionais ou de navegação. |
2182
- | `socialLinks?` | `Array<{ platform: 'facebook' 'twitter' 'linkedin' 'github'; url: string }>` | Links sociais com ícones. |
2183
- | `copyrightText?` | `string` | Texto de copyright. |
2184
- | `unsubscribeText?` | `string` | Texto do link de descadastro. |
2185
- | `backgroundColor?` | `string` | Cor de fundo do rodapé. |
2186
- | `textColor?` | `string` | Cor do texto do rodapé. |
2187
-
2188
-
2189
- ## Catálogo de temas e metadados
2190
-
2191
- ### Temas registrados
2192
-
2193
- `TemplateFactory.listThemes()` expõe os temas registrados no `Map` estático e retorna:
2194
-
2195
- - `system`
2196
- - `monokai`
2197
- - `modern`
2198
- - `corporate`
2199
- - `minimal`
2200
-
2201
- ### Metadados retornados por `TemplateFactory.getThemeInfo`
2202
-
2203
- | `ThemeType` | `name` | `description` | `features` |
2204
- | --- | --- | --- | --- |
2205
- | `system` | `System` | `Tema limpo e profissional com cores adaptativas` | `Design minimalista`, `Alta acessibilidade`, `Compatibilidade total` |
2206
- | `monokai` | `Monokai` | `Inspirado no famoso tema de código, ideal para conteúdo técnico` | `Cores vibrantes`, `Destaque de sintaxe`, `Efeitos glow` |
2207
- | `modern` | `Modern` | `Design contemporâneo com gradientes e efeitos modernos` | `Gradientes elegantes`, `Glassmorphism`, `Animações suaves` |
2208
- | `corporate` | `Corporate` | `Design profissional e elegante para empresas` | `Tipografia serifada`, `Detalhes em dourado`, `Layout estruturado` |
2209
- | `minimal` | `Minimal` | `Design clean e focado no conteúdo` | `Sem distrações`, `Espaçamento generoso`, `Tipografia limpa` |
2210
-
2211
-
2212
- ### Metadados extras adicionados por `TemplateService.getThemeInfo`
2213
-
2214
- `TemplateService.getThemeInfo(themeType)` retorna:
2215
-
2216
- | Campo | Descrição |
2217
- | --- | --- |
2218
- | `name` | Nome amigável do tema. |
2219
- | `description` | Descrição curta para exibição em catálogo. |
2220
- | `features` | Lista de características destacadas. |
2221
- | `availableVariants` | Sempre `light` e `dark`. |
2222
- | `defaultConfig` | Configuração padrão sugerida para o tema. |
2223
-
2224
-
2225
- ### Variantes suportadas
2226
-
2227
- Todas as entradas do catálogo expõem:
2228
-
2229
- - `light`
2230
- - `dark`
2231
-
2232
- ### Configuração padrão por tema
2233
-
2234
- `TemplateService.getDefaultConfigForTheme` parte de uma base comum:
2235
-
2236
- | Campo | Valor base |
2237
- | --- | --- |
2238
- | `header.show` | `true` |
2239
- | `header.logo.type` | `text` |
2240
- | `header.logo.text` | `MyApp` |
2241
- | `header.logo.size` | `medium` |
2242
- | `footer.show` | `true` |
2243
- | `footer.copyrightText` | `© {ano atual} MyApp. All rights reserved.` |
2244
- | `layout` | `full` |
2245
- | `spacing` | `normal` |
2246
- | `borderRadius` | `medium` |
2247
-
2248
-
2249
- Ajustes específicos por tema:
2250
-
2251
- | Tema | `borderRadius` | `spacing` | Observação |
2252
- | --- | --- | --- | --- |
2253
- | `system` | `medium` | `normal` | Usa a base comum. |
2254
- | `monokai` | `small` | `normal` | Ajuste mais contido. |
2255
- | `modern` | `large` | `relaxed` | Visual mais espaçado. |
2256
- | `corporate` | `small` | `normal` | Mantém formalidade visual. |
2257
- | `minimal` | `none` | `relaxed` | Reduz a ornamentação. |
2258
-
2259
-
2260
- ## Fluxo de descoberta e seleção
2261
-
2262
- ### Descoberta de temas
2263
-
2264
- 1. A interface chama `TemplateService.listThemes()`.
2265
- 2. O serviço delega para `TemplateFactory.listThemes()`.
2266
- 3. A lista de `ThemeType` é usada para popular cards, dropdowns ou etapas de seleção.
2267
-
2268
- ### Resolução de metadados
2269
-
2270
- 1. A UI chama `TemplateService.getThemeInfo(themeType)`.
2271
- 2. `TemplateService` busca o texto de apresentação com `TemplateFactory.getThemeInfo(themeType)`.
2272
- 3. O serviço busca a instância concreta com `TemplateFactory.getTheme(themeType)`.
2273
- 4. O resultado é enriquecido com `availableVariants` e `defaultConfig`.
2274
- 5. A interface pode usar esses dados para orientar a escolha do layout e pré-preencher controles.
2275
-
2276
- ### Criação do template selecionado
2277
-
2278
- 1. O usuário escolhe `ThemeType`, `variant` e configurações.
2279
- 2. `TemplateService.createTemplate()` valida `ITemplateConfig`.
2280
- 3. O identificador do template é gerado a partir de tema, variante e JSON da configuração.
2281
- 4. Se houver cache válido para a mesma combinação, a instância é reutilizada.
2282
- 5. Caso contrário, `TemplateFactory.createTemplate()` resolve o tema e gera o template.
2283
- 6. O template é enriquecido com `getVersion`, `getId` e `clone`.
2284
- 7. O resultado é armazenado em cache e no histórico.
2285
-
2286
- ```mermaid
2287
- sequenceDiagram
2288
- participant U as Usuario
2289
- participant S as TemplateService
2290
- participant F as TemplateFactory
2291
- participant T as Tema concreto
2292
- participant B as TemplateBuilder
2293
-
2294
- U->>S: listThemes
2295
- S->>F: listThemes
2296
- F-->>S: ThemeType Array
2297
- S-->>U: lista de temas
2298
-
2299
- U->>S: getThemeInfo themeType
2300
- S->>F: getThemeInfo themeType
2301
- F-->>S: name description features
2302
- S->>F: getTheme themeType
2303
- F-->>S: ITheme
2304
- S-->>U: name description features availableVariants defaultConfig
2305
-
2306
- U->>S: createTemplate themeType variant config
2307
- S->>S: validateTemplateConfig
2308
- S->>S: generateTemplateId
2309
- S->>F: createTemplate themeType variant config
2310
- F->>T: resolve tema registrado
2311
- F->>B: new TemplateBuilder theme config variant
2312
- B-->>F: HTML final via render
2313
- F-->>S: ITemplate
2314
- S-->>U: template enriquecido e cacheado
2315
- ```
2316
-
2317
- ## Estado, cache e histórico
2318
-
2319
- ### Cache de templates
2320
-
2321
- TemplateFactory.createTemplate lê body a partir de data.template.config.body, mas TemplateService.renderTemplate repassa data sem anexar template. Quando a renderização é feita diretamente por renderTemplate, o corpo usa os fallbacks internos, a menos que o chamador já tenha incluído template em data.
2322
-
2323
- - Chave do cache: `themeType_variant_hash`
2324
- - Fonte do hash: `JSON.stringify({ theme, variant, config })`
2325
- - Persistência: `Map<string, TemplateCache>`
2326
- - TTL padrão: `3600` segundos
2327
- - Limpeza automática: `setInterval(..., 3600000)` no construtor
2328
-
2329
- ### Regras de uso do cache
2330
-
2331
- - `createTemplate()` reutiliza a entrada quando a chave já existe.
2332
- - `previewTemplate()` cria template com `cache: false`.
2333
- - `restoreTemplateVersion()` recria a versão restaurada com `cache: false`.
2334
- - `clearCache(themeType?)` remove por tema ou apaga tudo.
2335
-
2336
- ### Histórico de versões
2337
-
2338
- createTemplate() verifica apenas a presença da chave no Map. A remoção de entradas expiradas acontece pelo limpador periódico, então uma entrada vencida pode continuar sendo usada até a próxima limpeza.
2339
-
2340
- - Cada `templateId` mantém um array em `templateHistory`.
2341
- - `addToHistory()` preserva apenas as últimas 10 versões.
2342
- - `getTemplateHistory(templateId)` retorna o histórico salvo.
2343
- - `restoreTemplateVersion(templateId, versionIndex)` recria uma versão anterior com o mesmo `theme`, `variant` e `config`.
2344
-
2345
- ### Estatísticas expostas
2346
-
2347
- `getTemplateStats()` consolida:
2348
-
2349
- - `totalTemplates`
2350
- - `cachedTemplates`
2351
- - `totalHits`
2352
- - `templatesByTheme`
2353
- - `cacheHitRate`
2354
-
2355
- `getTemplateDetails(templateId)` retorna:
2356
-
2357
- - `template`
2358
- - `history`
2359
- - `cacheInfo`
2360
- - `usageCount`
2361
-
2362
- ## Tratamento de erros
2363
-
2364
- | Origem | Condição | Efeito |
2365
- | --- | --- | --- |
2366
- | `TemplateFactory.createTemplate` | Tema não encontrado no catálogo | Lança `Error('Theme ${themeType} not found')`. |
2367
- | `TemplateService.validateTemplateConfig` | Configuração inválida | Lança `Error('Template configuration validation failed:\n...')`. |
2368
- | `TemplateService.renderTemplate` | Falha durante renderização ou minificação | Lança `Error('Failed to render template: ...')`. |
2369
- | `TemplateService.importTemplate` | JSON inválido ou campos obrigatórios ausentes | Lança `Error('Failed to import template: ...')`. |
2370
- | `TemplateService.restoreTemplateVersion` | Histórico inexistente ou índice fora do intervalo | Retorna `null`. |
2371
-
2372
-
2373
- ## Integração com a demonstração Express
2374
-
2375
- TemplateService.getThemeInfo assume que TemplateFactory.getThemeInfo(themeType) devolve um objeto. Se um valor inválido for passado em tempo de execução, o spread de undefined provoca falha antes de availableVariants e defaultConfig serem montados.
2376
-
2377
- *`src/index.ts`*
2378
-
2379
- A demonstração local usa o catálogo para montar exemplos prontos com temas diferentes e variantes distintas:
2380
-
2381
- - `ThemeType.MODERN` com `light`
2382
- - `ThemeType.MONOKAI` com `light`
2383
- - `ThemeType.CORPORATE` com `dark`
2384
- - `ThemeType.MINIMAL` com `dark`
2385
-
2386
- Ela também expõe um endpoint de teste que envia a newsletter minimalista com anexo local.
2387
-
2388
- #### Executar envio de newsletter minimalista
2389
-
2390
- ```api
2391
- {
2392
- "title": "Executar envio de newsletter minimalista",
2393
- "description": "Rota de demonstra\u00e7\u00e3o que dispara o envio de email com o template minimalista e um anexo carregado de disco",
2394
- "method": "GET",
2395
- "baseUrl": "<DemoServerBaseUrl>",
2396
- "endpoint": "/test",
2397
- "headers": [],
2398
- "queryParams": [],
2399
- "pathParams": [],
2400
- "bodyType": "none",
2401
- "requestBody": "",
2402
- "formData": [],
2403
- "rawBody": "",
2404
- "responses": {
2405
- "200": {
2406
- "description": "Resultado retornado por sendMinimalNewsletter e repassado pelo res.json",
2407
- "body": "{\n \"success\": true,\n \"messageId\": \"abc123def456\",\n \"response\": \"250 2.0.0 OK queued as 12345\"\n}"
2408
- }
2409
- }
2410
- }
2411
- ```
2412
-
2413
- ## Referência rápida dos temas
2414
-
2415
- | Tema | Nome | Melhor uso |
2416
- | --- | --- | --- |
2417
- | `system` | System | Emails neutros e adaptativos. |
2418
- | `monokai` | Monokai | Conteúdo técnico e newsletters para desenvolvedores. |
2419
- | `modern` | Modern | Campanhas com estética contemporânea. |
2420
- | `corporate` | Corporate | Comunicação institucional e executiva. |
2421
- | `minimal` | Minimal | Mensagens focadas em conteúdo e legibilidade. |
2422
-
2423
-
2424
- ## Key Classes Reference
2425
-
2426
- O handler de /test não aplica autenticação nem validação adicional. Ele chama sendMinimalNewsletter('antiquesclub007@gmail.com'), carrega via AttachmentService.addFromPath e devolve o resultado bruto do envio.
2427
-
2428
- | Class | Responsibility |
2429
- | --- | --- |
2430
- | `template-factory.ts` | Registra, resolve e instancia os temas concretos do catálogo. |
2431
- | `template.service.ts` | Expõe descoberta de temas, metadados, cache, histórico e criação de templates. |
2432
- | `theme.enum.ts` | Define os identificadores `ThemeType` aceitos pelo catálogo. |
2433
- | `theme.interface.ts` | Define o contrato dos temas e das estruturas visuais associadas. |
2434
- | `template.interface.ts` | Define o contrato do template e das configurações estruturais usadas na seleção. |
2435
- | `index.ts` | Demonstra o uso dos temas e expõe a rota `/test` do servidor de teste. |
2436
-
2437
-
2438
- ---
2439
-
2440
- ## Primeiros passos e uso básico/Servidor de demonstração e exemplos guiados
2441
-
2442
- # Primeiros passos e uso básico - Servidor de demonstração e exemplos guiados
2443
-
2444
- ## Visão geral
2445
-
2446
- Este trecho do projeto transforma em um laboratório executável para ver a biblioteca funcionando em runtime real. O arquivo sobe um servidor Express, carrega variáveis com `dotenv`, inicializa o `EmailFactory` com SMTP, cria templates prontos para uso e expõe uma rota de teste que dispara um envio de email de ponta a ponta.
2447
-
2448
- Para quem está começando, este é o caminho mais rápido para entender como a biblioteca compõe tema, template, anexo e transporte SMTP. Os exemplos `sendWelcomeEmail`, `sendTechNewsletter`, `sendCorporateReport` e `sendMinimalNewsletter` mostram quatro perfis de uso distintos: boas-vindas, newsletter técnica, relatório corporativo e newsletter mínima com anexo.
2449
-
2450
- ## Servidor de demonstração em
2451
-
2452
- *Arquivo: `src/index.ts`*
2453
-
2454
- O arquivo atua em duas funções ao mesmo tempo: é o ponto de entrada do servidor de demonstração e também o barrel de exportação pública do pacote. A sequência visível no código é:
2455
-
2456
- - `dotenv.config()` é executado no topo do módulo.
2457
- - O servidor cria `app` com `express()`.
2458
- - `PORT` é fixado em `3001`.
2459
- - O middleware `express.json()` e `express.urlencoded({ extended: true })` é ativado.
2460
- - `SMTP_CONFIG` é montado com `process.env.SMTP_USER` e `process.env.SMTP_PASS`.
2461
- - `EmailFactory.initialize(SMTP_CONFIG)` cria a instância única usada no laboratório.
2462
- - `templateService` é obtido via `emailFactory.getTemplateService()`.
2463
- - Quatro templates de demonstração são criados com `templateService.createTemplate(...)`.
2464
- - A rota `GET /test` chama `sendMinimalNewsletter('antiquesclub007@gmail.com')`.
2465
- - `app.listen(PORT)` inicia o processo na porta `3001`.
2466
-
2467
- ### Exportações públicas do arquivo
2468
-
2469
- O mesmo arquivo também reexporta os símbolos centrais do pacote para consumo a partir da raiz.
2470
-
2471
- | Símbolo | Finalidade |
2472
- | --- | --- |
2473
- | `EmailFactory` | Fachada principal para configurar SMTP e enviar emails |
2474
- | `TemplateFactory` | Criação direta de templates por tema |
2475
- | `ITemplate` | Contrato de template renderizável |
2476
- | `ITemplateConfig` | Contrato de configuração do template |
2477
- | `ThemeType` | Enum de temas |
2478
- | `ITheme` | Contrato base dos temas |
2479
- | `TemplateService` | Criação, cache, renderização e inspeção de templates |
2480
- | `EmailService` | Envio real via Nodemailer |
2481
- | `AttachmentService` | Montagem de anexos |
2482
- | `TemplateBuilder` | Montagem do HTML final do email |
2483
- | `CorporateTheme` | Tema corporativo |
2484
- | `MinimalTheme` | Tema minimalista |
2485
- | `ModernTheme` | Tema moderno |
2486
- | `MonokaiTheme` | Tema técnico estilo editor |
2487
- | `SystemTheme` | Tema base do sistema |
2488
-
2489
-
2490
- ### Configuração SMTP usada no laboratório
2491
-
2492
- | Campo | Valor no código | Observação |
2493
- | --- | --- | --- |
2494
- | `host` | `smtp.gmail.com` | Host SMTP de demonstração |
2495
- | `port` | `587` | Porta usada no exemplo |
2496
- | `secure` | `false` | Conexão não TLS implícita |
2497
- | `auth.user` | `process.env.SMTP_USER!` | Vem do `.env` carregado por `dotenv` |
2498
- | `auth.pass` | `process.env.SMTP_PASS!` | Vem do `.env` carregado por `dotenv` |
2499
- | `defaultFrom` | `LyraX Corp <lyrax.com@gmail.com>` | Remetente padrão aplicado quando `from` não é informado |
2500
-
2501
-
2502
- ## Fluxo de inicialização do servidor
2503
-
2504
- ```mermaid
2505
- sequenceDiagram
2506
- participant Runtime as Node Runtime
2507
- participant Dotenv as dotenv
2508
- participant Index as src index ts
2509
- participant Factory as EmailFactory
2510
- participant Transport as Nodemailer
2511
- participant ExpressApp as Express App
2512
-
2513
- Runtime->>Dotenv: config
2514
- Dotenv-->>Runtime: variaveis carregadas
2515
- Runtime->>Index: executar modulo
2516
- Index->>Factory: initialize SMTP_CONFIG
2517
- Factory->>Transport: createTransport
2518
- Factory-->>Index: instancia inicializada
2519
- Index->>ExpressApp: criar app e middlewares
2520
- Index->>ExpressApp: registrar GET test
2521
- Index->>ExpressApp: listen 3001
2522
- ExpressApp-->>Runtime: servidor pronto
2523
- ```
2524
-
2525
- ### O que acontece na inicialização
2526
-
2527
- O laboratório envia emails reais pela configuração SMTP definida em . A rota GET /test não é um simulador: ela dispara o fluxo completo de envio usando o destinatário fixo antiquesclub007@gmail.com.
2528
-
2529
- 1. `dotenv.config()` carrega `SMTP_USER` e `SMTP_PASS` antes da criação do `SMTP_CONFIG`.
2530
- 2. `EmailFactory.initialize(SMTP_CONFIG)` instancia `EmailService`, `TemplateService` e `AttachmentService`.
2531
- 3. Os templates de demonstração são montados uma vez na subida do processo.
2532
- 4. O servidor Express começa a escutar na porta `3001`.
2533
- 5. O console imprime a mensagem de boot com a URL local.
2534
-
2535
- ## Endpoint HTTP de demonstração
2536
-
2537
- #### Testar newsletter minimalista
2538
-
2539
- ```api
2540
- {
2541
- "title": "Testar newsletter minimalista",
2542
- "description": "Dispara o fluxo completo de envio usado no laborat\u00f3rio, chamando sendMinimalNewsletter com destinat\u00e1rio fixo e retornando o resultado bruto do envio",
2543
- "method": "GET",
2544
- "baseUrl": "<DemoServerBaseUrl>",
2545
- "endpoint": "/test",
2546
- "headers": [],
2547
- "queryParams": [],
2548
- "pathParams": [],
2549
- "bodyType": "none",
2550
- "requestBody": "",
2551
- "formData": [],
2552
- "rawBody": "",
2553
- "responses": {
2554
- "200": {
2555
- "description": "Resultado retornado por sendMinimalNewsletter",
2556
- "body": "{\n \"success\": true,\n \"messageId\": \"message-id-example\",\n \"response\": \"250 2.0.0 OK queued as example\"\n}"
2557
- }
2558
- }
2559
- }
2560
- ```
2561
-
2562
- ## Exemplos guiados de envio
2563
-
2564
- A rota GET /test chama sendMinimalNewsletter('antiquesclub007@gmail.com') diretamente. O handler não abre um modo de pré-visualização nem faz mock do SMTP; ele usa a implementação real de anexos, template e envio.
2565
-
2566
- Os quatro exemplos abaixo são funções internas do laboratório em . Todas seguem o mesmo padrão geral: log no console, construção de `options` e chamada de `emailFactory.sendEmail(...)`.
2567
-
2568
- | Função | Tema | Variante | Assunto | Particularidade |
2569
- | --- | --- | --- | --- | --- |
2570
- | `sendWelcomeEmail` | `ThemeType.MODERN` | `light` | `Bem-vindo ao Meu App!` | Usa `modernTemplate` sem anexos |
2571
- | `sendTechNewsletter` | `ThemeType.MONOKAI` | `light` | `DevHub Newsletter - Novidades da Semana` | Usa conteúdo com trecho de código em destaque |
2572
- | `sendCorporateReport` | `ThemeType.CORPORATE` | `dark` | `Relatório Trimestral - Q4 2024` | Usa `corporateTemplate` em modo escuro |
2573
- | `sendMinimalNewsletter` | `ThemeType.MINIMAL` | `dark` | `Pensamentos sobre design` | Usa anexo carregado de |
2574
-
2575
-
2576
- ### `sendWelcomeEmail`
2577
-
2578
- Envia uma mensagem de boas-vindas usando o tema `MODERN` no modo `light`. O template criado para este caso inclui cabeçalho com logo de imagem, corpo centralizado, botão de ação e rodapé com links e redes sociais.
2579
-
2580
- **Uso interno no laboratório**
2581
-
2582
- - `subject`: `Bem-vindo ao Meu App!`
2583
- - `template`: `modernTemplate`
2584
- - `to`: parâmetro da função
2585
-
2586
- ### `sendTechNewsletter`
2587
-
2588
- Envia a newsletter técnica com o tema `MONOKAI`. O conteúdo do corpo inclui texto multilinha e um bloco `<code>`, que é processado visualmente pelo builder do tema Monokai.
2589
-
2590
- **Uso interno no laboratório**
2591
-
2592
- - `subject`: `DevHub Newsletter - Novidades da Semana`
2593
- - `template`: `monokaiTemplate`
2594
- - `to`: parâmetro da função
2595
-
2596
- ### `sendCorporateReport`
2597
-
2598
- Envia um relatório corporativo usando `ThemeType.CORPORATE` em `dark`. O template foi montado para uso mais formal, com tipografia serifada, destaque dourado e links institucionais no rodapé.
2599
-
2600
- **Uso interno no laboratório**
2601
-
2602
- - `subject`: `Relatório Trimestral - Q4 2024`
2603
- - `template`: `corporateTemplate`
2604
- - `to`: parâmetro da função
2605
-
2606
- ### `sendMinimalNewsletter`
2607
-
2608
- É o exemplo mais completo do laboratório. Além do template minimalista, ele cria um anexo a partir do sistema de arquivos com `AttachmentService.addFromPath('uploads/PHOTO.jpg')`.
2609
-
2610
- **Uso interno no laboratório**
2611
-
2612
- - `subject`: `Pensamentos sobre design`
2613
- - `template`: `minimalTemplate`
2614
- - `to`: parâmetro da função
2615
- - `attachments`: array com o anexo retornado por `addFromPath`
2616
-
2617
- ## Componentes centrais usados pelo laboratório
2618
-
2619
- ### `EmailFactory`
2620
-
2621
- *Arquivo: `src/factories/email-factory.ts`*
2622
-
2623
- A `EmailFactory` é a fachada de orquestração do envio. Ela centraliza a criação do `transporter` do Nodemailer, instancia o serviço de email, expõe o serviço de templates e entrega o serviço de anexos.
2624
-
2625
- #### Propriedades
2626
-
2627
- | Propriedade | Tipo | Descrição |
2628
- | --- | --- | --- |
2629
- | `instance` | `EmailFactory` | Instância singleton mantida pela fábrica |
2630
- | `emailService` | `EmailService` | Serviço responsável pelo envio efetivo |
2631
- | `templateService` | `TemplateService` | Serviço de criação e renderização de templates |
2632
- | `attachmentService` | `AttachmentService` | Serviço de montagem de anexos |
2633
-
2634
-
2635
- #### Dependências do construtor
2636
-
2637
- | Tipo | Descrição |
2638
- | --- | --- |
2639
- | `IEmailConfig` | Configuração SMTP entregue ao Nodemailer |
2640
- | `any` | Opções adicionais repassadas ao `TemplateService` |
2641
-
2642
-
2643
- #### Métodos públicos
2644
-
2645
- | Método | Descrição |
2646
- | --- | --- |
2647
- | `initialize` | Cria a instância singleton da fábrica |
2648
- | `getInstance` | Retorna a instância já inicializada |
2649
- | `sendEmail` | Encaminha o envio para `EmailService.send` |
2650
- | `getTemplateService` | Expõe a instância de `TemplateService` |
2651
- | `getAttachmentService` | Expõe a instância de `AttachmentService` |
2652
- | `previewTemplate` | Renderiza um template em modo de pré-visualização |
2653
- | `getThemeInfo` | Consulta informações de um tema |
2654
- | `listThemes` | Lista os temas disponíveis |
2655
- | `getTemplateStats` | Retorna estatísticas do uso de templates |
2656
-
2657
-
2658
- #### Fluxo de uso
2659
-
2660
- 1. `EmailFactory.initialize(SMTP_CONFIG)` cria o transporter com `nodemailer.createTransport(config)`.
2661
- 2. O construtor instancia `EmailService`, `TemplateService` e `AttachmentService`.
2662
- 3. `sendEmail(options)` repassa diretamente o envio para `EmailService.send`.
2663
- 4. O laboratório usa `getTemplateService()` para criar os templates que alimentam os exemplos.
2664
-
2665
- ### `EmailService`
2666
-
2667
- *Arquivo: `src/services/email.service.ts`*
2668
-
2669
- É o serviço que realmente chama `transporter.sendMail(...)`. Ele normaliza destinatários, escolhe o HTML renderizado pelo template e devolve uma resposta estruturada com sucesso ou falha.
2670
-
2671
- #### Propriedades
2672
-
2673
- | Propriedade | Tipo | Descrição |
2674
- | --- | --- | --- |
2675
- | `transporter` | `Transporter` | Conexão Nodemailer usada para envio |
2676
- | `defaultFrom` | `string` | Remetente padrão aplicado quando `options.from` não existe |
2677
-
2678
-
2679
- #### Dependências do construtor
2680
-
2681
- | Tipo | Descrição |
2682
- | --- | --- |
2683
- | `Transporter` | Transporte Nodemailer já configurado |
2684
- | `string` | Remetente padrão opcional |
2685
-
2686
-
2687
- #### Métodos públicos
2688
-
2689
- | Método | Descrição |
2690
- | --- | --- |
2691
- | `send` | Constrói `mailOptions`, renderiza template quando necessário e envia o email |
2692
-
2693
-
2694
- #### Comportamento de envio
2695
-
2696
- - `from` usa `options.from` quando existe; caso contrário, usa `defaultFrom`.
2697
- - `to` aceita string ou array; arrays são unidos por vírgula.
2698
- - `html` usa `options.html` quando informado.
2699
- - Se `html` não existir e `template` for fornecido, `options.template.render(options)` gera o HTML.
2700
- - `attachments` é repassado diretamente ao Nodemailer.
2701
- - O retorno é um objeto com `success`, `messageId` e `response` em caso de êxito, ou `success: false` com `error` quando o transporte falha.
2702
-
2703
- ```mermaid
2704
- sequenceDiagram
2705
- participant Caller as Chamada de envio
2706
- participant EmailService as EmailService
2707
- participant Template as Template
2708
- participant Builder as TemplateBuilder
2709
- participant Nodemailer as Nodemailer Transporter
2710
-
2711
- Caller->>EmailService: send options
2712
- EmailService->>Template: render options
2713
- Template->>Builder: build HTML
2714
- Builder-->>Template: html final
2715
- Template-->>EmailService: html
2716
- EmailService->>Nodemailer: sendMail mailOptions
2717
- Nodemailer-->>EmailService: info ou error
2718
- EmailService-->>Caller: objeto de resultado
2719
- ```
2720
-
2721
- ### `TemplateService`
2722
-
2723
- *Arquivo: `src/services/template.service.ts`*
2724
-
2725
- É o centro de composição dos templates. O serviço valida a configuração, gera um identificador estável para cache, cria o template por tema, adiciona histórico e fornece estatísticas de uso.
2726
-
2727
- #### Propriedades
2728
-
2729
- | Propriedade | Tipo | Descrição |
2730
- | --- | --- | --- |
2731
- | `templateCache` | `Map<string, TemplateCache>` | Cache em memória dos templates gerados |
2732
- | `defaultTTL` | `number` | TTL padrão em segundos |
2733
- | `templateHistory` | `Map<string, ITemplate[]>` | Histórico de versões dos templates |
2734
- | `options` | `TemplateOptions` | Configurações de comportamento do serviço |
2735
-
2736
-
2737
- #### Estrutura interna de cache
2738
-
2739
- | Propriedade | Tipo | Descrição |
2740
- | --- | --- | --- |
2741
- | `template` | `ITemplate` | Template armazenado no cache |
2742
- | `createdAt` | `Date` | Data de criação no cache |
2743
- | `expiresAt` | `Date` | Data de expiração |
2744
- | `hits` | `number` | Quantidade de acessos |
2745
-
2746
-
2747
- #### Opções do construtor
2748
-
2749
- | Tipo | Descrição |
2750
- | --- | --- |
2751
- | `cache?: boolean` | Liga ou desliga cache |
2752
- | `cacheTTL?: number` | TTL do cache em segundos |
2753
- | `validateConfig?: boolean` | Valida a configuração antes de criar o template |
2754
- | `minify?: boolean` | Minifica o HTML no render |
2755
- | `preview?: boolean` | Marca renderização como pré-visualização |
2756
-
2757
-
2758
- #### Métodos públicos
2759
-
2760
- | Método | Descrição |
2761
- | --- | --- |
2762
- | `createTemplate` | Cria ou recupera um template em cache |
2763
- | `cloneTemplate` | Cria uma nova versão a partir de um template existente |
2764
- | `renderTemplate` | Renderiza um template com dados e metadados |
2765
- | `previewTemplate` | Cria e renderiza em modo de prévia |
2766
- | `getThemeInfo` | Retorna dados do tema e configuração padrão |
2767
- | `listThemes` | Lista todos os temas |
2768
- | `getTemplateStats` | Retorna métricas de cache e histórico |
2769
- | `clearCache` | Remove o cache total ou por tema |
2770
- | `getTemplateHistory` | Retorna versões armazenadas de um template |
2771
- | `restoreTemplateVersion` | Recria uma versão anterior |
2772
- | `preloadTemplates` | Pré-carrega múltiplos templates no cache |
2773
- | `exportTemplate` | Serializa template em JSON |
2774
- | `importTemplate` | Reconstrói template a partir de JSON |
2775
- | `generateExampleTemplate` | Cria um template de exemplo pronto |
2776
- | `isValidTemplate` | Valida a estrutura de um template |
2777
- | `getTemplateDetails` | Retorna detalhes, histórico e cache de um template |
2778
-
2779
-
2780
- #### Validações aplicadas por `validateTemplateConfig`
2781
-
2782
- - `header.logo.imageUrl` é obrigatório quando `logo.type === 'image'`.
2783
- - `header.logo.text` é obrigatório quando `logo.type === 'text'`.
2784
- - `footer.links` deve conter pares `text` e `url`.
2785
- - `layout` aceita apenas `full` ou `minimal`.
2786
- - `spacing` aceita apenas `compact`, `normal` ou `relaxed`.
2787
- - `borderRadius` aceita apenas `none`, `small`, `medium` ou `large`.
2788
-
2789
- #### Fluxo de `createTemplate`
2790
-
2791
- 1. Valida a configuração quando a validação está ativa.
2792
- 2. Gera um ID com `generateTemplateId(themeType, variant, config)`.
2793
- 3. Consulta o cache com a chave gerada.
2794
- 4. Se houver cache válido, incrementa `hits` e retorna o template armazenado.
2795
- 5. Se não houver cache, chama `TemplateFactory.createTemplate(...)`.
2796
- 6. Enriquece o template com `getVersion`, `getId` e `clone`.
2797
- 7. Armazena a versão no cache quando o cache está habilitado.
2798
- 8. Adiciona o template ao histórico, mantendo no máximo 10 versões.
2799
-
2800
- ```mermaid
2801
- sequenceDiagram
2802
- participant Caller as Chamada
2803
- participant TemplateService as TemplateService
2804
- participant TemplateFactory as TemplateFactory
2805
- participant Builder as TemplateBuilder
2806
-
2807
- Caller->>TemplateService: createTemplate
2808
- TemplateService->>TemplateService: validateTemplateConfig
2809
- TemplateService->>TemplateService: generateTemplateId
2810
- TemplateService->>TemplateService: check cache
2811
- alt cache hit
2812
- TemplateService-->>Caller: template em cache
2813
- else cache miss
2814
- TemplateService->>TemplateFactory: createTemplate
2815
- TemplateFactory->>Builder: render function uses builder
2816
- Builder-->>TemplateFactory: html renderer
2817
- TemplateFactory-->>TemplateService: template base
2818
- TemplateService->>TemplateService: enhanceTemplate
2819
- TemplateService->>TemplateService: addToHistory
2820
- TemplateService-->>Caller: template enriquecido
2821
- end
2822
- ```
2823
-
2824
- ### Cache de templates em memória
2825
-
2826
- O cache é gerenciado inteiramente dentro de `TemplateService`. Ele usa duas estruturas:
2827
-
2828
- - `templateCache` para armazenar o template ativo com TTL e contagem de uso.
2829
- - `templateHistory` para guardar as versões produzidas por `createTemplate`.
2830
-
2831
- #### Chave de cache
2832
-
2833
- A chave é gerada em `generateTemplateId(...)` a partir de:
2834
-
2835
- - `themeType`
2836
- - `variant`
2837
- - `config`
2838
-
2839
- O conteúdo é serializado com `JSON.stringify(...)` e convertido em um hash simples, resultando no formato:
2840
-
2841
- ```text
2842
- {themeType}_{variant}_{hashAbsoluto}
2843
- ```
2844
-
2845
- #### Invalidação
2846
-
2847
- - `clearCache(themeType?)` limpa o cache inteiro ou apenas os templates do tema informado.
2848
- - `cleanExpiredCache()` remove entradas expiradas.
2849
- - `setInterval(..., 3600000)` executa a limpeza automática a cada hora.
2850
- - `restoreTemplateVersion(...)` recria uma versão anterior sem reaproveitar a versão original do cache.
2851
-
2852
- #### Métricas retornadas por `getTemplateStats`
2853
-
2854
- | Campo | Origem |
2855
- | --- | --- |
2856
- | `totalTemplates` | Tamanho de `templateHistory` |
2857
- | `cachedTemplates` | Tamanho de `templateCache` |
2858
- | `totalHits` | Soma dos `hits` de todas as entradas |
2859
- | `templatesByTheme` | Contagem por `ThemeType` |
2860
- | `cacheHitRate` | `totalHits / cachedTemplates * 100` |
2861
-
2862
-
2863
- ### `TemplateFactory`
2864
-
2865
- *Arquivo: `src/factories/template-factory.ts`*
2866
-
2867
- A fábrica liga o `ThemeType` ao tema concreto e devolve um objeto de template com função `render`. É aqui que o laboratório transforma a configuração em HTML.
2868
-
2869
- #### Propriedades
2870
-
2871
- | Propriedade | Tipo | Descrição |
2872
- | --- | --- | --- |
2873
- | `themes` | `Map<ThemeType, ITheme>` | Registro dos temas disponíveis |
2874
-
2875
-
2876
- #### Métodos públicos
2877
-
2878
- | Método | Descrição |
2879
- | --- | --- |
2880
- | `createTemplate` | Cria o template baseado em tema, variante e configuração |
2881
- | `getTheme` | Retorna a implementação concreta do tema |
2882
- | `listThemes` | Lista as chaves do mapa de temas |
2883
- | `getThemeInfo` | Retorna nome, descrição e recursos do tema |
2884
-
2885
-
2886
- #### O que `createTemplate` devolve
2887
-
2888
- O objeto de template retornado contém:
2889
-
2890
- | Propriedade | Tipo | Descrição |
2891
- | --- | --- | --- |
2892
- | `name` | `string` | Nome no formato `{themeType}_{variant}` |
2893
- | `theme` | `ThemeType` | Tema selecionado |
2894
- | `variant` | `'light' | 'dark'` | Variante visual |
2895
- | `config` | `ITemplateConfig` | Configuração recebida |
2896
- | `render` | `(data: any) => Promise<string>` | Função assíncrona que gera o HTML |
2897
-
2898
-
2899
- #### Comportamento do `render`
2900
-
2901
- - Usa `TemplateBuilder` com tema, config e variante.
2902
- - Lê `data.template.config.body`.
2903
- - Monta um corpo padrão quando `body.content` não existe.
2904
- - Chama `buildHeader(data.headerContent)`.
2905
- - Chama `buildBody(bodyContent)`.
2906
- - Só chama `buildButton(...)` quando `buttonText` e `buttonUrl` existem.
2907
- - Finaliza com `buildFooter()` e `build()`.
2908
-
2909
- ### `TemplateBuilder`
2910
-
2911
- *Arquivo: `src/templates/base/template-builder.ts`*
2912
-
2913
- É o construtor de HTML usado por cada template. Ele aplica variações visuais com base no tema, organiza cabeçalho, corpo, botão e rodapé, e gera a estrutura HTML completa do email.
2914
-
2915
- #### Propriedades
2916
-
2917
- | Propriedade | Tipo | Descrição |
2918
- | --- | --- | --- |
2919
- | `template` | `string` | HTML acumulado durante a montagem |
2920
- | `theme` | `ITheme` | Tema concreto usado na renderização |
2921
- | `config` | `ITemplateConfig` | Configuração do template |
2922
- | `variant` | `'light'` `'dark'` | Variante usada para escolher paleta |
2923
-
2924
-
2925
- #### Dependências do construtor
2926
-
2927
- | Tipo | Descrição |
2928
- | --- | --- |
2929
- | `ITheme` | Tema concreto com cores, tipografia e espaçamento |
2930
- | `ITemplateConfig` | Configuração do layout e das seções |
2931
- | `'light` `'dark'` | Variante visual |
2932
-
2933
-
2934
- #### Métodos públicos
2935
-
2936
- | Método | Descrição |
2937
- | --- | --- |
2938
- | `buildHeader` | Monta o cabeçalho e o logo |
2939
- | `buildBody` | Monta o corpo do email |
2940
- | `buildButton` | Monta o botão de chamada para ação |
2941
- | `buildFooter` | Monta o rodapé |
2942
- | `build` | Fecha o HTML completo do email |
2943
-
2944
-
2945
- #### Observações de renderização
2946
-
2947
- - O cabeçalho é omitido quando `config.header.show` é falso.
2948
- - O corpo processa HTML específico por tema.
2949
- - O botão só aparece quando o texto e a URL são informados na configuração.
2950
- - O rodapé pode incluir links, ícones sociais, copyright e unsubscribe.
2951
- - `build()` encapsula tudo em uma página HTML completa com `meta charset`, `viewport` e regra responsiva para telas pequenas.
2952
-
2953
- ### `AttachmentService`
2954
-
2955
- *Arquivo: `src/services/attachment.service.ts`*
2956
-
2957
- É o serviço usado para preparar anexos compatíveis com Nodemailer. No laboratório, ele é exercitado diretamente por `sendMinimalNewsletter`.
2958
-
2959
- #### Propriedades
2960
-
2961
- Não há propriedades de instância declaradas.
2962
-
2963
- #### Métodos públicos
2964
-
2965
- | Método | Descrição |
2966
- | --- | --- |
2967
- | `addFromPath` | Cria um anexo a partir de um arquivo no sistema |
2968
- | `addFromBuffer` | Cria um anexo a partir de um `Buffer` em memória |
2969
- | `addFromUrl` | Método declarado, mas lança erro de implementação |
2970
-
2971
-
2972
- #### Comportamento de `addFromPath`
2973
-
2974
- 1. Executa `fs.promises.stat(filePath)`.
2975
- 2. Verifica se o caminho é um arquivo.
2976
- 3. Lança `Error` se não for arquivo válido.
2977
- 4. Retorna um objeto com:- `filename`
2978
- - `path`
2979
- - `contentType`
2980
- - `cid`
2981
-
2982
- #### Comportamento de `addFromBuffer`
2983
-
2984
- Retorna um anexo com:
2985
-
2986
- - `filename`
2987
- - `content` com o buffer recebido
2988
- - `contentType`
2989
- - `cid`
2990
-
2991
- #### Comportamento de `addFromUrl`
2992
-
2993
- O método existe, mas lança:
2994
-
2995
- ```text
2996
- Method not implemented yet
2997
- ```
2998
-
2999
- ## Contratos e modelos usados pelo laboratório
3000
-
3001
- ### `ThemeType`
3002
-
3003
- *Arquivo: `src/core/enums/theme.enum.ts`*
3004
-
3005
- Valores disponíveis: `system`, `monokai`, `modern`, `corporate`, `minimal`.
3006
-
3007
- ### `ITheme`
3008
-
3009
- *Arquivo: `src/templates/themes/theme.interface.ts`*
3010
-
3011
- #### Propriedades
3012
-
3013
- | Propriedade | Tipo | Descrição |
3014
- | --- | --- | --- |
3015
- | `id` | `ThemeType` | Identificador do tema |
3016
- | `name` | `string` | Nome legível do tema |
3017
- | `light` | `IThemeColors` | Paleta para variante clara |
3018
- | `dark` | `IThemeColors` | Paleta para variante escura |
3019
- | `typography` | `ITypography` | Tipografia base |
3020
- | `spacing` | `ISpacing` | Escala de espaçamento |
3021
-
3022
-
3023
- ### `IThemeColors`
3024
-
3025
- *Arquivo: `src/templates/themes/theme.interface.ts`*
3026
-
3027
- | Propriedade | Tipo |
3028
- | --- | --- |
3029
- | `primary` | `string` |
3030
- | `secondary` | `string` |
3031
- | `background` | `string` |
3032
- | `text` | `string` |
3033
- | `textMuted` | `string` |
3034
- | `border` | `string` |
3035
- | `success` | `string` |
3036
- | `error` | `string` |
3037
- | `warning` | `string` |
3038
-
3039
-
3040
- ### `ITypography`
3041
-
3042
- *Arquivo: `src/templates/themes/theme.interface.ts`*
3043
-
3044
- | Propriedade | Tipo |
3045
- | --- | --- |
3046
- | `fontFamily` | `string` |
3047
- | `fontSizes.small` | `string` |
3048
- | `fontSizes.medium` | `string` |
3049
- | `fontSizes.large` | `string` |
3050
- | `fontSizes.xlarge` | `string` |
3051
- | `fontWeights.normal` | `number` |
3052
- | `fontWeights.medium` | `number` |
3053
- | `fontWeights.bold` | `number` |
3054
-
3055
-
3056
- ### `ISpacing`
3057
-
3058
- *Arquivo: `src/templates/themes/theme.interface.ts`*
3059
-
3060
- | Propriedade | Tipo |
3061
- | --- | --- |
3062
- | `xs` | `string` |
3063
- | `sm` | `string` |
3064
- | `md` | `string` |
3065
- | `lg` | `string` |
3066
- | `xl` | `string` |
3067
-
3068
-
3069
- ### `IEmailConfig`
3070
-
3071
- *Arquivo: `src/core/interfaces/email.interface.ts`*
3072
-
3073
- | Propriedade | Tipo | Descrição |
3074
- | --- | --- | --- |
3075
- | `host` | `string` | Host SMTP |
3076
- | `port` | `number` | Porta SMTP |
3077
- | `secure` | `boolean` | Modo seguro do transporte |
3078
- | `auth.user` | `string` | Usuário SMTP |
3079
- | `auth.pass` | `string` | Senha SMTP |
3080
- | `defaultFrom?` | `string` | Remetente padrão |
3081
-
3082
-
3083
- ### `IEmailOptions`
3084
-
3085
- *Arquivo: `src/core/interfaces/email.interface.ts`*
3086
-
3087
- | Propriedade | Tipo | Descrição |
3088
- | --- | --- | --- |
3089
- | `to` | `string` `string[]` | Destinatário ou lista de destinatários |
3090
- | `subject` | `string` | Assunto do email |
3091
- | `from?` | `string` | Remetente explícito |
3092
- | `cc?` | `string` `string[]` | Cópia |
3093
- | `bcc?` | `string` `string[]` | Cópia oculta |
3094
- | `attachments?` | `IAttachment[]` | Anexos |
3095
- | `template?` | `ITemplate` | Template usado para gerar HTML |
3096
- | `text?` | `string` | Corpo em texto puro |
3097
- | `html?` | `string` | Corpo em HTML |
3098
-
3099
-
3100
- ### `IAttachment`
3101
-
3102
- *Arquivo: `src/core/interfaces/email.interface.ts`*
3103
-
3104
- | Propriedade | Tipo | Descrição |
3105
- | --- | --- | --- |
3106
- | `filename` | `string` | Nome do arquivo anexado |
3107
- | `content?` | `string` | Buffer` | Conteúdo em memória |
3108
- | `path?` | `string` | Caminho local do arquivo |
3109
- | `contentType?` | `string` | MIME type |
3110
- | `cid?` | `string` | Content ID para inline |
3111
-
3112
-
3113
- ### `ITemplate`
3114
-
3115
- *Arquivo: `src/core/interfaces/template.interface.ts`*
3116
-
3117
- | Propriedade | Tipo | Descrição |
3118
- | --- | --- | --- |
3119
- | `name` | `string` | Nome do template |
3120
- | `theme` | `ThemeType` | Tema selecionado |
3121
- | `variant` | `'light'` `'dark'` | Variante visual |
3122
- | `config` | `ITemplateConfig` | Configuração aplicada |
3123
- | `render` | `(data: any) => Promise<string>` | Função de renderização |
3124
-
3125
-
3126
- ### `ITemplateConfig`
3127
-
3128
- *Arquivo: `src/core/interfaces/template.interface.ts`*
3129
-
3130
- | Propriedade | Tipo | Descrição |
3131
- | --- | --- | --- |
3132
- | `header?` | `IHeaderConfig` | Configuração do cabeçalho |
3133
- | `body?` | `IBodyConfig` | Configuração do corpo |
3134
- | `footer?` | `IFooterConfig` | Configuração do rodapé |
3135
- | `layout?` | `'full'` `'minimal'` | Tipo de layout |
3136
- | `spacing?` | `'compact'` `'normal'` `'relaxed'` | Densidade do espaçamento |
3137
- | `borderRadius?` | `'none'` `'small'` `'medium'` `'large'` | Raio de borda do card |
3138
-
3139
-
3140
- ### `IHeaderConfig`
3141
-
3142
- *Arquivo: `src/core/interfaces/template.interface.ts`*
3143
-
3144
- | Propriedade | Tipo | Descrição |
3145
- | --- | --- | --- |
3146
- | `show` | `boolean` | Controla exibição do cabeçalho |
3147
- | `logo?` | `{ type: 'text' 'image'; text?: string; imageUrl?: string; alt?: string; size?: 'small' 'medium' 'large' }` | Dados do logo |
3148
- | `backgroundColor?` | `string` | Cor de fundo |
3149
- | `textColor?` | `string` | Cor do texto |
3150
-
3151
-
3152
- ### `IBodyConfig`
3153
-
3154
- *Arquivo: `src/core/interfaces/template.interface.ts`*
3155
-
3156
- | Propriedade | Tipo | Descrição |
3157
- | --- | --- | --- |
3158
- | `title?` | `string` | Título principal |
3159
- | `message?` | `string` | Mensagem do corpo |
3160
- | `content?` | `string` | HTML bruto do conteúdo |
3161
- | `buttonText?` | `string` | Texto do botão |
3162
- | `buttonUrl?` | `string` | URL do botão |
3163
- | `buttonVariant?` | `'primary'` `'secondary'` `'success'` `'danger'` | Variante do botão |
3164
- | `alignment?` | `'left'` `center'` `'right'` | Alinhamento do conteúdo |
3165
- | `backgroundColor?` | `string` | Cor de fundo do bloco |
3166
- | `textColor?` | `string` | Cor do texto |
3167
- | `fontSize?` | `number` | Tamanho da fonte |
3168
-
3169
-
3170
- ### `IFooterConfig`
3171
-
3172
- *Arquivo: `src/core/interfaces/template.interface.ts`*
3173
-
3174
- | Propriedade | Tipo | Descrição |
3175
- | --- | --- | --- |
3176
- | `show` | `boolean` | Controla exibição do rodapé |
3177
- | `links?` | `Array<{ text: string; url: string }>` | Links do rodapé |
3178
- | `socialLinks?` | `Array<{ platform: 'facebook' 'twitter' 'linkedin' 'github'; url: string }>` | Redes sociais |
3179
- | `copyrightText?` | `string` | Texto de copyright |
3180
- | `unsubscribeText?` | `string` | Texto de cancelamento |
3181
- | `backgroundColor?` | `string` | Cor de fundo |
3182
- | `textColor?` | `string` | Cor do texto |
3183
-
3184
-
3185
- ## Temas usados nos exemplos guiados
3186
-
3187
- ### `SystemTheme`
3188
-
3189
- *Arquivo: `src/templates/themes/system.theme.ts`*
3190
-
3191
- #### Propriedades
3192
-
3193
- | Propriedade | Tipo | Descrição |
3194
- | --- | --- | --- |
3195
- | `id` | `ThemeType.SYSTEM` | Identificador do tema |
3196
- | `name` | `string` | Nome do tema |
3197
- | `light` | `IThemeColors` | Paleta clara |
3198
- | `dark` | `IThemeColors` | Paleta escura |
3199
- | `typography` | `ITypography` | Tipografia |
3200
- | `spacing` | `ISpacing` | Espaçamento |
3201
-
3202
-
3203
- ### `MonokaiTheme`
3204
-
3205
- *Arquivo: `src/templates/themes/monokai.theme.ts`*
3206
-
3207
- #### Propriedades
3208
-
3209
- | Propriedade | Tipo | Descrição |
3210
- | --- | --- | --- |
3211
- | `id` | `ThemeType.MONOKAI` | Identificador do tema |
3212
- | `name` | `string` | Nome do tema |
3213
- | `light` | `IThemeColors` | Paleta clara |
3214
- | `dark` | `IThemeColors` | Paleta escura |
3215
- | `typography` | `ITypography` | Tipografia monospace |
3216
- | `spacing` | `ISpacing` | Espaçamento |
3217
- | `codeHighlight` | `{ comment: string; keyword: string; string: string; number: string; function: string; variable: string }` | Cores para destaque de código |
3218
- | `borderStyle` | `{ radius: string; width: string; style: string }` | Raio e borda do tema |
3219
- | `effects` | `{ glow: string; shadow: string; transition: string }` | Efeitos visuais |
3220
-
3221
-
3222
- ### `ModernTheme`
3223
-
3224
- *Arquivo: `src/templates/themes/modern.theme.ts`*
3225
-
3226
- #### Propriedades
3227
-
3228
- | Propriedade | Tipo | Descrição |
3229
- | --- | --- | --- |
3230
- | `id` | `ThemeType.MODERN` | Identificador do tema |
3231
- | `name` | `string` | Nome do tema |
3232
- | `light` | `IThemeColors` | Paleta clara |
3233
- | `dark` | `IThemeColors` | Paleta escura |
3234
- | `typography` | `ITypography` | Tipografia |
3235
- | `spacing` | `ISpacing` | Espaçamento |
3236
- | `gradients` | `{ primary: string; secondary: string; accent: string; dark: string; light: string }` | Gradientes do tema |
3237
- | `borderStyle` | `{ radius: { small: string; medium: string; large: string; full: string }; width: string; style: string }` | Bordas arredondadas |
3238
- | `glassmorphism` | `{ light: string; dark: string; blur: string }` | Camada glassmorphism |
3239
- | `animations` | `{ hover: string; fade: string; slide: string }` | Transições e animações |
3240
-
3241
-
3242
- ### `CorporateTheme`
3243
-
3244
- *Arquivo: `src/templates/themes/corporate.theme.ts`*
3245
-
3246
- #### Propriedades
3247
-
3248
- | Propriedade | Tipo | Descrição |
3249
- | --- | --- | --- |
3250
- | `id` | `ThemeType.CORPORATE` | Identificador do tema |
3251
- | `name` | `string` | Nome do tema |
3252
- | `light` | `IThemeColors` | Paleta clara |
3253
- | `dark` | `IThemeColors` | Paleta escura |
3254
- | `typography` | `ITypography` | Tipografia serifada |
3255
- | `spacing` | `ISpacing` | Espaçamento |
3256
- | `corporateColors` | `{ gold: string; silver: string; bronze: string; navy: string; charcoal: string; ivory: string }` | Paleta institucional |
3257
- | `borderStyle` | `{ radius: { small: string; medium: string; large: string; pill: string }; width: { thin: string; medium: string; thick: string }; style: string }` | Bordas e espessuras |
3258
- | `elevation` | `{ shadow: string; card: string; modal: string; hover: string }` | Sombras |
3259
- | `branding` | `{ logoSize: { small: string; medium: string; large: string }; letterSpacing: { tight: string; normal: string; wide: string; wider: string }; textTransform: { uppercase: string; lowercase: string; capitalize: string; normal: string } }` | Regras de branding |
3260
- | `layout` | `{ maxWidth: string; contentWidth: string; sidebarWidth: string; headerHeight: string; footerHeight: string }` | Medidas de layout |
3261
-
3262
-
3263
- ### `MinimalTheme`
3264
-
3265
- *Arquivo: `src/templates/themes/minimal.theme.ts`*
3266
-
3267
- #### Propriedades
3268
-
3269
- | Propriedade | Tipo | Descrição |
3270
- | --- | --- | --- |
3271
- | `id` | `ThemeType.MINIMAL` | Identificador do tema |
3272
- | `name` | `string` | Nome do tema |
3273
- | `light` | `IThemeColors` | Paleta clara |
3274
- | `dark` | `IThemeColors` | Paleta escura |
3275
- | `typography` | `ITypography` | Tipografia |
3276
- | `spacing` | `ISpacing` | Espaçamento |
3277
- | `minimalColors` | `{ white: string; black: string; gray100: string; gray200: string; gray300: string; gray400: string; gray500: string; gray600: string; gray700: string; gray800: string; gray900: string }` | Escala neutra |
3278
- | `borderStyle` | `{ radius: { none: string; small: string; medium: string; large: string; full: string }; width: { thin: string; medium: string }; style: string }` | Bordas simples |
3279
- | `effects` | `{ shadow: string; transition: string; opacity: { hover: string; disabled: string } }` | Efeitos visuais mínimos |
3280
- | `layout` | `{ maxWidth: string; contentWidth: string; spacingMultiplier: number; lineHeight: number; paragraphSpacing: string }` | Regras de layout |
3281
- | `designSystem` | `{ grid: { columns: number; gutter: string; margin: string }; breakpoints: { mobile: string; tablet: string; desktop: string }; zIndex: { base: number; overlay: number; modal: number } }` | Sistema de design |
3282
-
3283
-
3284
- ## Fluxo do envio com anexo no laboratório
3285
-
3286
- ```mermaid
3287
- sequenceDiagram
3288
- participant User as Usuário
3289
- participant ExpressApp as Express App
3290
- participant Demo as sendMinimalNewsletter
3291
- participant Attach as AttachmentService
3292
- participant Factory as EmailFactory
3293
- participant Email as EmailService
3294
- participant Template as Template
3295
- participant SMTP as Nodemailer SMTP
3296
-
3297
- User->>ExpressApp: GET /test
3298
- ExpressApp->>Demo: sendMinimalNewsletter
3299
- Demo->>Attach: addFromPath uploads PHOTO jpg
3300
- Attach-->>Demo: attachment
3301
- Demo->>Factory: sendEmail
3302
- Factory->>Email: send
3303
- Email->>Template: render options
3304
- Template-->>Email: html
3305
- Email->>SMTP: sendMail
3306
- SMTP-->>Email: info
3307
- Email-->>Demo: success result
3308
- Demo-->>ExpressApp: JSON result
3309
- ExpressApp-->>User: 200 OK
3310
- ```
3311
-
3312
- ## Tratamento de erros
3313
-
3314
- | Componente | Condição | Efeito |
3315
- | --- | --- | --- |
3316
- | `EmailService.send` | `transporter.sendMail(...)` falha | Retorna `{ success: false, error }` |
3317
- | `AttachmentService.addFromPath` | O caminho não aponta para arquivo | Lança `Error` |
3318
- | `AttachmentService.addFromUrl` | Método chamado | Lança `Error` de não implementação |
3319
- | `TemplateService.validateTemplateConfig` | Configuração inválida | Lança `Error` com lista de problemas |
3320
- | `TemplateService.renderTemplate` | Falha na renderização | Lança `Error` com contexto |
3321
- | `TemplateFactory.createTemplate` | Tema inexistente | Lança `Error` |
3322
-
3323
-
3324
- ## Referência rápida das classes-chave
3325
-
3326
- | Class | Location | Responsibility |
3327
- | --- | --- | --- |
3328
- | | | Servidor de demonstração, bootstrap SMTP e rota `/test` |
3329
- | `EmailFactory` | `email-factory.ts` | Fachada de criação e envio |
3330
- | `EmailService` | `email.service.ts` | Envio real via Nodemailer |
3331
- | `TemplateService` | `template.service.ts` | Criação, cache e renderização de templates |
3332
- | `TemplateFactory` | `template-factory.ts` | Criação do template por tema |
3333
- | `TemplateBuilder` | `template-builder.ts` | Montagem do HTML final |
3334
- | `AttachmentService` | `attachment.service.ts` | Criação de anexos |
3335
- | `SystemTheme` | `system.theme.ts` | Tema base adaptativo |
3336
- | `MonokaiTheme` | `monokai.theme.ts` | Tema técnico com destaque de código |
3337
- | `ModernTheme` | `modern.theme.ts` | Tema moderno com gradientes |
3338
- | `CorporateTheme` | `corporate.theme.ts` | Tema corporativo formal |
3339
- | `MinimalTheme` | `minimal.theme.ts` | Tema minimalista |
3340
- | `theme.interface.ts` | `theme.interface.ts` | Contrato base dos temas |
3341
- | `email.interface.ts` | `email.interface.ts` | Contratos de email e anexos |
3342
- | `template.interface.ts` | `template.interface.ts` | Contratos de template e configuração |
3343
-
3344
-
3345
- ---
3346
-
3347
- ## Gerenciamento de Templates/Builder HTML e composição estrutural do email
3348
-
3349
- # Gerenciamento de Templates - Builder HTML e composição estrutural do email
3350
-
3351
- ## Visão Geral
3352
-
3353
- O `TemplateBuilder` é a peça que transforma configuração temática e conteúdo já preparado em um HTML completo de email. Ele concentra a montagem estrutural das quatro regiões principais do template — header, body, button e footer — e aplica variações visuais conforme o tema e o modo `light` ou `dark`.
3354
-
3355
- Na prática, essa classe é usada para gerar emails com composição consistente entre temas como `system`, `monokai`, `modern`, `corporate` e `minimal`, preservando compatibilidade com clientes de email por meio de tabelas aninhadas, estilos inline e um wrapper final com `DOCTYPE`, `meta viewport` e responsividade básica.
3356
-
3357
- ## Visão de Arquitetura
3358
-
3359
- ```mermaid
3360
- flowchart TB
3361
- subgraph Configuracao [Contratos e tema]
3362
- TP[TemplatePart]
3363
- TI[ITemplateConfig]
3364
- TH[ITheme]
3365
- end
3366
-
3367
- subgraph Montagem [TemplateBuilder]
3368
- RF[Render do TemplateFactory]
3369
- BH[buildHeader]
3370
- BL[buildLogo]
3371
- BB[buildBody]
3372
- FC[formatCorporateContent]
3373
- FM[formatMinimalContent]
3374
- HC[highlightCode]
3375
- AS[applySyntaxHighlighting]
3376
- BU[buildButton]
3377
- BF[buildFooter]
3378
- BFL[buildFooterLinks]
3379
- BSL[buildSocialLinks]
3380
- GSI[getSocialIcon]
3381
- BD[build]
3382
- end
3383
-
3384
- subgraph Saida [HTML final]
3385
- HT[Documento HTML de email]
3386
- end
3387
-
3388
- TI --> RF
3389
- TH --> RF
3390
- RF --> BH
3391
- BH --> BL
3392
- RF --> BB
3393
- BB --> FC
3394
- BB --> FM
3395
- BB --> HC
3396
- HC --> AS
3397
- RF --> BU
3398
- RF --> BF
3399
- BF --> BFL
3400
- BF --> BSL
3401
- BSL --> GSI
3402
- BF --> BD
3403
- BD --> HT
3404
-
3405
- TP -.-> BH
3406
- TP -.-> BB
3407
- TP -.-> BU
3408
- TP -.-> BF
3409
- ```
3410
-
3411
- ## Estrutura dos Componentes
3412
-
3413
- ### TemplatePart
3414
-
3415
- *`src/core/enums/template-part.enum.ts`*
3416
-
3417
- O enum define as partes estruturais semânticas do email e espelha a divisão física aplicada pelo builder.
3418
-
3419
- Valores: `HEADER` = `header`, `BODY` = `body`, `FOOTER` = `footer`, `BUTTON` = `button`.
3420
-
3421
- ### Contratos de tema e configuração
3422
-
3423
- #### ITheme
3424
-
3425
- > **Note:** `TemplatePart` nomeia exatamente as mesmas regiões que `TemplateBuilder` monta por métodos dedicados, mas o arquivo não o importa nem faz despacho baseado nesse enum. A composição é feita por chamadas explícitas de `buildHeader`, `buildBody`, `buildButton`, `buildFooter` e `build()`.
3426
-
3427
- *`src/templates/themes/theme.interface.ts`*
3428
-
3429
- A interface base do tema fornece os tokens consumidos pelo builder para definir cores, tipografia e espaçamento.
3430
-
3431
- | Propriedade | Tipo | Descrição |
3432
- | --- | --- | --- |
3433
- | `id` | `ThemeType` | Identificador do tema usado nas ramificações internas do builder. |
3434
- | `name` | `string` | Nome legível do tema. |
3435
- | `light` | `IThemeColors` | Paleta usada quando `variant` é `light`. |
3436
- | `dark` | `IThemeColors` | Paleta usada quando `variant` é `dark`. |
3437
- | `typography` | `ITypography` | Tokens tipográficos usados em header, body, botões e footer. |
3438
- | `spacing` | `ISpacing` | Escala de espaçamento aplicada na composição HTML. |
3439
-
3440
-
3441
- #### IThemeColors
3442
-
3443
- *`src/templates/themes/theme.interface.ts`*
3444
-
3445
- | Propriedade | Tipo | Descrição |
3446
- | --- | --- | --- |
3447
- | `primary` | `string` | Cor principal aplicada em títulos, botões e destaques. |
3448
- | `secondary` | `string` | Cor secundária para variações de botão e apoio visual. |
3449
- | `background` | `string` | Cor de fundo da seção ou do container. |
3450
- | `text` | `string` | Cor principal do texto. |
3451
- | `textMuted` | `string` | Cor de texto atenuada para rodapé e metadados. |
3452
- | `border` | `string` | Cor de borda usada em divisórias e contornos. |
3453
- | `success` | `string` | Cor de sucesso disponível para uso temático. |
3454
- | `error` | `string` | Cor de erro disponível para uso temático. |
3455
- | `warning` | `string` | Cor de alerta disponível para uso temático. |
3456
-
3457
-
3458
- #### ITypography
3459
-
3460
- *`src/templates/themes/theme.interface.ts`*
3461
-
3462
- | Propriedade | Tipo | Descrição |
3463
- | --- | --- | --- |
3464
- | `fontFamily` | `string` | Família tipográfica aplicada nos blocos principais. |
3465
- | `fontSizes.small` | `string` | Tamanho pequeno. |
3466
- | `fontSizes.medium` | `string` | Tamanho médio. |
3467
- | `fontSizes.large` | `string` | Tamanho grande. |
3468
- | `fontSizes.xlarge` | `string` | Tamanho extra grande, usado no logo textual e títulos. |
3469
- | `fontWeights.normal` | `number` | Peso normal. |
3470
- | `fontWeights.medium` | `number` | Peso intermediário. |
3471
- | `fontWeights.bold` | `number` | Peso negrito. |
3472
-
3473
-
3474
- #### ISpacing
3475
-
3476
- *`src/templates/themes/theme.interface.ts`*
3477
-
3478
- | Propriedade | Tipo | Descrição |
3479
- | --- | --- | --- |
3480
- | `xs` | `string` | Espaçamento extra pequeno. |
3481
- | `sm` | `string` | Espaçamento pequeno. |
3482
- | `md` | `string` | Espaçamento médio. |
3483
- | `lg` | `string` | Espaçamento grande. |
3484
- | `xl` | `string` | Espaçamento extra grande. |
3485
-
3486
-
3487
- #### ITemplate
3488
-
3489
- *`src/core/interfaces/template.interface.ts`*
3490
-
3491
- A interface representa o template montável e renderizável consumido por `EmailService`.
3492
-
3493
- | Propriedade | Tipo | Descrição |
3494
- | --- | --- | --- |
3495
- | `name` | `string` | Nome do template, normalmente derivado de tema e variante. |
3496
- | `theme` | `ThemeType` | Tema selecionado. |
3497
- | `variant` | `'light' \ | 'dark'` | Variante visual que escolhe a paleta do tema. |
3498
- | `config` | `ITemplateConfig` | Configuração estrutural passada ao builder e à fábrica. |
3499
- | `render` | `(data: any) => Promise<string>` | Função que produz o HTML final. |
3500
-
3501
-
3502
- #### ITemplateConfig
3503
-
3504
- *`src/core/interfaces/template.interface.ts`*
3505
-
3506
- | Propriedade | Tipo | Descrição |
3507
- | --- | --- | --- |
3508
- | `header` | `IHeaderConfig` | Configuração do cabeçalho. |
3509
- | `body` | `IBodyConfig` | Configuração do conteúdo principal. |
3510
- | `footer` | `IFooterConfig` | Configuração do rodapé. |
3511
- | `layout` | `'full' \ | 'minimal'` | Define o layout geral do template. |
3512
- | `spacing` | `'compact' \ | 'normal' \ | 'relaxed'` | Define a densidade visual do template. |
3513
- | `borderRadius` | `'none' \ | 'small' \ | 'medium' \ | 'large'` | Define o raio de borda estrutural. |
3514
-
3515
-
3516
- #### IHeaderConfig
3517
-
3518
- *`src/core/interfaces/template.interface.ts`*
3519
-
3520
- | Propriedade | Tipo | Descrição |
3521
- | --- | --- | --- |
3522
- | `show` | `boolean` | Habilita ou oculta o header. |
3523
- | `logo` | `{ type: 'text' \ | 'image'; text?: string; imageUrl?: string; alt?: string; size?: 'small' \ | 'medium' \ | 'large' }` | Define o logotipo textual ou por imagem. |
3524
- | `backgroundColor` | `string` | Cor de fundo específica do header. |
3525
- | `textColor` | `string` | Cor de texto específica do header. |
3526
-
3527
-
3528
- #### IBodyConfig
3529
-
3530
- *`src/core/interfaces/template.interface.ts`*
3531
-
3532
- | Propriedade | Tipo | Descrição |
3533
- | --- | --- | --- |
3534
- | `title` | `string` | Título do conteúdo. |
3535
- | `message` | `string` | Mensagem principal do corpo. |
3536
- | `content` | `string` | HTML já pronto para renderização direta. |
3537
- | `buttonText` | `string` | Rótulo do botão principal. |
3538
- | `buttonUrl` | `string` | URL do botão principal. |
3539
- | `buttonVariant` | `'primary'` `'secondary'` `'success'` `'danger'` | Variante visual do botão. |
3540
- | `alignment` | `'left'` `'center'` `'right'` | Alinhamento do bloco do corpo. |
3541
- | `backgroundColor` | `string` | Cor de fundo do conteúdo. |
3542
- | `textColor` | `string` | Cor do texto do conteúdo. |
3543
- | `fontSize` | `number` | Tamanho base da fonte em pixels. |
3544
-
3545
-
3546
- #### IFooterConfig
3547
-
3548
- *`src/core/interfaces/template.interface.ts`*
3549
-
3550
- | Propriedade | Tipo | Descrição |
3551
- | --- | --- | --- |
3552
- | `show` | `boolean` | Habilita ou oculta o rodapé. |
3553
- | `links` | `Array<{ text: string; url: string }>` | Links textuais do rodapé. |
3554
- | `socialLinks` | `Array<{ platform: 'facebook' 'twitter' 'linkedin' 'github'; url: string }>` | Ícones sociais com URL de destino. |
3555
- | `copyrightText` | `string` | Texto de copyright. |
3556
- | `unsubscribeText` | `string` | Texto do link de cancelamento de inscrição. |
3557
- | `backgroundColor` | `string` | Cor de fundo do rodapé. |
3558
- | `textColor` | `string` | Cor de texto do rodapé. |
3559
-
3560
-
3561
- ## TemplateBuilder
3562
-
3563
- *`src/templates/base/template-builder.ts`*
3564
-
3565
- O `TemplateBuilder` mantém o HTML acumulado em uma string interna e devolve a mesma instância em cada método público, permitindo encadeamento fluente de composição. Ele recebe o tema, a configuração estrutural e a variante visual, e a partir disso decide quais regiões renderizar e quais tokens visuais aplicar.
3566
-
3567
- ### Propriedades
3568
-
3569
- | Propriedade | Tipo | Descrição |
3570
- | --- | --- | --- |
3571
- | `template` | `string` | Buffer interno que acumula os fragmentos HTML construídos pelos métodos. |
3572
- | `theme` | `ITheme` | Tema base usado para cores, tipografia e espaçamento. |
3573
- | `config` | `ITemplateConfig` | Configuração estrutural do template. |
3574
- | `variant` | `'light'` `'dark'` | Seleção da paleta do tema. |
3575
-
3576
-
3577
- ### Dependências do construtor
3578
-
3579
- | Type | Description |
3580
- | --- | --- |
3581
- | `ITheme` | Fornece as paletas `light` e `dark`, tokens tipográficos e espaçamentos. |
3582
- | `ITemplateConfig` | Define quais partes serão exibidas e quais conteúdos serão montados. |
3583
- | `'light'` `'dark'` | Seleciona a paleta aplicada durante a montagem HTML. |
3584
-
3585
-
3586
- ### Métodos públicos
3587
-
3588
- | Method | Description |
3589
- | --- | --- |
3590
- | `buildHeader` | Monta o bloco de header, incluindo logo e conteúdo opcional. |
3591
- | `buildBody` | Monta o bloco principal do email e aplica formatações específicas por tema. |
3592
- | `buildButton` | Monta o CTA centralizado com variação visual por tema e variante. |
3593
- | `buildFooter` | Monta o rodapé com links, redes sociais, copyright e unsubscribe. |
3594
- | `build` | Fecha a estrutura final e embrulha o HTML em `DOCTYPE`, `html`, `head` e `body`. |
3595
-
3596
-
3597
- ### Métodos internos
3598
-
3599
- | Method | Description |
3600
- | --- | --- |
3601
- | `buildLogo` | Renderiza logo textual ou por imagem conforme `config.header.logo`. |
3602
- | `formatCorporateContent` | Aplica transformação de `<blockquote>` e `<highlight>` no conteúdo corporativo. |
3603
- | `formatMinimalContent` | Reescreve tags de título e parágrafo para uma apresentação minimalista. |
3604
- | `highlightCode` | Envolve blocos `<code>` em `<pre>` com estilos Monokai. |
3605
- | `applySyntaxHighlighting` | Coloriza palavras-chave, strings, números e nomes de função em trechos de código. |
3606
- | `buildFooterLinks` | Gera a fileira de links textuais do rodapé. |
3607
- | `buildSocialLinks` | Gera os ícones sociais do rodapé. |
3608
- | `getSocialIcon` | Resolve a URL do ícone do serviço social solicitado. |
3609
-
3610
-
3611
- ### Comportamento por etapa de montagem
3612
-
3613
- #### `buildHeader(content?: string)`
3614
-
3615
- - Sai imediatamente quando `this.config.header?.show` é falso ou ausente.
3616
- - Seleciona as cores do tema com base em `variant`.
3617
- - Ajusta o header conforme o tema:- `corporate`: borda inferior dourada, sombra, uppercase e letter-spacing reforçado.
3618
- - `minimal`: borda inferior fina e padding ajustado.
3619
- - `modern`: borda inferior, `backdrop-filter` com blur e sombra leve.
3620
- - `monokai`: borda inferior em cor primária, sombra e transição.
3621
- - demais temas: borda inferior padrão.
3622
- - Chama `buildLogo()` e inclui `content` opcional abaixo do logo.
3623
- - Usa tabelas com `role="presentation"` para compatibilidade com clientes de email.
3624
-
3625
- #### `buildLogo()`
3626
-
3627
- - Retorna string vazia se `config.header?.logo` não existir.
3628
- - Quando `logo.type === 'text'`:- Usa `logo.text` ou fallback literal `Logo`.
3629
- - Ajusta tamanho, peso, cor e efeitos por tema.
3630
- - `corporate` troca a família tipográfica para serifada e usa dourado.
3631
- - `minimal` reduz peso e controla espaçamento entre letras.
3632
- - `monokai` aplica `text-shadow`.
3633
- - `modern` aplica gradiente com clipping no texto.
3634
- - Quando `logo.type === 'image'`:- Define altura por `size`: `small` = `30px`, `medium` = `60px`, `large` = `100px`.
3635
- - Usa `logo.imageUrl` como `src` e `logo.alt` ou fallback `Logo` como `alt`.
3636
- - Em `modern`, adiciona borda arredondada e transição.
3637
- - Em `corporate`, adiciona raio de borda pequeno.
3638
-
3639
- #### `buildBody(content: string)`
3640
-
3641
- - Constrói o bloco central com padding, fundo, cor de texto, fonte e line-height.
3642
- - Ajusta o container conforme o tema:- `corporate`: borda lateral dourada, margem vertical e sombra de card.
3643
- - `minimal`: largura de conteúdo controlada, padding mais aberto e centralização.
3644
- - `modern`: raio médio e margens.
3645
- - `monokai`: borda lateral em cor primária.
3646
- - Processa o conteúdo antes de inserir:- `corporate`: chama `formatCorporateContent`.
3647
- - `minimal`: chama `formatMinimalContent`.
3648
- - `monokai` com `<code>`: chama `highlightCode`.
3649
- - Envolve o conteúdo em uma tabela externa com fundo branco e padding de 10px.
3650
-
3651
- #### `buildButton(text: string, url: string, variant: 'primary' | 'secondary' = 'primary')`
3652
-
3653
- - Escolhe a cor base do botão entre `primary` e `secondary`.
3654
- - Renderiza o CTA em uma tabela centralizada.
3655
- - Ajusta o estilo por tema:- `corporate`: raio pequeno, uppercase, letter-spacing amplo e hover com sombra.
3656
- - `minimal`: fundo transparente, borda sólida e hover invertendo cores.
3657
- - `modern`: gradiente, raio médio, transição e sombra.
3658
- - `monokai`: borda dupla, raio do tema, transição e hover com glow.
3659
- - demais temas: raio simples de `4px`.
3660
- - Insere o texto como `<a>` com `href` apontando para `url`.
3661
-
3662
- #### `buildFooter()`
3663
-
3664
- - Sai imediatamente quando `this.config.footer?.show` é falso ou ausente.
3665
- - Usa cores do tema de acordo com `variant`.
3666
- - Ajusta o rodapé por tema:- `corporate`: borda superior dourada e tipografia menor.
3667
- - `minimal`: padding mais controlado e fonte compacta.
3668
- - `modern`: blur de fundo e raio pequeno.
3669
- - `monokai`: borda superior mais espessa e colorida.
3670
- - Monta, na ordem:1. links do rodapé via `buildFooterLinks()`;
3671
- 2. redes sociais via `buildSocialLinks()`;
3672
- 3. `copyrightText`, se presente;
3673
- 4. `unsubscribeText`, se presente, com link `#`.
3674
-
3675
- #### `buildFooterLinks()`
3676
-
3677
- - Retorna string vazia se `config.footer?.links` não existir ou estiver vazio.
3678
- - Usa tabela centralizada para alinhar os links.
3679
- - Aplica variações por tema:- `modern`: transição e hover com mudança de cor.
3680
- - `corporate`: uppercase e hover dourado.
3681
- - `minimal`: hover sublinhado.
3682
- - Cada item de `links` é renderizado como `<a href="...">`.
3683
-
3684
- #### `buildSocialLinks()`
3685
-
3686
- - Retorna string vazia se `config.footer?.socialLinks` não existir ou estiver vazio.
3687
- - Renderiza ícones sociais em tabela centralizada.
3688
- - Cada item usa `target="_blank"` e um `<img>` com `width="20"` e `height="20"`.
3689
- - O `src` do ícone vem de `getSocialIcon(platform)`.
3690
-
3691
- #### `getSocialIcon(platform: string)`
3692
-
3693
- - Resolve a URL do ícone por uma tabela interna de strings.
3694
- - Plataformas mapeadas no arquivo: `facebook`, `twitter`, `github`, `instagram`, `youtube`, `discord`, `reddit`, `pinterest`, `tiktok`, `gitlab`, `stackoverflow`, `medium`, `dribbble`, `behance`, `telegram`.
3695
- - Retorna `https://cdn.simpleicons.org/virginmedia/5865F2` como fallback.
3696
-
3697
- #### `build()`
3698
-
3699
- - Gera o documento HTML final com:- `<!DOCTYPE html>`;
3700
- - `<html>`, `<head>`, `<body>`;
3701
- - `meta charset="utf-8"`;
3702
- - `meta name="viewport" content="width=device-width, initial-scale=1.0"`;
3703
- - `<title>Email Template</title>`.
3704
- - Injeta um `<style>` com media query para telas até `600px`.
3705
- - Calcula o `containerStyles` com `max-width`:- `640px` quando o tema é `minimal`;
3706
- - `600px` nos demais.
3707
- - O fundo final varia por `variant`, com override específico em `minimal`.
3708
-
3709
- ## Relação entre TemplatePart e a composição do builder
3710
-
3711
- O enum `TemplatePart` serve como vocabulário estrutural para a composição do template. No builder, essa mesma divisão aparece em forma de métodos:
3712
-
3713
- - `HEADER` → `buildHeader()`
3714
- - `BODY` → `buildBody()`
3715
- - `BUTTON` → `buildButton()`
3716
- - `FOOTER` → `buildFooter()`
3717
-
3718
- A relação é semântica e estrutural: o enum nomeia as partes, enquanto o builder implementa a montagem real dessas partes em HTML.
3719
-
3720
- ## Contratos de renderização e uso upstream
3721
-
3722
- O `TemplateBuilder` não recebe dados de domínio diretamente. O fluxo visível no repositório passa por `TemplateFactory.createTemplate(...)`, que instancia o builder e transforma `body` em uma string HTML antes de chamar os métodos de composição.
3723
-
3724
- ### Fluxo de envio com template
3725
-
3726
- ```mermaid
3727
- sequenceDiagram
3728
- participant C as Chamada
3729
- participant ES as EmailService
3730
- participant RT as template.render
3731
- participant TB as TemplateBuilder
3732
- participant HT as HTML final
3733
-
3734
- C->>ES: send(options)
3735
- ES->>RT: render(options)
3736
- RT->>TB: new TemplateBuilder(theme, config, variant)
3737
- RT->>TB: buildHeader(data.headerContent)
3738
- RT->>TB: buildBody(bodyContent)
3739
- opt buttonText e buttonUrl
3740
- RT->>TB: buildButton(text, url, variant)
3741
- end
3742
- RT->>TB: buildFooter()
3743
- RT->>TB: build()
3744
- TB-->>RT: html
3745
- RT-->>ES: html
3746
- ES-->>C: resultado
3747
- ```
3748
-
3749
- ### Fluxo de pré-visualização
3750
-
3751
- ```mermaid
3752
- sequenceDiagram
3753
- participant C as Chamada
3754
- participant TS as TemplateService
3755
- participant TF as TemplateFactory
3756
- participant RT as renderTemplate
3757
- participant TB as TemplateBuilder
3758
-
3759
- C->>TS: previewTemplate(themeType, variant, config, data)
3760
- TS->>TF: createTemplate(themeType, variant, config)
3761
- TS->>RT: renderTemplate(template, data)
3762
- RT->>TB: template.render(renderData)
3763
- RT->>TB: buildHeader
3764
- RT->>TB: buildBody
3765
- RT->>TB: buildFooter
3766
- RT->>TB: build
3767
- ```
3768
-
3769
- ## Gerenciamento de Estado e Montagem
3770
-
3771
- > **Note:** `TemplateFactory.createTemplate` monta o `bodyContent` a partir de `data.template.config.body`, mas `TemplateService.previewTemplate` chama `renderTemplate(template, data)` sem adicionar a propriedade `template` em `renderData`. O caminho de preview, portanto, depende de `data` já conter `template` com `config.body`.
3772
-
3773
- O estado interno do builder é totalmente acumulativo. Cada método público concatena fragmentos em `this.template` e retorna `this`, permitindo a composição encadeada até o HTML final ser embrulhado por `build()`.
3774
-
3775
- | Campo | Papel |
3776
- | --- | --- |
3777
- | `template` | Acumula o HTML gerado pelos métodos de composição. |
3778
- | `theme` | Define a paleta e os tokens usados nas ramificações por tema. |
3779
- | `config` | Ativa ou desativa seções e fornece conteúdo de header, body e footer. |
3780
- | `variant` | Escolhe entre as paletas `light` e `dark`. |
3781
-
3782
-
3783
- Esse padrão é usado no render do template criado pela fábrica, que sempre instancia um `TemplateBuilder` novo para cada renderização, mantendo a montagem isolada por execução.
3784
-
3785
- ## Integração com TemplateFactory e TemplateService
3786
-
3787
- O builder atua em conjunto com a fábrica e o serviço de templates:
3788
-
3789
- - `TemplateFactory.createTemplate(...)` cria o objeto `ITemplate` e centraliza a montagem do `bodyContent`.
3790
- - `TemplateService.createTemplate(...)` valida a configuração antes de delegar à fábrica.
3791
- - `TemplateService.renderTemplate(...)` adiciona `_meta` ao payload e aplica minificação opcional no HTML final.
3792
- - `EmailService.send(...)` chama `options.template.render(options)` quando recebe um template, usando o HTML montado pelo builder como corpo da mensagem.
3793
-
3794
- ### Validações upstream que afetam o builder
3795
-
3796
- `TemplateService.validateTemplateConfig(...)` verifica, antes da criação, pontos diretamente consumidos pela montagem:
3797
-
3798
- - logo em imagem exige `imageUrl`;
3799
- - logo textual exige `text`;
3800
- - `footer.links` exige `text` e `url` em cada item;
3801
- - `layout`, `spacing` e `borderRadius` devem estar dentro dos valores válidos.
3802
-
3803
- Essas validações reduzem a chance de o `TemplateBuilder` receber configurações inconsistentes.
3804
-
3805
- ## Tratamento de erros e validações de composição
3806
-
3807
- O arquivo do builder trabalha mais com guard clauses e retornos vazios do que com exceções. Isso afeta diretamente o HTML gerado quando alguma parte não está configurada.
3808
-
3809
- - `buildHeader()` e `buildFooter()` retornam `this` sem alterar o template quando `show` é falso.
3810
- - `buildLogo()` retorna string vazia quando `logo` não existe.
3811
- - `buildFooterLinks()` e `buildSocialLinks()` retornam string vazia quando não há itens.
3812
- - `getSocialIcon()` sempre retorna uma URL, usando fallback.
3813
-
3814
- ## Responsividade e wrappers HTML
3815
-
3816
- > **Note:** Os estilos de `hover` em `buildButton()` e `buildFooterLinks()`/`buildSocialLinks()` são inseridos dentro de strings de `style` inline com sintaxe `&:hover { ... }`. Esse formato não é aplicado por atributos HTML inline, então os hovers descritos nessas strings não são efetivos no HTML final gerado por este arquivo. **Note:** O `@media only screen and (max-width: 600px)` definido em `build()` ajusta `.container` e `.button`, mas o HTML gerado por `buildButton()` não adiciona a classe `button` a nenhum elemento. O seletor responsivo para botão, portanto, não encontra alvo no markup produzido por este builder. **Note:** `IFooterConfig.socialLinks` restringe `platform` a `facebook`, `twitter`, `linkedin` e `github`, mas `getSocialIcon()` conhece várias outras plataformas, como `instagram`, `youtube`, `discord`, `reddit`, `pinterest`, `tiktok`, `gitlab`, `stackoverflow`, `medium`, `dribbble`, `behance` e `telegram`. Esses valores adicionais não podem ser expressos sem um desvio de tipo.
3817
-
3818
- O wrapper final é construído para clientes de email, com estrutura simples e previsível:
3819
-
3820
- - `body` com `margin: 0; padding: 0;`
3821
- - container centralizado com `max-width`
3822
- - `overflow: hidden` em `modern`
3823
- - borda e sombra ajustadas por tema
3824
- - media query para telas pequenas
3825
-
3826
- ### Detalhes da responsividade
3827
-
3828
- - O container passa a `width: 100%` em telas até `600px`.
3829
- - O botão foi preparado para layout em bloco na mesma media query.
3830
- - O tema `minimal` usa `640px` de largura máxima, acima do limite dos demais temas.
3831
-
3832
- ### Wrapper HTML final
3833
-
3834
- O HTML final sempre inclui:
3835
-
3836
- - `<!DOCTYPE html>`
3837
- - `<html>`
3838
- - `<head>`
3839
- - `<meta charset="utf-8">`
3840
- - `<meta name="viewport" ...>`
3841
- - `<title>Email Template</title>`
3842
- - `<body>`
3843
- - `<div class="container">`
3844
- - o conteúdo acumulado em `this.template`
3845
-
3846
- ## Dependências
3847
-
3848
- ### Dependências diretas do arquivo
3849
-
3850
- - `ITemplateConfig` de
3851
- - `ITheme` de
3852
- - `MonokaiTheme`, `ModernTheme`, `CorporateTheme`, `MinimalTheme` para ramificações visuais específicas
3853
-
3854
- ### Dependências funcionais relacionadas
3855
-
3856
- - `TemplatePart` para semântica estrutural
3857
- - `TemplateFactory` para instanciar e usar o builder no fluxo normal de renderização
3858
- - `TemplateService` para validação, renderização, preview e minificação do HTML final
3859
- - `EmailService` para envio do HTML gerado
3860
-
3861
- ## Referência das Classes Principais
3862
-
3863
- | Class | Responsibility |
3864
- | --- | --- |
3865
- | `template-builder.ts` | Monta o HTML estrutural do email em header, body, button, footer e wrapper final. |
3866
- | `template.interface.ts` | Define o contrato de template e as configurações estruturais consumidas pelo builder. |
3867
- | `template-part.enum.ts` | Nomeia semanticamente as partes do email: header, body, footer e button. |
3868
- | `theme.interface.ts` | Define os tokens base de tema usados para cores, tipografia e espaçamento. |
3869
- | `template-factory.ts` | Cria o template renderizável e coordena a instância do `TemplateBuilder`. |
3870
- | `template.service.ts` | Valida, renderiza, pré-visualiza e gerencia o ciclo de vida dos templates. |
3871
-
3872
-
3873
- ---
3874
-
3875
- ## Gerenciamento de Templates/Cache, histórico, clonagem, importação e estatísticas
3876
-
3877
- # Gerenciamento de Templates - Cache, histórico, clonagem, importação e estatísticas
3878
-
3879
- ## Visão geral
3880
-
3881
- O `TemplateService` concentra o ciclo de vida dos templates de email depois da criação: ele valida configurações, gera um identificador determinístico, reaproveita instâncias em cache, mantém histórico de versões e expõe operações de cópia, exportação e importação. Na prática, isso permite reutilizar templates em escala sem recriar a mesma estrutura a cada solicitação.
3882
-
3883
- Esse serviço é o ponto de entrada para cenários de manutenção e automação: pré-carregamento de templates, restauração de versões anteriores, geração de exemplos para demonstração e leitura de estatísticas de uso. Ele opera em conjunto com `TemplateFactory` para materializar o template executável e com a estrutura interna de cache e histórico para controlar reuso e expiração.
3884
-
3885
- ## Arquitetura do gerenciamento de templates
3886
-
3887
- ```mermaid
3888
- flowchart TB
3889
- subgraph Consumidor [Consumidor da biblioteca]
3890
- App[Codigo da aplicacao]
3891
- Demo[Servidor de demonstracao]
3892
- end
3893
-
3894
- subgraph TemplateManagement [Gerenciamento de Templates]
3895
- Service[TemplateService]
3896
- Factory[TemplateFactory]
3897
- Cache[templateCache Map]
3898
- History[templateHistory Map]
3899
- Validator[validateTemplateConfig]
3900
- Cleaner[cleanExpiredCache]
3901
- Stats[getTemplateStats]
3902
- end
3903
-
3904
- subgraph RuntimeTemplate [Template em execucao]
3905
- Enhanced[Template aprimorado]
3906
- Builder[TemplateBuilder]
3907
- end
3908
-
3909
- App -->|createTemplate cloneTemplate importTemplate| Service
3910
- Demo -->|getTemplateService| Service
3911
-
3912
- Service -->|valida configuracao| Validator
3913
- Service -->|gera cache key| Cache
3914
- Service -->|registra versoes| History
3915
- Service -->|cria template base| Factory
3916
- Service -->|limpeza periodica| Cleaner
3917
- Service -->|consulta estatisticas| Stats
3918
-
3919
- Factory -->|render| Builder
3920
- Service -->|enhanceTemplate| Enhanced
3921
- Enhanced -->|render| Builder
3922
- ```
3923
-
3924
- ## Estrutura do componente
3925
-
3926
- ### TemplateService
3927
-
3928
- *`src/services/template.service.ts`*
3929
-
3930
- O `TemplateService` é a fachada principal desta seção. Ele recebe opções de comportamento no construtor, mantém dois mapas internos (`templateCache` e `templateHistory`) e expõe a API pública para criação, clonagem, importação, exportação, estatísticas e inspeção detalhada.
3931
-
3932
- #### Propriedades
3933
-
3934
- | Propriedade | Tipo | Descrição |
3935
- | --- | --- | --- |
3936
- | `templateCache` | `Map<string, TemplateCache>` | Cache em memória indexado por ID determinístico do template. |
3937
- | `defaultTTL` | `number` | TTL padrão em segundos usado quando nenhuma configuração explícita é fornecida. Valor inicial: `3600`. |
3938
- | `templateHistory` | `Map<string, ITemplate[]>` | Histórico por ID do template, preservando versões anteriores. |
3939
- | `options` | `TemplateOptions` | Configuração mesclada no construtor com os defaults do serviço. |
3940
-
3941
-
3942
- #### Dependências do construtor
3943
-
3944
- | Type | Description |
3945
- | --- | --- |
3946
- | `TemplateOptions` | Define cache, TTL, validação, minificação e modo de preview. |
3947
-
3948
-
3949
- #### Métodos públicos
3950
-
3951
- | Method | Description |
3952
- | --- | --- |
3953
- | `createTemplate` | Cria um template a partir de `themeType`, `variant` e `config`. Valida a configuração, calcula o ID determinístico, reutiliza o cache quando disponível, registra histórico e retorna um `ITemplate` aprimorado. |
3954
- | `cloneTemplate` | Cria um novo template com base em outro template existente. Faz mesclagem rasa entre `template.config` e `modifications` e delega para `createTemplate`. Retorna `ITemplate`. |
3955
- | `renderTemplate` | Renderiza um `ITemplate` com os dados informados, injeta `_meta`, aplica minificação quando habilitada e retorna `Promise<string>`. |
3956
- | `previewTemplate` | Gera uma pré-visualização sem poluir o cache. Internamente chama `createTemplate` com `cache: false` e depois `renderTemplate` com `preview: true`. Retorna `Promise<string>`. |
3957
- | `getThemeInfo` | Combina metadados do tema com variantes disponíveis e configuração padrão por tema. Retorna nome, descrição, features, variantes e `defaultConfig`. |
3958
- | `listThemes` | Retorna a lista de temas disponíveis via `TemplateFactory`. Resultado: `ThemeType[]`. |
3959
- | `getTemplateStats` | Consolida métricas de uso: total de templates no histórico, templates em cache, total de hits, agrupamento por tema e taxa de acerto do cache. |
3960
- | `clearCache` | Remove entradas do cache inteiro ou apenas do tema informado. Retorna a quantidade de itens removidos. |
3961
- | `getTemplateHistory` | Retorna o histórico de versões de um `templateId` ou um array vazio. |
3962
- | `restoreTemplateVersion` | Recria uma versão anterior a partir do histórico. Se o índice for inválido, retorna `null`. |
3963
- | `preloadTemplates` | Pré-carrega vários templates em paralelo usando `Promise.all`. Cada item é processado por `createTemplate`. Retorna `Promise<void>`. |
3964
- | `exportTemplate` | Serializa um template para JSON com `name`, `theme`, `variant`, `config`, `exportedAt` e `version`. Retorna `string`. |
3965
- | `importTemplate` | Lê JSON, valida presença de `theme`, `variant` e `config`, e recria o template por `createTemplate`. Retorna `ITemplate`. |
3966
- | `generateExampleTemplate` | Gera um template de demonstração com configuração pronta, usando `ThemeType.MODERN` e `light` por padrão. Retorna `ITemplate`. |
3967
- | `isValidTemplate` | Valida a forma estrutural de um template arbitrário: objeto, `name`, `theme`, `variant`, `config` e `render`. Retorna `boolean`. |
3968
- | `getTemplateDetails` | Retorna o template atual, o histórico, o `cacheInfo` e o `usageCount` do `templateId`. |
3969
-
3970
-
3971
- #### Métodos privados de suporte
3972
-
3973
- | Method | Description |
3974
- | --- | --- |
3975
- | `validateTemplateConfig` | Valida `header`, `footer`, `layout`, `spacing` e `borderRadius`, acumulando erros e lançando exceção ao final. |
3976
- | `generateTemplateId` | Gera o ID determinístico com base em `themeType`, `variant` e `config` serializados em JSON. |
3977
- | `enhanceTemplate` | Adiciona os métodos dinâmicos `getVersion`, `getId` e `clone` ao template retornado. |
3978
- | `addToHistory` | Insere o template no histórico e mantém apenas as últimas 10 versões. |
3979
- | `cleanExpiredCache` | Remove entradas cujo `expiresAt` já passou. Executado periodicamente pelo `setInterval` do construtor. |
3980
- | `minifyHtml` | Remove excesso de espaços, comentários e espaçamento entre tags para reduzir o HTML final. |
3981
- | `getDefaultConfigForTheme` | Monta a configuração padrão por tema com ajustes específicos de `borderRadius` e `spacing`. |
3982
-
3983
-
3984
- #### Métodos dinâmicos adicionados ao template retornado
3985
-
3986
- Os objetos retornados por `createTemplate` e pelos fluxos que passam por ele recebem métodos anexados em runtime:
3987
-
3988
- | Method | Description |
3989
- | --- | --- |
3990
- | `getVersion` | Retorna a quantidade de versões armazenadas no histórico do `templateId`. |
3991
- | `getId` | Retorna o ID determinístico calculado para o template. |
3992
- | `clone` | Cria uma cópia do template com modificações parciais em `ITemplateConfig`. |
3993
-
3994
-
3995
- ### TemplateCache
3996
-
3997
- cloneTemplate faz mesclagem rasa de template.config com modifications. Campos aninhados, como header.logo ou footer.links, não são combinados profundamente; o valor fornecido em modifications substitui o bloco correspondente.
3998
-
3999
- *`src/services/template.service.ts`*
4000
-
4001
- Estrutura interna usada por `templateCache` para armazenar metadados de expiração e uso por template.
4002
-
4003
- #### Propriedades
4004
-
4005
- | Propriedade | Tipo | Descrição |
4006
- | --- | --- | --- |
4007
- | `template` | `ITemplate` | Instância do template armazenado no cache. |
4008
- | `createdAt` | `Date` | Momento de criação do item em cache. |
4009
- | `expiresAt` | `Date` | Data e hora em que o item deixa de ser válido. |
4010
- | `hits` | `number` | Número de reutilizações do item em cache. |
4011
-
4012
-
4013
- ### TemplateOptions
4014
-
4015
- *`src/services/template.service.ts`*
4016
-
4017
- Opções aplicadas no nível do serviço e mescladas com os defaults no construtor.
4018
-
4019
- #### Propriedades
4020
-
4021
- | Propriedade | Tipo | Default | Descrição |
4022
- | --- | --- | --- | --- |
4023
- | `cache` | `boolean` | `true` | Habilita ou desabilita o uso de cache. |
4024
- | `cacheTTL` | `number` | `3600` | TTL em segundos usado ao armazenar templates no cache. |
4025
- | `validateConfig` | `boolean` | `true` | Ativa a validação de `ITemplateConfig` antes da criação. |
4026
- | `minify` | `boolean` | `true` | Aplica minificação no HTML retornado por `renderTemplate`. |
4027
- | `preview` | `boolean` | `false` | Marca o render como pré-visualização no metadado `_meta`. |
4028
-
4029
-
4030
- ### TemplateFactory
4031
-
4032
- *`src/factories/template-factory.ts`*
4033
-
4034
- A `TemplateFactory` é a dependência direta usada pelo `TemplateService` para materializar a instância concreta de `ITemplate`. Ela mantém o catálogo de temas em memória e produz a estrutura que depois será enriquecida pelo serviço.
4035
-
4036
- #### Propriedades
4037
-
4038
- | Propriedade | Tipo | Descrição |
4039
- | --- | --- | --- |
4040
- | `themes` | `Map<ThemeType, ITheme>` | Repositório estático dos temas disponíveis: `system`, `monokai`, `modern`, `corporate` e `minimal`. |
4041
-
4042
-
4043
- #### Métodos públicos
4044
-
4045
- | Method | Description |
4046
- | --- | --- |
4047
- | `createTemplate` | Cria o objeto `ITemplate` com `name`, `theme`, `variant`, `config` e função `render`. A renderização interna monta a saída HTML por meio de `TemplateBuilder`. |
4048
- | `getTheme` | Retorna a instância de tema associada ao `ThemeType`, ou `undefined` se não existir. |
4049
- | `listThemes` | Retorna os `ThemeType` disponíveis no mapa interno. |
4050
- | `getThemeInfo` | Retorna metadados estáticos do tema: nome, descrição e lista de features. |
4051
-
4052
-
4053
- ## Fluxos principais
4054
-
4055
- ### Criação e reaproveitamento via cache
4056
-
4057
- ```mermaid
4058
- sequenceDiagram
4059
- participant C as Consumidor
4060
- participant S as TemplateService
4061
- participant M as templateCache
4062
- participant F as TemplateFactory
4063
- participant H as templateHistory
4064
-
4065
- C->>S: createTemplate
4066
- S->>S: validateTemplateConfig
4067
- S->>S: generateTemplateId
4068
- S->>M: lookup templateId
4069
-
4070
- alt Cache hit
4071
- M-->>S: TemplateCache
4072
- S->>M: hits++
4073
- S-->>C: ITemplate
4074
- else Cache miss
4075
- M-->>S: vazio
4076
- S->>F: createTemplate
4077
- F-->>S: ITemplate
4078
- S->>S: enhanceTemplate
4079
- S->>M: store template
4080
- S->>H: addToHistory
4081
- S-->>C: ITemplate
4082
- end
4083
- ```
4084
-
4085
- O fluxo começa com a validação opcional da configuração e a geração do `templateId`. Se o ID já existir no cache e o cache estiver habilitado, o serviço retorna a instância existente e incrementa `hits`. Caso contrário, cria um novo template por `TemplateFactory`, adiciona os métodos dinâmicos, armazena no cache com TTL e registra a versão no histórico.
4086
-
4087
- ### Clonagem, histórico e restauração de versões
4088
-
4089
- ```mermaid
4090
- sequenceDiagram
4091
- participant C as Consumidor
4092
- participant S as TemplateService
4093
- participant H as templateHistory
4094
- participant F as TemplateFactory
4095
-
4096
- C->>S: cloneTemplate
4097
- S->>S: merge config
4098
- S->>S: createTemplate
4099
- S-->>C: ITemplate
4100
-
4101
- C->>S: restoreTemplateVersion
4102
- S->>H: get history
4103
-
4104
- alt Version encontrada
4105
- H-->>S: ITemplate
4106
- S->>F: createTemplate com cache false
4107
- F-->>S: ITemplate
4108
- S-->>C: ITemplate
4109
- else Version ausente
4110
- H-->>S: vazio ou index invalido
4111
- S-->>C: null
4112
- end
4113
- ```
4114
-
4115
- `cloneTemplate` reaproveita o tema e a variante originais do template de origem e só altera o bloco configurado em `modifications`. Já `restoreTemplateVersion` reconstrói uma versão histórica sem gravá-la novamente em cache, usando `cache: false`.
4116
-
4117
- ### Importação, exportação e pré-carregamento
4118
-
4119
- ```mermaid
4120
- sequenceDiagram
4121
- participant C as Consumidor
4122
- participant S as TemplateService
4123
- participant F as TemplateFactory
4124
-
4125
- C->>S: exportTemplate
4126
- S-->>C: JSON string
4127
-
4128
- C->>S: importTemplate
4129
- S->>S: parse JSON
4130
- S->>F: createTemplate
4131
- F-->>S: ITemplate
4132
- S-->>C: ITemplate
4133
-
4134
- C->>S: preloadTemplates
4135
- loop cada template
4136
- S->>S: createTemplate
4137
- S->>F: createTemplate
4138
- F-->>S: ITemplate
4139
- end
4140
- S-->>C: void
4141
- ```
4142
-
4143
- `exportTemplate` serializa apenas os dados essenciais do template e um `version` derivado do método dinâmico `getVersion`, quando presente. `importTemplate` ignora metadados exportados como `exportedAt` e recria uma nova instância gerenciada pelo serviço. `preloadTemplates` funciona como aquecimento de cache e também preenche histórico para cada combinação processada.
4144
-
4145
- ### Geração de exemplos e renderização com metadados
4146
-
4147
- - `generateExampleTemplate` monta uma configuração pronta para demonstração, com:- `header.logo.type` igual a `text` e `text` igual a `ExampleApp`
4148
- - `footer.links` com `Privacy Policy`, `Terms of Service` e `Contact`
4149
- - `footer.socialLinks` com `twitter`, `github` e `linkedin`
4150
- - `layout: 'full'`, `spacing: 'normal'`
4151
- - `borderRadius` igual a `none` apenas quando o tema é `ThemeType.MINIMAL`
4152
- - `renderTemplate` injeta `_meta` com:- `isPreview`
4153
- - `renderDate`
4154
- - `templateName`
4155
- - `theme`
4156
- - `variant`
4157
- - Quando `minify` está ativo, o HTML final passa por redução de espaços e remoção de comentários.
4158
-
4159
- ## Gestão de estado
4160
-
4161
- ### Estados internos do template
4162
-
4163
- ```mermaid
4164
- stateDiagram-v2
4165
- [*] --> Criado
4166
- Criado --> EmCache: cache habilitado
4167
- EmCache --> Reutilizado: mesmo templateId
4168
- Reutilizado --> EmCache: hits incrementa
4169
- EmCache --> Expirado: cleanExpiredCache
4170
- Expirado --> RemovidoDoCache
4171
- Criado --> Historico: addToHistory
4172
- Historico --> Restaurado: restoreTemplateVersion
4173
- Restaurado --> Criado
4174
- ```
4175
-
4176
- TemplateFactory.createTemplate lê data.template.config.body, mas TemplateService.renderTemplate só adiciona _meta ao payload. Isso faz com que previewTemplate e qualquer renderização direta sem data.template dependam de o chamador já fornecer essa estrutura. Impacto: o fluxo de preview não é autossuficiente e pode falhar antes de gerar HTML.
4177
-
4178
- O estado do serviço é mantido em memória por dois mapas: `templateCache` e `templateHistory`. O cache controla expiração por `expiresAt` e contagem de acesso por `hits`; o histórico preserva as últimas 10 versões por `templateId`. A restauração produz uma nova instância funcional, em vez de reativar o objeto antigo do histórico.
4179
-
4180
- ### Regras de estado por operação
4181
-
4182
- | Operação | Efeito no cache | Efeito no histórico |
4183
- | --- | --- | --- |
4184
- | `createTemplate` | Armazena ou reaproveita por `templateId`. | Adiciona a nova versão quando há criação nova. |
4185
- | `cloneTemplate` | Segue a lógica de `createTemplate`. | Gera novo registro para a variação clonada. |
4186
- | `previewTemplate` | Não grava no cache quando cria o template base. | Registra a criação da instância temporária. |
4187
- | `restoreTemplateVersion` | Cria a nova instância com `cache: false`. | Não altera o histórico original. |
4188
- | `clearCache` | Remove entradas do cache total ou por tema. | Não apaga o histórico. |
4189
- | `cleanExpiredCache` | Remove apenas itens cujo `expiresAt` já venceu. | Não altera o histórico. |
4190
-
4191
-
4192
- ## Estratégia de cache
4193
-
4194
- ### Chave determinística
4195
-
4196
- O ID de cache é gerado por `generateTemplateId` com base em uma serialização JSON do triplo:
4197
-
4198
- ```ts
124
+ ```typescript
4199
125
  {
4200
- theme: themeType,
4201
- variant,
4202
- config
126
+ success: boolean;
127
+ messageId?: string;
128
+ response?: string;
129
+ error?: any;
4203
130
  }
4204
131
  ```
4205
132
 
4206
- O hash simples percorre a string serializada e produz um ID no formato:
4207
-
4208
- ```ts
4209
- `${themeType}_${variant}_${Math.abs(hash)}`
4210
- ```
4211
-
4212
- Isso garante que a mesma combinação de tema, variante e configuração produza o mesmo identificador dentro do processo. A consequência prática é o reaproveitamento direto em `createTemplate`, `importTemplate`, `preloadTemplates` e `restoreTemplateVersion` quando os dados são equivalentes.
4213
-
4214
- ### TTL e limpeza periódica
4215
-
4216
- - `cacheTTL` é lido em segundos e convertido para milissegundos na hora de armazenar o item.
4217
- - `defaultTTL` do serviço também é `3600`, usado quando nenhuma outra opção define TTL.
4218
- - O construtor agenda `cleanExpiredCache` com `setInterval` a cada `3600000` ms.
4219
- - `cleanExpiredCache` remove apenas entradas vencidas; o histórico permanece intacto.
4220
-
4221
- ### Invalidação e remoção
4222
-
4223
- | Método | Estratégia |
4224
- | --- | --- |
4225
- | `clearCache()` | Limpa todo o cache imediatamente. |
4226
- | `clearCache(themeType)` | Remove apenas entradas cujo `template.theme` corresponde ao tema informado. |
4227
- | `cleanExpiredCache()` | Remove entradas vencidas com base em `expiresAt`. |
4228
- | `restoreTemplateVersion()` | Não reutiliza o item antigo do cache; recria nova instância. |
4229
-
4230
-
4231
- ### Hits e reutilização
4232
-
4233
- - Cada cache hit incrementa `hits`.
4234
- - `getTemplateDetails` usa `cacheInfo?.hits` como `usageCount`.
4235
- - `getTemplateStats` soma os `hits` de todas as entradas em cache para produzir `totalHits`.
4236
-
4237
- ### Estatísticas expostas
4238
-
4239
- | Campo | Origem | Observação |
4240
- | --- | --- | --- |
4241
- | `totalTemplates` | `templateHistory.size` | Conta IDs com histórico, não cada versão individual. |
4242
- | `cachedTemplates` | `templateCache.size` | Conta apenas itens atualmente em cache. |
4243
- | `totalHits` | Soma de `cache.hits` | Agrega todos os hits das entradas cacheadas. |
4244
- | `templatesByTheme` | Cache atual agrupado por `template.theme` | Não considera histórico fora do cache. |
4245
- | `cacheHitRate` | `totalHits / totalCached * 100` | Usa a quantidade de itens em cache como denominador. |
4246
-
4247
-
4248
- ## Tratamento de erros
4249
-
4250
- O serviço usa exceções para problemas de configuração e importação, e retornos sentinela para restauração e consulta de histórico.
4251
-
4252
- ### Erros lançados
4253
-
4254
- ```ts
4255
- throw new Error(`Template configuration validation failed:\n${errors.join('\n')}`);
4256
- throw new Error(`Failed to import template: ${error}`);
4257
- throw new Error(`Theme ${themeType} not found`);
4258
- throw new Error('EmailFactory not initialized. Call initialize() first.');
4259
- ```
4260
-
4261
- ### Comportamento por método
4262
-
4263
- | Método | Comportamento em erro |
4264
- | --- | --- |
4265
- | `validateTemplateConfig` | Acumula múltiplos erros e lança uma única exceção consolidada. |
4266
- | `importTemplate` | Captura falhas de JSON ou validação e relança com prefixo `Failed to import template`. |
4267
- | `restoreTemplateVersion` | Retorna `null` quando o histórico não existe ou o índice é inválido. |
4268
- | `getTemplateHistory` | Retorna `[]` quando não há entrada para o `templateId`. |
4269
- | `isValidTemplate` | Retorna `false` em qualquer exceção ou forma inválida. |
4270
-
4271
-
4272
- ### Regras de validação explícitas
4273
-
4274
- - `header.logo.type === 'image'` exige `imageUrl`.
4275
- - `header.logo.type === 'text'` exige `text`.
4276
- - `footer.links` exige pares `text` e `url` em cada item.
4277
- - `layout` aceita apenas `full` e `minimal`.
4278
- - `spacing` aceita apenas `compact`, `normal` e `relaxed`.
4279
- - `borderRadius` aceita apenas `none`, `small`, `medium` e `large`.
4280
-
4281
- ## Integrações e dependências
4282
-
4283
- ### Integrações internas
4284
-
4285
- getDefaultConfigForTheme(themeType, theme?) recebe theme, mas o corpo atual decide o resultado apenas por themeType. O parâmetro adicional não altera a configuração retornada.
4286
-
4287
- - `TemplateFactory`: criação do template base que depois é enriquecido pelo serviço.
4288
- - `TemplateBuilder`: usado indiretamente dentro da função `render` gerada por `TemplateFactory`.
4289
- - `EmailFactory.getTemplateService()`: expõe este serviço para consumidores da biblioteca.
4290
- - : usa o serviço na demonstração local para criar templates temáticos de exemplo.
4291
-
4292
- ### Tipos e enums utilizados
4293
-
4294
- - `ThemeType`: `system`, `monokai`, `modern`, `corporate`, `minimal`
4295
- - `ITemplate`: contrato retornado por criação, clonagem, importação e restauração
4296
- - `ITemplateConfig`: configuração de entrada para construção e clone
4297
- - `ITheme`: usado por `getDefaultConfigForTheme` e `TemplateFactory`
4298
-
4299
- ### Dependências de plataforma
4300
-
4301
- - `Map` para armazenamento em memória.
4302
- - `Date` para TTL, criação e metadados.
4303
- - `JSON.stringify` e `JSON.parse` para ID determinístico e importação/exportação.
4304
- - `setInterval` para limpeza periódica do cache.
4305
- - `console.log` dentro de `renderTemplate` para rastreio de renderização.
4306
-
4307
- ## Considerações de teste
4308
-
4309
- | Cenário | O que verificar |
4310
- | --- | --- |
4311
- | Cache hit em `createTemplate` | Mesmo `themeType`, `variant` e `config` retornam o mesmo `ITemplate` e incrementam `hits`. |
4312
- | Cache miss em `createTemplate` | Nova instância é criada, cache é preenchido e histórico recebe a versão. |
4313
- | Expiração por TTL | `cleanExpiredCache` remove apenas a entrada vencida. |
4314
- | `clearCache(themeType)` | Remove somente templates daquele tema. |
4315
- | Histórico limitado | Após mais de 10 versões, a versão mais antiga é descartada. |
4316
- | `cloneTemplate` | A cópia preserva tema e variante e aplica apenas as modificações recebidas. |
4317
- | `restoreTemplateVersion` | Índice inválido retorna `null`; índice válido recria uma nova instância. |
4318
- | `exportTemplate` e `importTemplate` | O JSON exportado contém os campos esperados e a importação recria um template funcional. |
4319
- | `generateExampleTemplate` | O template gerado usa os defaults esperados do tema e da variante. |
4320
- | `isValidTemplate` | Objetos sem `render`, `theme` ou `config` retornam `false`. |
4321
- | `getTemplateDetails` | O retorno combina `template`, `history`, `cacheInfo` e `usageCount` corretamente. |
4322
-
4323
-
4324
- ## Key Classes Reference
4325
-
4326
- | Class | Location | Responsibility |
4327
- | --- | --- | --- |
4328
- | `TemplateService` | `template.service.ts` | Gerencia criação, cache, histórico, clonagem, importação, exportação e estatísticas de templates. |
4329
- | `TemplateFactory` | `template-factory.ts` | Cria a instância executável do template e fornece metadados dos temas disponíveis. |
4330
-
4331
-
4332
- ---
4333
-
4334
- ## Gerenciamento de Templates/Criação, validação, renderização e preview de templates
4335
-
4336
- # Gerenciamento de Templates - Criação, validação, renderização e preview de templates
4337
-
4338
- ## Overview
4339
-
4340
- Este núcleo organiza a criação de templates de email a partir de `ThemeType`, `variant` e `ITemplateConfig`, transformando configurações estruturais em HTML pronto para envio ou visualização. No fluxo da biblioteca, `TemplateService` coordena validação, cache, histórico e renderização; `TemplateFactory` materializa o objeto `ITemplate`; e `TemplateBuilder` converte a combinação de tema e configuração em markup HTML.
4341
-
4342
- Para quem consome a biblioteca, isso significa poder montar templates temáticos com cabeçalho, corpo, botão e rodapé, gerar prévias sem enviar email e reaproveitar configurações com rastreio de versões. O resultado final é um pipeline de composição que separa a intenção do template da geração do HTML.
4343
-
4344
- ## Architecture Overview
4345
-
4346
- ```mermaid
4347
- flowchart TB
4348
- subgraph UsoDaBiblioteca[Uso da Biblioteca]
4349
- Chamador[Chamador]
4350
- end
4351
-
4352
- subgraph DominioDeTemplates[Dominio de Templates]
4353
- TemplateService[TemplateService]
4354
- TemplateFactory[TemplateFactory]
4355
- TemplateBuilder[TemplateBuilder]
4356
- TemplateInterface[ITemplate e ITemplateConfig]
4357
- ThemeCatalog[ThemeType e ITheme]
4358
- end
4359
-
4360
- Chamador -->|cria ou previsualiza| TemplateService
4361
- TemplateService -->|valida configuracao| TemplateService
4362
- TemplateService -->|gera identificador| TemplateService
4363
- TemplateService -->|instancia template| TemplateFactory
4364
- TemplateFactory -->|seleciona tema| ThemeCatalog
4365
- TemplateFactory -->|retorna ITemplate| TemplateService
4366
- TemplateFactory -->|usa builder| TemplateBuilder
4367
- TemplateBuilder -->|consome tema e config| ThemeCatalog
4368
- TemplateBuilder -->|monta HTML| TemplateInterface
4369
- TemplateService -->|retorna template ou HTML| Chamador
4370
- ```
4371
-
4372
- ```mermaid
4373
- classDiagram
4374
- class TemplateService
4375
- class TemplateFactory
4376
- class TemplateBuilder
4377
- class ITemplate
4378
- class ITemplateConfig
4379
- class ITheme
4380
- class ThemeType
4381
-
4382
- TemplateService --> TemplateFactory
4383
- TemplateService --> ITemplate
4384
- TemplateService --> ITemplateConfig
4385
- TemplateFactory --> TemplateBuilder
4386
- TemplateFactory --> ITheme
4387
- TemplateFactory --> ThemeType
4388
- TemplateBuilder --> ITheme
4389
- TemplateBuilder --> ITemplateConfig
4390
- ITemplate --> ThemeType
4391
- ITemplate --> ITemplateConfig
4392
- ```
4393
-
4394
- ## Component Structure
4395
-
4396
- ### Modelo de domínio de templates
4397
-
4398
- #### `ThemeType`
4399
-
4400
- *Arquivo:*
4401
-
4402
- Valores: `SYSTEM`, `MONOKAI`, `MODERN`, `CORPORATE`, `MINIMAL`.
4403
-
4404
- Esse enum é a chave de seleção usada por `TemplateFactory` e `TemplateService` para localizar o tema concreto e para gerar metadados de tema.
4405
-
4406
- #### `ITemplate`
4407
-
4408
- *Arquivo:*
4409
-
4410
- | Propriedade | Tipo | Descrição |
4411
- | --- | --- | --- |
4412
- | `name` | `string` | Nome do template gerado, montado como `${themeType}_${variant}`. |
4413
- | `theme` | `ThemeType` | Tema associado ao template. |
4414
- | `variant` | `'light'` `'dark'` | Variante visual aplicada ao tema. |
4415
- | `config` | `ITemplateConfig` | Configuração estrutural usada na composição do email. |
4416
- | `render` | `(data: any) => Promise<string>` | Função assíncrona que gera o HTML final. |
4417
-
4418
-
4419
- #### `ITemplateConfig`
4420
-
4421
- *Arquivo:*
4422
-
4423
- | Propriedade | Tipo | Descrição |
4424
- | --- | --- | --- |
4425
- | `header?` | `IHeaderConfig` | Configuração opcional do cabeçalho. |
4426
- | `body?` | `IBodyConfig` | Configuração opcional do conteúdo principal. |
4427
- | `footer?` | `IFooterConfig` | Configuração opcional do rodapé. |
4428
- | `layout?` | `'full'` `'minimal'` | Define a estrutura geral do template. |
4429
- | `spacing?` | `'compact'` `'normal'` `'relaxed'` | Ajusta a densidade de espaçamento do layout. |
4430
- | `borderRadius?` | `'none'` `'small'` `'medium'` `'large'` | Controla o arredondamento dos blocos. |
4431
-
4432
-
4433
- #### `IHeaderConfig`
4434
-
4435
- *Arquivo:*
4436
-
4437
- | Propriedade | Tipo | Descrição |
4438
- | --- | --- | --- |
4439
- | `show` | `boolean` | Define se o cabeçalho será renderizado. |
4440
- | `logo?` | `{ type: 'text' 'image'; text?: string; imageUrl?: string; alt?: string; size?: 'small' 'medium' 'large' }` | Define o conteúdo e a apresentação do logo. |
4441
- | `backgroundColor?` | `string` | Cor de fundo do cabeçalho. |
4442
- | `textColor?` | `string` | Cor do texto do cabeçalho. |
4443
-
4444
-
4445
- #### Estrutura de `logo`
4446
-
4447
- | Propriedade | Tipo | Descrição |
4448
- | --- | --- | --- |
4449
- | `type` | `'text'` `'image'` | Tipo do logo. |
4450
- | `text?` | `string` | Texto exibido quando `type` é `text`. |
4451
- | `imageUrl?` | `string` | URL da imagem quando `type` é `image`. |
4452
- | `alt?` | `string` | Texto alternativo da imagem. |
4453
- | `size?` | `'small'` `'medium'` `'large'` | Tamanho visual do logo. |
4454
-
4455
-
4456
- #### `IBodyConfig`
4457
-
4458
- *Arquivo:*
4459
-
4460
- | Propriedade | Tipo | Descrição |
4461
- | --- | --- | --- |
4462
- | `title?` | `string` | Título principal do corpo do email. |
4463
- | `message?` | `string` | Mensagem principal. |
4464
- | `content?` | `string` | Conteúdo HTML completo que substitui o bloco padrão. |
4465
- | `buttonText?` | `string` | Texto do botão de chamada para ação. |
4466
- | `buttonUrl?` | `string` | URL de destino do botão. |
4467
- | `buttonVariant?` | `'primary'` `'secondary'` `'success'` `'danger'` | Variante declarada para o botão. |
4468
- | `alignment?` | `'left'` `'center'` `'right'` | Alinhamento do conteúdo. |
4469
- | `backgroundColor?` | `string` | Cor de fundo do corpo. |
4470
- | `textColor?` | `string` | Cor do texto do corpo. |
4471
- | `fontSize?` | `number` | Tamanho base da fonte em pixels. |
4472
-
4473
-
4474
- #### `IFooterConfig`
4475
-
4476
- *Arquivo:*
4477
-
4478
- | Propriedade | Tipo | Descrição |
4479
- | --- | --- | --- |
4480
- | `show` | `boolean` | Define se o rodapé será renderizado. |
4481
- | `links?` | `Array<{ text: string; url: string }>` | Lista de links textuais do rodapé. |
4482
- | `socialLinks?` | `Array<{ platform: 'facebook' 'twitter' 'linkedin' 'github'; url: string }>` | Lista de links sociais. |
4483
- | `copyrightText?` | `string` | Texto de copyright. |
4484
- | `unsubscribeText?` | `string` | Texto do link de descadastro. |
4485
- | `backgroundColor?` | `string` | Cor de fundo do rodapé. |
4486
- | `textColor?` | `string` | Cor do texto do rodapé. |
4487
-
4488
-
4489
- #### Item de `links`
4490
-
4491
- | Propriedade | Tipo | Descrição |
4492
- | --- | --- | --- |
4493
- | `text` | `string` | Texto exibido no link. |
4494
- | `url` | `string` | Destino do link. |
4495
-
4496
-
4497
- #### Item de `socialLinks`
4498
-
4499
- | Propriedade | Tipo | Descrição |
4500
- | --- | --- | --- |
4501
- | `platform` | `'facebook'` `'twitter'` `'linkedin'` `'github'` | Plataforma social usada para escolher o ícone. |
4502
- | `url` | `string` | Destino do link social. |
4503
-
4504
-
4505
- #### `TemplateOptions`
4506
-
4507
- *Arquivo:*
4508
-
4509
- | Propriedade | Tipo | Descrição |
4510
- | --- | --- | --- |
4511
- | `cache?` | `boolean` | Habilita ou desabilita o uso de cache. |
4512
- | `cacheTTL?` | `number` | Tempo de vida do cache em segundos. |
4513
- | `validateConfig?` | `boolean` | Ativa a validação do `ITemplateConfig`. |
4514
- | `minify?` | `boolean` | Controla a minificação do HTML renderizado. |
4515
- | `preview?` | `boolean` | Marca a renderização como prévia. |
4516
-
4517
-
4518
- #### `TemplateCache`
4519
-
4520
- *Arquivo:*
4521
-
4522
- | Propriedade | Tipo | Descrição |
4523
- | --- | --- | --- |
4524
- | `template` | `ITemplate` | Template enriquecido e armazenado em cache. |
4525
- | `createdAt` | `Date` | Momento de criação do cache. |
4526
- | `expiresAt` | `Date` | Momento de expiração do cache. |
4527
- | `hits` | `number` | Quantidade de acessos ao item em cache. |
4528
-
4529
-
4530
- ### Núcleo de criação e renderização
4531
-
4532
- #### `TemplateService`
4533
-
4534
- *Arquivo:*
4535
-
4536
- `TemplateService` concentra o ciclo de vida do template: cria, valida, renderiza, pré-visualiza, exporta, importa, lista temas, coleta estatísticas e mantém histórico. Ele também mantém cache em memória, limpa entradas expiradas em intervalos regulares e injeta metadados de renderização no payload passado ao template.
4537
-
4538
- **Inicialização**
4539
-
4540
- | Tipo | Descrição |
4541
- | --- | --- |
4542
- | `TemplateOptions` | Opções mescladas com os defaults internos: `cache: true`, `cacheTTL: 3600`, `validateConfig: true`, `minify: true`, `preview: false`. |
4543
-
4544
-
4545
- **Propriedades**
4546
-
4547
- | Propriedade | Tipo | Descrição |
4548
- | --- | --- | --- |
4549
- | `templateCache` | `Map<string, TemplateCache>` | Armazena templates por identificador calculado. |
4550
- | `defaultTTL` | `number` | TTL padrão em segundos. |
4551
- | `templateHistory` | `Map<string, ITemplate[]>` | Histórico de versões por identificador. |
4552
- | `options` | `TemplateOptions` | Configuração efetiva da instância. |
4553
-
4554
-
4555
- **Métodos públicos**
4556
-
4557
- | Method | Description |
4558
- | --- | --- |
4559
- | `createTemplate` | Cria um `ITemplate`, valida `ITemplateConfig` quando habilitado, calcula ID, reutiliza cache e registra histórico. |
4560
- | `cloneTemplate` | Cria um novo template a partir de um existente aplicando modificações rasas em `config`. |
4561
- | `renderTemplate` | Renderiza um template com metadados `_meta` e aplica minificação quando configurada. |
4562
- | `previewTemplate` | Cria um template sem cache e o renderiza em modo de prévia. |
4563
- | `getThemeInfo` | Retorna metadados do tema, variantes disponíveis e configuração padrão. |
4564
- | `listThemes` | Lista todos os `ThemeType` registrados no factory. |
4565
- | `getTemplateStats` | Calcula estatísticas do cache, histórico e hits por tema. |
4566
- | `clearCache` | Remove entradas do cache, opcionalmente filtrando por `ThemeType`. |
4567
- | `getTemplateHistory` | Retorna as versões armazenadas para um `templateId`. |
4568
- | `restoreTemplateVersion` | Restaura uma versão anterior a partir do histórico. |
4569
- | `preloadTemplates` | Pré-carrega uma lista de templates no cache. |
4570
- | `exportTemplate` | Serializa um template para JSON. |
4571
- | `importTemplate` | Desserializa JSON e recria o template. |
4572
- | `generateExampleTemplate` | Cria um template de demonstração com configuração padrão. |
4573
- | `isValidTemplate` | Verifica a forma estrutural de um objeto de template. |
4574
- | `getTemplateDetails` | Retorna template, histórico, cache e contador de uso de um ID. |
4575
-
4576
-
4577
- **Métodos internos**
4578
-
4579
- | Method | Description |
4580
- | --- | --- |
4581
- | `validateTemplateConfig` | Valida regras de `header`, `footer`, `layout`, `spacing` e `borderRadius`. |
4582
- | `generateTemplateId` | Gera o identificador com hash de `themeType`, `variant` e `config`. |
4583
- | `enhanceTemplate` | Anexa `getVersion`, `getId` e `clone` ao objeto do template. |
4584
- | `addToHistory` | Adiciona a versão atual ao histórico e mantém no máximo 10 entradas. |
4585
- | `cleanExpiredCache` | Remove templates cuja data de expiração já passou. |
4586
- | `minifyHtml` | Reduz espaços e comentários do HTML renderizado. |
4587
- | `getDefaultConfigForTheme` | Monta a configuração padrão base e aplica ajustes por tema. |
4588
-
4589
-
4590
- **Regras de validação aplicadas por ****`validateTemplateConfig`**
4591
-
4592
- - `header.logo.type === 'image'` exige `imageUrl`.
4593
- - `header.logo.type === 'text'` exige `text`.
4594
- - `footer.links` exige `text` e `url` em cada item.
4595
- - `layout` aceita apenas `full` e `minimal`.
4596
- - `spacing` aceita apenas `compact`, `normal` e `relaxed`.
4597
- - `borderRadius` aceita apenas `none`, `small`, `medium` e `large`.
4598
-
4599
- **Comportamento de cache e histórico**
4600
-
4601
- - O ID do template é derivado de `themeType`, `variant` e `config`.
4602
- - O cache guarda o template enriquecido com `hits`.
4603
- - O histórico preserva as últimas 10 versões por ID.
4604
- - `clearCache(themeType)` remove apenas os templates daquele tema.
4605
- - `previewTemplate` chama `createTemplate(..., { cache: false })`, evitando poluir o cache com prévias.
4606
-
4607
- #### `TemplateFactory`
4608
-
4609
- *Arquivo:*
4610
-
4611
- `TemplateFactory` é o ponto de materialização do domínio. Ele resolve o `ThemeType` para uma instância de tema, cria o objeto `ITemplate` e entrega a função `render` que delega a composição do HTML para `TemplateBuilder`.
4612
-
4613
- **Propriedades**
4614
-
4615
- | Propriedade | Tipo | Descrição |
4616
- | --- | --- | --- |
4617
- | `themes` | `Map<ThemeType, ITheme>` | Registro estático dos temas disponíveis e suas implementações. |
4618
-
4619
-
4620
- **Métodos públicos**
4621
-
4622
- | Method | Description |
4623
- | --- | --- |
4624
- | `createTemplate` | Cria o `ITemplate` com `name`, `theme`, `variant`, `config` e `render`. |
4625
- | `getTheme` | Retorna a implementação de tema associada ao `ThemeType`. |
4626
- | `listThemes` | Retorna a lista de `ThemeType` registrados no mapa. |
4627
- | `getThemeInfo` | Retorna `name`, `description` e `features` do tema. |
4628
-
4629
-
4630
- **Temas registrados no mapa**
4631
-
4632
- | ThemeType | Nome | Descrição | Features |
4633
- | --- | --- | --- | --- |
4634
- | `SYSTEM` | `System` | Tema limpo e profissional com cores adaptativas | Design minimalista, alta acessibilidade, compatibilidade total |
4635
- | `MONOKAI` | `Monokai` | Inspirado no tema de código, voltado a conteúdo técnico | Cores vibrantes, destaque de sintaxe, efeitos glow |
4636
- | `MODERN` | `Modern` | Design contemporâneo com gradientes e efeitos modernos | Gradientes elegantes, glassmorphism, animações suaves |
4637
- | `CORPORATE` | `Corporate` | Design profissional e elegante para empresas | Tipografia serifada, detalhes em dourado, layout estruturado |
4638
- | `MINIMAL` | `Minimal` | Design clean e focado no conteúdo | Sem distrações, espaçamento generoso, tipografia limpa |
4639
-
4640
-
4641
- **Comportamento do ****`render`**** retornado por ****`createTemplate`**
4642
-
4643
- - Instancia `TemplateBuilder` com `theme`, `config` e `variant`.
4644
- - Lê `data.template.config.body` para construir o conteúdo base.
4645
- - Usa `data.headerContent` como conteúdo opcional do cabeçalho.
4646
- - Só adiciona botão quando `body.buttonText` e `body.buttonUrl` existem.
4647
- - Finaliza com `buildFooter().build()`.
4648
-
4649
- #### `TemplateBuilder`
4650
-
4651
- TemplateFactory.createTemplate e TemplateService.renderTemplate não compartilham o mesmo formato de payload. O render gerado por TemplateFactory lê data.template.config.body, mas TemplateService.renderTemplate passa renderData sem a propriedade template. Já o caminho via EmailService.send funciona porque IEmailOptions inclui template e o objeto é repassado ao render. [!NOTE] IBodyConfig.buttonVariant aceita success e danger, mas TemplateBuilder.buildButton só tipa e trata primary e secondary. Na prática, qualquer valor diferente de primary cai no ramo de secondary.
4652
-
4653
- *Arquivo:*
4654
-
4655
- `TemplateBuilder` acumula fragmentos HTML em `template` e aplica variações visuais com base no tema e na variante. Ele é o responsável direto por transformar configurações de header, body, botão e footer em markup final.
4656
-
4657
- **Construtor**
4658
-
4659
- | Tipo | Descrição |
4660
- | --- | --- |
4661
- | `ITheme` | Tema concreto usado para cores, tipografia, espaçamento e recursos específicos. |
4662
- | `ITemplateConfig` | Configuração estrutural do template. |
4663
- | `'light'` `'dark'` | Variante visual aplicada ao tema. |
4664
-
4665
-
4666
- **Propriedades**
4667
-
4668
- | Propriedade | Tipo | Descrição |
4669
- | --- | --- | --- |
4670
- | `template` | `string` | Buffer interno com o HTML parcial em construção. |
4671
- | `theme` | `ITheme` | Tema efetivo do template. |
4672
- | `config` | `ITemplateConfig` | Configuração usada para decidir quais blocos renderizar. |
4673
- | `variant` | `'light'` `'dark'` | Variante corrente para escolher a paleta apropriada. |
4674
-
4675
-
4676
- **Métodos públicos**
4677
-
4678
- | Method | Description |
4679
- | --- | --- |
4680
- | `buildHeader` | Renderiza o cabeçalho e o logo, opcionalmente com conteúdo adicional. |
4681
- | `buildBody` | Renderiza o corpo principal e aplica formatação específica de tema. |
4682
- | `buildButton` | Renderiza o botão de CTA com estilos dependentes do tema e da variante. |
4683
- | `buildFooter` | Renderiza o rodapé com links, redes sociais e textos finais. |
4684
- | `build` | Finaliza o documento HTML completo com `doctype`, `head`, `body` e container. |
4685
-
4686
-
4687
- **Métodos internos**
4688
-
4689
- | Method | Description |
4690
- | --- | --- |
4691
- | `buildLogo` | Monta o logo textual ou em imagem. |
4692
- | `formatCorporateContent` | Formata `<blockquote>` e `<highlight>` para o estilo Corporate. |
4693
- | `formatMinimalContent` | Reescreve títulos e parágrafos para o estilo Minimal. |
4694
- | `highlightCode` | Transforma blocos `<code>` em `<pre>` com destaque de código. |
4695
- | `applySyntaxHighlighting` | Aplica coloração simplificada para keywords, strings, números e funções. |
4696
- | `buildFooterLinks` | Gera a área de links textuais do rodapé. |
4697
- | `buildSocialLinks` | Gera a área de links sociais com ícones. |
4698
- | `getSocialIcon` | Resolve a URL do ícone para cada plataforma suportada. |
4699
-
4700
-
4701
- **Comportamentos de composição HTML**
4702
-
4703
- - `buildHeader` usa `config.header.show` para decidir se renderiza o bloco.
4704
- - `buildLogo` aceita `type: 'text'` e `type: 'image'`.
4705
- - `buildBody` aplica estilos por tema:- `Corporate`: borda dourada, sombra e formatação de citações.
4706
- - `Minimal`: largura de conteúdo, tipografia leve e limpeza de markup.
4707
- - `Monokai`: destaque de código quando há `<code>`.
4708
- - `Modern`: raio, glassmorphism e gradientes.
4709
- - `buildButton` usa `buttonVariant` como `primary` ou `secondary`.
4710
- - `buildFooter` só renderiza links, redes e textos quando `config.footer.show` está ativo.
4711
- - `build()` encerra o HTML com container centralizado e media query para telas até `600px`.
4712
-
4713
- **Ícones sociais aceitos por ****`getSocialIcon`**
4714
-
4715
- `facebook`, `twitter`, `github`, `instagram`, `youtube`, `discord`, `reddit`, `pinterest`, `tiktok`, `gitlab`, `stackoverflow`, `medium`, `dribbble`, `behance`, `telegram`.
4716
-
4717
- ### Catálogo e seleção de temas
4718
-
4719
- `TemplateFactory` e `TemplateService` usam `ThemeType` como chave para descobrir o tema concreto e sua configuração padrão. `getThemeInfo` devolve o nome amigável, a descrição e as features do tema, além de `availableVariants` e `defaultConfig` em `TemplateService`.
4720
-
4721
- #### `getDefaultConfigForTheme`
4722
-
4723
- A configuração base retornada por `TemplateService` inclui:
4724
-
4725
- - `header.show = true`
4726
- - `header.logo.type = 'text'`
4727
- - `header.logo.text = 'MyApp'`
4728
- - `footer.show = true`
4729
- - `footer.copyrightText` com o ano corrente
4730
- - `layout = 'full'`
4731
- - `spacing = 'normal'`
4732
- - `borderRadius = 'medium'`
4733
-
4734
- Ajustes específicos por tema:
4735
-
4736
- - `MONOKAI`: `borderRadius = 'small'`
4737
- - `MODERN`: `borderRadius = 'large'` e `spacing = 'relaxed'`
4738
- - `CORPORATE`: `borderRadius = 'small'`
4739
- - `MINIMAL`: `borderRadius = 'none'` e `spacing = 'relaxed'`
4740
-
4741
- ## Feature Flows
4742
-
4743
- ### Criação de template e geração de HTML
4744
-
4745
- ```mermaid
4746
- sequenceDiagram
4747
- participant C as Chamador
4748
- participant TS as TemplateService
4749
- participant TF as TemplateFactory
4750
- participant TB as TemplateBuilder
4751
- participant T as ITemplate
4752
-
4753
- C->>TS: createTemplate
4754
- TS->>TS: validateTemplateConfig
4755
- TS->>TS: generateTemplateId
4756
- alt cache habilitado e id existente
4757
- TS-->>C: template em cache
4758
- else cache miss
4759
- TS->>TF: createTemplate
4760
- TF-->>TS: ITemplate
4761
- TS->>TS: enhanceTemplate
4762
- TS->>TS: addToHistory
4763
- TS-->>C: template enriquecido
4764
- end
4765
-
4766
- C->>TS: renderTemplate
4767
- TS->>T: render renderData
4768
- T->>TB: new TemplateBuilder
4769
- T->>TB: buildHeader buildBody buildButton buildFooter build
4770
- TB-->>T: HTML
4771
- T-->>TS: HTML
4772
- TS-->>C: HTML minificado
4773
- ```
4774
-
4775
- ### Preview de template
4776
-
4777
- ```mermaid
4778
- sequenceDiagram
4779
- participant C as Chamador
4780
- participant TS as TemplateService
4781
- participant TF as TemplateFactory
4782
- participant T as ITemplate
4783
- participant TB as TemplateBuilder
4784
-
4785
- C->>TS: previewTemplate
4786
- TS->>TS: createTemplate cache false
4787
- TS->>TF: createTemplate
4788
- TF-->>TS: ITemplate
4789
- TS->>TS: renderTemplate preview true
4790
- TS->>T: render renderData com _meta
4791
- T->>TB: new TemplateBuilder
4792
- T->>TB: buildHeader buildBody buildButton buildFooter build
4793
- TB-->>T: HTML
4794
- T-->>TS: HTML
4795
- TS-->>C: HTML minificado
4796
- ```
4797
-
4798
- ### Exportação, importação e restauração de versões
4799
-
4800
- `TemplateService` também manipula o ciclo de vida de configuração fora da renderização:
4801
-
4802
- - `exportTemplate` serializa `name`, `theme`, `variant`, `config`, `exportedAt` e `version`.
4803
- - `importTemplate` valida a presença de `theme`, `variant` e `config` antes de recriar o template.
4804
- - `restoreTemplateVersion` lê o histórico pelo `templateId` e recria a versão escolhida com `cache: false`.
4805
-
4806
- ## State Management
4807
-
4808
- ### Cache e histórico de templates
4809
-
4810
- | Estado | Origem | Uso |
4811
- | --- | --- | --- |
4812
- | `templateCache` | `Map<string, TemplateCache>` | Reaproveita templates por hash de configuração. |
4813
- | `templateHistory` | `Map<string, ITemplate[]>` | Guarda as últimas 10 versões por `templateId`. |
4814
- | `options.preview` | `TemplateOptions` | Marca a renderização como prévia em `_meta.isPreview`. |
4815
- | `_meta.renderDate` | `renderTemplate` | Carimba a hora da renderização. |
4816
- | `_meta.templateName` | `renderTemplate` | Registra o nome do template renderizado. |
4817
- | `_meta.theme` | `renderTemplate` | Registra o tema usado. |
4818
- | `_meta.variant` | `renderTemplate` | Registra a variante usada. |
4819
-
4820
-
4821
- ### Regras operacionais
4822
-
4823
- - `cacheTTL` é definido em segundos e convertido para milissegundos na inserção em cache.
4824
- - `cleanExpiredCache` roda a cada `3600000` ms.
4825
- - `clearCache(themeType)` remove apenas entradas do tema informado.
4826
- - `generateTemplateId` usa `JSON.stringify` do trio `themeType`, `variant` e `config`.
4827
- - `addToHistory` limita o histórico às 10 versões mais recentes.
4828
- - `enhanceTemplate` adiciona métodos dinâmicos `getVersion`, `getId` e `clone` ao objeto retornado.
4829
-
4830
- ## Error Handling
4831
-
4832
- | Contexto | Comportamento | Impacto |
4833
- | --- | --- | --- |
4834
- | `TemplateFactory.createTemplate` | Lança `Error` quando o tema não existe no mapa. | A criação é interrompida antes da composição HTML. |
4835
- | `TemplateService.validateTemplateConfig` | Acumula mensagens e lança um `Error` único com todas as violações. | O chamador recebe uma lista agregada de problemas de configuração. |
4836
- | `TemplateService.renderTemplate` | Envolve qualquer falha em `Failed to render template: ...`. | Padroniza o erro de renderização para o consumidor. |
4837
- | `TemplateService.importTemplate` | Lança `Failed to import template: ...` quando JSON é inválido ou campos obrigatórios faltam. | Bloqueia importações inconsistentes. |
4838
- | `TemplateService.restoreTemplateVersion` | Retorna `null` quando o histórico não existe ou o índice é inválido. | O fluxo pode tratar ausência de versão sem exceção. |
4839
- | `TemplateService.isValidTemplate` | Retorna `false` para qualquer estrutura fora do contrato esperado. | Permite validação booleana sem exceções. |
4840
-
4841
-
4842
- ## Dependencies
4843
-
4844
- ### Dependências internas diretas
4845
-
4846
- -
4847
- -
4848
- -
4849
- -
4850
- -
4851
- -
4852
- -
4853
- -
4854
- -
4855
- -
4856
-
4857
- ### Integração com o fluxo de envio
4858
-
4859
- `ITemplate` é consumido no contrato de email via `IEmailOptions.template`, e o método `EmailService.send` chama `template.render(options)` quando `html` não é fornecido. Isso conecta o núcleo de templates ao pipeline de envio sem acoplar o template ao transporte SMTP.
4860
-
4861
- ## Key Classes Reference
4862
-
4863
- | Class | Responsibility |
4864
- | --- | --- |
4865
- | `template.service.ts` | Orquestra criação, validação, renderização, cache, histórico, exportação e importação de templates. |
4866
- | `template-factory.ts` | Materializa `ITemplate` a partir de `ThemeType`, `variant` e `ITemplateConfig`. |
4867
- | `template-builder.ts` | Constrói o HTML final do email por composição de header, body, footer e botão. |
4868
- | `template.interface.ts` | Define `ITemplate`, `ITemplateConfig` e os contratos de configuração do template. |
4869
- | `theme.enum.ts` | Define os valores de seleção de tema usados pelo factory e pelo service. |
4870
- | `theme.interface.ts` | Define o contrato estrutural dos temas consumidos pelo builder. |
4871
-
4872
-
4873
- ---
133
+ ---