@purecore/apify expõe a classe Apify, que herda de um roteador compatível com Express.
Você monta sua aplicação exatamente como faria com { express: () => app }: registra middlewares com app.use(...), define app.get/post/put/delete/patch(...) e finaliza com app.listen(...).
Os objetos Request e Response carregam params, query, body, baseUrl, originalUrl e helpers status, json, send, permitindo migrar handlers Express com mínimo esforço.
Acho que essa lib não precisa de muita explicação.
Instalação:
npm i @purecore/apify
yarn add @purecore/apify
bun add @purecore/apify
pnpm add @purecore/apify
Confira todas as mudanças e atualizações: CHANGELOG.md
import { Apify, jsonBodyParser } from '@purecore/apify';
const app = new Apify();
// Middleware global (body parser, logger, etc.)
app.use(jsonBodyParser);
// Rota com params e query
app.get('/users/:id', (req, res) => {
const { id } = req.params;
const { role } = req.query;
res.status(200).json({ id, role, message: 'Usuário encontrado' });
});
// Sub-router (igual express.Router)
const apiRouter = new Apify();
apiRouter.get('/status', (req, res) => res.json({ status: 'ok' }));
app.use('/api', apiRouter);
app.listen(3344, () => console.log('@purecore/apify rodando na porta 3344'));
modules/<resource>/routes.ts
O gerador cria um sub-roteador completo com todas as operações CRUD:
- POST
/– cria usuário em memória e retorna o registro persistido. - GET
/:id– busca um usuário específico (com 404 se não existir). - GET
/– lista todos os usuários, retornando{ total, data }. - PUT/PATCH
/:id– atualização pontual (updateOne) aceitando tanto PUT quanto PATCH. - PUT/PATCH
/bulk– atualização em massa (updateMany) recebendo{ ids: string[], data: Partial<User> }. - DELETE
/:id– remove usuário e responde 204 se tudo certo.
Basta importar e registrar:
import { usersRouter } from './modules/users/routes';
app.use('/users', usersRouter);
Você pode criar módulos automaticamente com:
npx @purecore/apify create crud users
O comando fará duas coisas:
- Gera
modules/users/routes.tscom todas as rotas CRUD usando o template acima. - Injeta automaticamente
import { usersRouter } from '../modules/users/routes';eapp.use('/users', usersRouter);no arquivosrc/index.ts(ou outro informado com--entry).
Caso seu arquivo principal esteja em outro caminho, passe --entry:
npx @purecore/apify create crud billing --entry apps/api/src/main.ts
Você pode usar os decorators para aplicar resiliência, observabilidade, segurança e performance em controladores class-based (igual ao Nest):
import {
CircuitBreaker,
Timeout,
Logs,
Metrics,
TraceSpan,
SmartCache,
AuthJWTGuard,
} from '@purecore/apify';
class UsersController {
@Logs()
@Metrics()
@TraceSpan('users.list')
@SmartCache({ ttlMs: 3000 })
@CircuitBreaker({ failureThreshold: 3 })
@Timeout({ ms: 2000 })
async list(req, res) {
res.json({ ok: true });
}
@AuthJWTGuard()
async create(req, res) {
res.status(201).json({ created: true });
}
}
@CircuitBreaker,@Timeout,@Failover
@Logs,@Metrics,@TraceSpan
@AuthExpressGuard,@XSSGuard,@AuthJWTGuard,@IdempotentGuard,@CSRFGuard
@SmartCache,@CQRS
@purecore/apify expõe a classe Apify, que herda de um roteador compatível com Express.
Você monta sua aplicação exatamente como faria com { express: () => app }: registra middlewares com app.use(...), define app.get/post/put/delete/patch(...) e finaliza com app.listen(...).
Os objetos Request e Response carregam params, query, body, baseUrl, originalUrl e helpers status, json, send, permitindo migrar handlers Express com mínimo esforço.
Acho que essa lib não precisa de muita explicação.
Instalação:
npm i @purecore/apify
yarn add @purecore/apify
bun add @purecore/apify
pnpm add @purecore/apifyimport { Apify, jsonBodyParser } from '@purecore/apify';
const app = new Apify();
// Middleware global (body parser, logger, etc.)
app.use(jsonBodyParser);
// Rota com params e query
app.get('/users/:id', (req, res) => {
const { id } = req.params;
const { role } = req.query;
res.status(200).json({ id, role, message: 'Usuário encontrado' });
});
// Sub-router (igual express.Router)
const apiRouter = new Apify();
apiRouter.get('/status', (req, res) => res.json({ status: 'ok' }));
app.use('/api', apiRouter);
app.listen(3344, () => console.log('@purecore/apify rodando na porta 3344'));O gerador cria um sub-roteador completo com todas as operações CRUD:
- POST
/– cria usuário em memória e retorna o registro persistido. - GET
/:id– busca um usuário específico (com 404 se não existir). - GET
/– lista todos os usuários, retornando{ total, data }. - PUT/PATCH
/:id– atualização pontual (updateOne) aceitando tanto PUT quanto PATCH. - PUT/PATCH
/bulk– atualização em massa (updateMany) recebendo{ ids: string[], data: Partial<User> }. - DELETE
/:id– remove usuário e responde 204 se tudo certo.
Basta importar e registrar:
import { usersRouter } from './modules/users/routes';
app.use('/users', usersRouter);Você pode criar módulos automaticamente com:
npx @purecore/apify create crud usersO comando fará duas coisas:
- Gera
modules/users/routes.tscom todas as rotas CRUD usando o template acima. - Injeta automaticamente
import { usersRouter } from '../modules/users/routes';eapp.use('/users', usersRouter);no arquivosrc/index.ts(ou outro informado com--entry).
Caso seu arquivo principal esteja em outro caminho, passe --entry:
npx @purecore/apify create crud billing --entry apps/api/src/main.tsO @purecore/apify possui um sistema inédito de auto-geração de código baseado em schemas Zod! Basta definir um schema Zod simples e o sistema gera automaticamente:
- Repository com operações CRUD completas
- Service com regras de negócio
- Controller com endpoints REST
- Routes com roteamento automático
- DTOs e Interfaces TypeScript
- Tests automatizados
- Configurações e Schemas de banco
- Crie um arquivo
.tscom schema Zod emsrc/modules/ - Execute o servidor - o sistema detecta e gera código automaticamente
- Pronto! Toda a estrutura CRUD está criada
// src/modules/patient.ts
import { z } from 'zod';
export const schema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
phone: z.string().min(10).max(15),
birthDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
address: z.object({
street: z.string(),
city: z.string(),
state: z.string(),
zipCode: z.string(),
}).optional(),
});Resultado: O sistema gera automaticamente:
src/modules/patient/
├── index.ts # Exportações principais
├── routes.ts # Rotas Express
├── config.ts # Configurações
├── database/
│ ├── repository.ts # Operações de banco
│ └── schema.ts # Schema SQL
├── services/
│ └── patient.service.ts # Regras de negócio
├── controllers/
│ └── patient.controller.ts # Handlers HTTP
├── types/
│ ├── dto.ts # Data Transfer Objects
│ └── interface.ts # Interfaces TypeScript
└── tests/
└── patient.test.ts # Testes automatizados
| Método | Endpoint | Descrição |
|---|---|---|
GET |
/patient |
Lista pacientes com paginação |
POST |
/patient |
Cria novo paciente |
GET |
/patient/:id |
Busca paciente por ID |
PUT |
/patient/:id |
Atualiza paciente |
DELETE |
/patient/:id |
Remove paciente |
GET /patient?search=João&page=1&limit=10&sortBy=name&sortOrder=asc- Zod validation em todos os inputs
- TypeScript types gerados automaticamente
- SQL schemas para bancos de dados
describe('Patient Module', () => {
it('should create a new patient', async () => {
const result = await patientService.create({
name: 'João Silva',
email: 'joao@email.com',
phone: '+5511999999999',
birthDate: '1990-01-01'
});
expect(result.id).toBeDefined();
});
});export interface IPatient {
id: string;
name: string;
email: string;
phone: string;
birthDate: string;
address?: {
street: string;
city: string;
state: string;
zipCode: string;
};
createdAt: string;
updatedAt: string;
}export class PatientDTO {
name!: string;
email!: string;
phone!: string;
birthDate!: string;
address?: Address;
static validate(data: any): { success: boolean; data?: PatientDTO } {
// Validação Zod automática
}
}export class PatientRepository {
async create(data: Omit<IPatient, 'id'>): Promise<IPatient>
async findById(id: string): Promise<IPatient | null>
async find(query: PatientQuery): Promise<PatientResult>
async update(id: string, data: Partial<IPatient>): Promise<IPatient | null>
async delete(id: string): Promise<boolean>
}export class PatientService {
async create(input: PatientCreateInput): Promise<IPatient>
async getById(id: string): Promise<IPatient>
async list(options: ListOptions): Promise<PaginatedResult>
async update(id: string, input: PatientUpdateInput): Promise<IPatient>
async delete(id: string): Promise<void>
}export class PatientController {
@ApifyCompleteSentinel
async list(req: Request, res: Response) {
// Circuit Breaker + Timeout + JWT + XSS + Cache + Logs + Metrics
}
@ApifyCompleteSentinel
async create(req: Request, res: Response) {
// Tudo automático!
}
}- ⚡ Desenvolvimento 10x mais rápido - De schema para API completa em segundos
- 🛡️ Segurança máxima - Todos os decorators aplicados automaticamente
- 🔧 Manutenção zero - Código consistente e padronizado
- 📊 Observabilidade completa - Logs, métricas e traces incluídos
- ✅ Testes automatizados - Cobertura completa gerada automaticamente
- 🎯 TypeScript first - Types seguros em todas as camadas
O sistema executa automaticamente quando:
- Servidor inicia - Detecta arquivos
.tssoltos emmodules/ - Modo desenvolvimento - Regenera código quando schemas mudam
- Comando manual - Via API do auto-generator
# Forçar regeneração
npm run generate-modules
# Limpar módulos gerados
npm run clean-modules
# Listar módulos
npm run list-modulesPara usar a configuração padrão completa, crie um arquivo .env baseado no template:
# Copie o template de configuração
cp src/env-config.ts .env
# Ou crie manualmente com:
cat > .env << 'EOF'
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
NO_AUTH="GET /health, POST /login, GET /status"
CIRCUIT_BREAKER_FAILURE_THRESHOLD=5
CIRCUIT_BREAKER_RESET_TIMEOUT=10000
TIMEOUT_DEFAULT_MS=30000
TIMEOUT_MAX_MS=60000
TIMEOUT_RETRY_ATTEMPTS=3
CACHE_DEFAULT_TTL=300
ENABLE_DETAILED_LOGS=true
ENABLE_METRICS=true
ENABLE_TRACES=true
ENABLE_XSS_PROTECTION=true
ENABLE_WS_RETRY_CHANNEL=true
NODE_ENV=development
PORT=3344
API_PREFIX=/api/v1
EOF| Variável | Descrição | Padrão |
|---|---|---|
JWT_SECRET |
Segredo para tokens JWT | your-super-secret-jwt-key-change-this-in-production |
NO_AUTH |
Rotas sem autenticação | GET /health, POST /login, GET /status |
TIMEOUT_DEFAULT_MS |
Timeout padrão (ms) | 30000 (30s) |
CIRCUIT_BREAKER_FAILURE_THRESHOLD |
Limite de falhas | 5 |
ENABLE_WS_RETRY_CHANNEL |
Canal WS para retries | true |
O @purecore/apify detecta automaticamente todas as pastas dentro de src/modules e carrega suas rotas com o prefixo padrão /api/v1.
src/
└── modules/
├── users/
│ └── routes.ts # ou routes/index.ts
└── products/
└── routes.ts
import { Apify } from '@purecore/apify';
const app = new Apify();
// ✅ Prefixo '/api/v1' configurado automaticamente
// ✅ Módulos carregados automaticamente
app.listen(3344, () => {
console.log('Módulos carregados:');
console.log('• GET /api/v1/users');
console.log('• GET /api/v1/products');
});Os módulos podem exportar o router de diferentes formas:
// routes.ts
import { Router } from '@purecore/apify';
const usersRouter = new Router();
// ... definir rotas ...
export { usersRouter }; // ✅ Detectado automaticamente
// ou export default usersRouter;O @purecore/apify inclui um sistema completo de tratamento de erro com status codes apropriados e formatação consistente.
import {
NotFoundError, // 404
BadRequestError, // 400
ValidationError, // 400 (com campo específico)
UnauthorizedError, // 401
ForbiddenError, // 403
ConflictError, // 409
InternalServerError // 500
} from '@purecore/apify';import { NotFoundError, ValidationError } from '@purecore/apify';
app.get('/users/:id', (req, res) => {
const { id } = req.params;
if (!id) {
throw new ValidationError('ID obrigatório', 'id', id);
}
const user = findUser(id);
if (!user) {
throw new NotFoundError(`Usuário ${id} não encontrado`);
}
res.json(user);
});import { errorHandler } from '@purecore/apify';
// Deve ser o ÚLTIMO middleware registrado
app.use(errorHandler);import { error, validationError } from '@purecore/apify';
// Atalho para lançar erro por status code
throw error(404, 'Recurso não encontrado');
// Erro de validação com campo específico
throw validationError('Email inválido', 'email', 'invalid-email');{
"error": {
"message": "Usuário não encontrado",
"statusCode": 404,
"type": "NotFoundError",
"timestamp": "2024-01-01T12:00:00.000Z",
"path": "/api/v1/users/999",
"method": "GET"
}
}O sistema automaticamente detecta e trata:
- Erros de validação:
ValidationError→ 400 - JSON malformado:
SyntaxError→ 400 - IDs inválidos:
CastError→ 400 - Registros duplicados: MongoDB 11000 → 409
- Problemas de conectividade:
ENOTFOUND→ 503 - Erros inesperados: Qualquer erro → 500
Esse utilitário vem no auxilio da geração de códigos em uma arquitetura simples e modular.
/**
* Script de teste para geração automática de código
*/
import { ZodSchemaAnalyzer, CodeGenerator } from './src/zod-analyzer';
import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
import { join } from 'node:path';
// Simula o schema do patients
import { z } from 'zod';
const patientSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
phone: z.string().min(10).max(15),
birthDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
address: z.object({
street: z.string(),
city: z.string(),
state: z.string(),
zipCode: z.string(),
}).optional(),
});
async function testGeneration() {
console.log('🧪 Testando geração de código para Patients...');
// Analisa o schema
const metadata = ZodSchemaAnalyzer.analyzeSchema(patientSchema, 'Patient');
console.log(`📊 Schema analisado: ${metadata.fields.length} campos`);
// Gera códigos
const codes = {
interface: CodeGenerator.generateInterface(metadata),
dto: CodeGenerator.generateDTO(metadata),
repository: CodeGenerator.generateRepository(metadata),
service: CodeGenerator.generateService(metadata),
controller: CodeGenerator.generateController(metadata),
routes: CodeGenerator.generateRoutes(metadata),
config: CodeGenerator.generateConfig(metadata),
databaseSchema: CodeGenerator.generateDatabaseSchema(metadata),
tests: CodeGenerator.generateTests(metadata),
index: CodeGenerator.generateIndex(metadata)
};
// Cria diretório de teste
const testDir = 'test-generated';
if (!existsSync(testDir)) {
mkdirSync(testDir);
}
// Salva arquivos
Object.entries(codes).forEach(([name, content]) => {
const fileName = `${name}.ts`;
writeFileSync(join(testDir, fileName), content);
console.log(`📝 Gerado: ${fileName}`);
});
console.log('✅ Geração concluída! Verifique a pasta test-generated/');
}
// Executa se chamado diretamente
if (require.main === module) {
testGeneration().catch(console.error);
}
export { testGeneration };O @purecore/apify agora vem com uma configuração padrão completa que ativa TODOS os decorators automaticamente! Basta usar o ApifyCompleteSentinel e sua API estará completamente equipada com resiliência, observabilidade, segurança e performance.
import { ApifyCompleteSentinel } from '@purecore/apify';
class UsersController {
@ApifyCompleteSentinel
async list(req, res) {
// ✨ Circuit Breaker + Timeout 30s + WS Retry Channel
// 📊 Logger + Metrics + TraceSpan
// 🔐 JWT Auth + XSS Protection
// 🚀 Smart Cache (5min TTL)
res.json({ ok: true });
}
}O que vem ativado por padrão:
- 🔄 Circuit Breaker (5 falhas, reset 10s)
- ⏱️ Timeout (30s, max 60s, 3 retries)
- 🔗 WS Retry Channel para processamento paralelo
- 📝 Logger, 📊 Metrics, 🔍 TraceSpan
- 🔐 JWT Auth (com suporte NO_AUTH)
- 🛡️ XSS Protection
- 🛡️ Helmet Security Headers (CSP, HSTS, X-Frame-Options, etc.)
- 🚀 Smart Cache (5min TTL)
Configure rotas que não precisam de autenticação via .env:
# .env
NO_AUTH="GET /health, POST /login, GET /status, GET /api/v1/public/info"Rotas como /health e /login já são excluídas automaticamente.
Você também pode usar os decorators individualmente para controle fino:
import {
CircuitBreaker,
Timeout,
Logs,
Metrics,
TraceSpan,
SmartCache,
AuthJWTGuard,
} from '@purecore/apify';
class UsersController {
@Logs()
@Metrics()
@TraceSpan('users.list')
@SmartCache({ ttlMs: 3000 })
@CircuitBreaker({ failureThreshold: 3 })
@Timeout({ ms: 2000 })
async list(req, res) {
res.json({ ok: true });
}
@AuthJWTGuard()
async create(req, res) {
res.status(201).json({ created: true });
}
}@CircuitBreaker,@Timeout,@Failover
@Logs,@Metrics,@TraceSpan
@AuthExpressGuard,@XSSGuard,@AuthJWTGuard,@IdempotentGuard,@CSRFGuard
@SmartCache,@CQRS
O @purecore/apify inclui uma implementação nativa e completa de todos os headers de segurança HTTP do Helmet.js, sem dependências externas. Todos os headers estão disponíveis como decorators individuais ou através do HelmetGuard que combina tudo automaticamente.
| Header | Decorator | Descrição |
|---|---|---|
Content-Security-Policy |
@CSPGuard |
Controla recursos que o navegador pode carregar |
Strict-Transport-Security |
@HSTSGuard |
Força conexões HTTPS |
X-Frame-Options |
@XFrameOptionsGuard |
Previne clickjacking |
X-Content-Type-Options |
@XContentTypeOptionsGuard |
Previne MIME sniffing |
X-XSS-Protection |
@XXSSProtectionGuard |
Desabilita filtro XSS do navegador |
Referrer-Policy |
@ReferrerPolicyGuard |
Controla envio de referrer |
Cross-Origin-Embedder-Policy |
@COEPGuard |
Previne carregamento cross-origin |
Cross-Origin-Opener-Policy |
@COOPGuard |
Isola janelas cross-origin |
Cross-Origin-Resource-Policy |
@CORPGuard |
Controla compartilhamento cross-origin |
X-Powered-By |
@XPoweredByGuard |
Remove header X-Powered-By |
Origin-Agent-Cluster |
@OriginAgentClusterGuard |
Melhora isolamento de processos |
import { HelmetGuard } from '@purecore/apify';
class SecureController {
@HelmetGuard({
contentSecurityPolicy: {
directives: {
'default-src': ["'self'"],
'script-src': ["'self'", 'https://trusted.cdn.com'],
'style-src': ["'self'", "'unsafe-inline'"]
}
},
strictTransportSecurity: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
referrerPolicy: { policy: 'strict-origin-when-cross-origin' }
})
async secureEndpoint(req, res) {
res.json({ secure: true });
}
}import {
CSPGuard,
HSTSGuard,
XFrameOptionsGuard,
ReferrerPolicyGuard
} from '@purecore/apify';
class ApiController {
// Content Security Policy personalizado
@CSPGuard({
directives: {
'default-src': ["'self'"],
'img-src': ["'self'", 'data:', 'https:'],
'script-src': ["'self'", "'unsafe-inline'"]
}
})
async getContent(req, res) {
res.json({ content: 'CSP protected' });
}
// HSTS com preload
@HSTSGuard({
maxAge: 63072000, // 2 anos
includeSubDomains: true,
preload: true
})
async secureConnection(req, res) {
res.json({ hsts: 'enabled' });
}
// Anti-clickjacking
@XFrameOptionsGuard({ action: 'DENY' })
async noFrames(req, res) {
res.json({ frames: 'denied' });
}
// Referrer Policy rigorosa
@ReferrerPolicyGuard({ policy: 'no-referrer' })
async privateData(req, res) {
res.json({ referrer: 'hidden' });
}
}import { helmet } from '@purecore/apify';
// Middleware completo
app.use(helmet());
// Middleware personalizado
app.use(helmet({
contentSecurityPolicy: false, // Desabilitar CSP
strictTransportSecurity: {
maxAge: 31536000
}
}));Quando você usa @HelmetGuard() ou helmet(), os seguintes headers são aplicados:
Content-Security-Policy: default-src 'self'; base-uri 'self'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src 'self' data: https:; object-src 'none'; script-src 'self'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; upgrade-insecure-requests
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Referrer-Policy: strict-origin-when-cross-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
X-Powered-By: (removido)
# .env
ENABLE_CSP=true
ENABLE_HSTS=true
HSTS_MAX_AGE=31536000
HSTS_INCLUDE_SUBDOMAINS=true
REFERRER_POLICY=strict-origin-when-cross-origin
X_FRAME_OPTIONS=SAMEORIGIN
COEP_POLICY=require-corp
COOP_POLICY=same-origin
CORP_POLICY=same-originO @purecore/apify implementa o padrão AON (Adaptive Observability Negotiation) com o inédito ❄️👁️ CrystalBox Mode, oferecendo três modos de observabilidade baseados na negociação de conteúdo HTTP.
| Modo | Header | Descrição |
|---|---|---|
| Black Box | Accept: application/json |
Modo tradicional - resposta única |
| Glass Box | Accept: application/x-ndjson |
Streaming de telemetria em tempo real |
| ❄️👁️ CrystalBox | Accept: application/x-ndjson + X-Crystal-Mode: interactive |
Observabilidade interativa com self-healing |
O sistema retorna headers específicos que indicam o estado do healing e observabilidade:
X-AON-Mode: glassbox
X-AON-Request-ID: aon_1703123456789_abc123
X-AON-Summary: {"totalEvents":5,"duration":1200,"healingAttempts":1}X-Crystal-Mode: interactive
X-Request-ID: crystal_1703123456789_def456
X-Healing-Enabled: true
X-Dev-Notification: enabled
X-User-Theme: dark
X-Offline-Ready: trueX-Processing-Status: 102
X-Healing-Attempt: 3
X-Dev-Notified: true
X-Early-Hints: 103import { aonMiddleware, crystalBoxMiddleware } from '@purecore/apify';
// AON básico (Glass Box)
app.use(aonMiddleware({
enabled: true,
debug: true,
healingTimeout: 10000
}));
// ❄️👁️ CrystalBox (Modo Interativo)
app.use(crystalBoxMiddleware({
crystalBox: {
enableWhatsApp: true,
enableSlack: true,
devContacts: {
whatsapp: process.env.DEV_WHATSAPP,
slack: process.env.DEV_SLACK
}
},
themeDetection: {
enabled: true,
defaultTheme: 'dark'
},
offlineSupport: {
enabled: true,
components: ['forms', 'cache', 'sync']
}
}));import { withCrystalBox, requestInteractiveHealing, sendEarlyHints } from '@purecore/apify';
app.get('/api/users/:id', withCrystalBox(async (req, res) => {
// Envia Early Hints (103) para preload
sendEarlyHints(req, {
theme: req.userTheme,
preloadLinks: ['/css/user-profile.css'],
offlineComponents: ['user-cache']
});
// Healing interativo se necessário
if (connectionFailed) {
const healed = await requestInteractiveHealing(
req,
'database_recovery',
'Conexão com banco perdida',
{ database: 'users_db', errorCode: 'ECONNREFUSED' }
);
if (!healed) {
// Sistema nunca falha - sempre tenta se curar
return res.status(503).json({ error: 'Healing em andamento...' });
}
}
return { user: userData };
}));HTTP/1.1 102 Processing
Content-Type: application/x-ndjson
X-Crystal-Mode: healing
X-Healing-Attempt: 3
X-Dev-Notification: sent
{"type":"healing","action":"database_recovery","attempt":3,"dev_notified":true}HTTP/1.1 103 Early Hints
Link: </css/user-theme-dark.css>; rel=preload; as=style
Link: </js/offline-components.js>; rel=preload; as=script
X-User-Theme: dark
X-Offline-Ready: true
{"type":"preload","theme":"dark","offline_components":["forms","cache","sync"]}Quando o healing automático falha, o sistema notifica desenvolvedores via:
// Configuração
DEV_WHATSAPP=+5511999999999
WHATSAPP_TOKEN=your_whatsapp_business_token
WHATSAPP_PHONE_ID=your_phone_number_id// Configuração
DEV_SLACK=#dev-alerts
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...// Configuração
DEV_TEAMS=#development
TEAMS_WEBHOOK_URL=https://outlook.office.com/webhook/...❄️�r️ CrystalBox Alert 🚨
Action: database_recovery
Description: Conexão com banco perdida
Attempt: 3
Request ID: crystal_1703123456789_abc123
Time: 2024-12-15T10:30:00.000Z
Metadata:
{
"database": "users_db",
"connectionPool": "primary",
"errorCode": "ECONNREFUSED"
}
Reply with:
• HEAL:crystal_1703123456789_abc123:retry - Try again
• HEAL:crystal_1703123456789_abc123:skip - Skip this step
• HEAL:crystal_1703123456789_abc123:custom:YOUR_CODE - Custom fix
// Endpoint automático para receber soluções
app.post('/api/v1/crystal/heal/:requestId', (req, res) => {
const { requestId } = req.params;
const solution = req.body;
// Sistema aplica solução automaticamente
developerNotificationService.receiveDeveloperResponse({
requestId,
action: solution.action, // 'retry', 'skip', 'custom'
customCode: solution.customCode,
parameters: solution.parameters
});
res.json({ message: 'Solução aplicada', requestId });
});# AON Configuration
AON_ENABLED=true
AON_DEBUG=true
AON_HEALING_TIMEOUT=10000
AON_MAX_TELEMETRY_EVENTS=1000
# ❄️👁️ CrystalBox Configuration
CRYSTALBOX_INTERACTIVE=true
CRYSTALBOX_MAX_AUTO_ATTEMPTS=3
CRYSTALBOX_DEV_NOTIFICATION_THRESHOLD=2
CRYSTALBOX_DEV_RESPONSE_TIMEOUT=30000
# Developer Notifications
DEV_WHATSAPP=+5511999999999
DEV_SLACK=#dev-alerts
DEV_TEAMS=#development
WHATSAPP_TOKEN=your_token
SLACK_WEBHOOK_URL=https://hooks.slack.com/...
TEAMS_WEBHOOK_URL=https://outlook.office.com/...
# Theme Detection
THEME_DETECTION_ENABLED=true
DEFAULT_THEME=dark
SUPPORTED_THEMES=light,dark,auto
# Offline Support
OFFLINE_SUPPORT_ENABLED=true
OFFLINE_COMPONENTS=forms,cache,sync,storage
CACHE_STRATEGY=aggressive- ❄️👁️ Nunca Falha: Sistema sempre tenta se curar antes de retornar erro
- 📱 Notificação Instantânea: Desenvolvedor recebe WhatsApp/Slack em tempo real
- 🚀 Early Hints: Preload inteligente de recursos baseado no tema do usuário
- 📱 Offline-First: Suporte automático para PWAs e aplicações offline
- 🤖 Healing Interativo: Desenvolvedor pode intervir e corrigir problemas em tempo real
- 📊 Observabilidade Total: Visibilidade completa do processo de healing
# Modo Black Box (tradicional)
curl -H "Accept: application/json" http://localhost:3000/api/v1/users/123
# Modo Glass Box (streaming)
curl -H "Accept: application/x-ndjson" http://localhost:3000/api/v1/users/123
# Modo ❄️👁️ CrystalBox (interativo)
curl -H "Accept: application/x-ndjson" \
-H "X-Crystal-Mode: interactive" \
-H "X-User-Theme: dark" \
http://localhost:3000/api/v1/users/123Para mais detalhes, consulte: docs/Observability.modes.md
