smoonb 0.0.7 → 0.0.9

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.
@@ -1,412 +1,273 @@
1
- /**
2
- * Comando de checklist pós-restore
3
- * Verificação de integridade completa
4
- */
5
-
1
+ const { Command } = require('commander');
6
2
  const chalk = require('chalk');
7
- const { execSync } = require('child_process');
8
- const fs = require('fs');
9
3
  const path = require('path');
10
- const { getProjectId } = require('../utils/supabase');
11
-
12
- /**
13
- * Checklist pós-restore - Verificação de integridade
14
- * Resolve o problema: garantir que restauração foi bem-sucedida
15
- */
16
- async function checkCommand(options) {
17
- console.log(chalk.red.bold('🚀 smoonb - EXPERIMENTAL VERSION'));
18
- console.log(chalk.red.bold('⚠️ VERSÃO EXPERIMENTAL - NUNCA TESTADA EM PRODUÇÃO!'));
19
- console.log(chalk.red.bold('🚨 USE POR SUA CONTA E RISCO - Pode causar perda de dados!'));
20
- console.log(chalk.red.bold('❌ NÃO NOS RESPONSABILIZAMOS por qualquer perda de dados!\n'));
21
-
22
- console.log(chalk.cyan.bold('🔍 Checklist pós-restore - Verificação de integridade...\n'));
4
+ const fs = require('fs');
5
+ const { ensureBin, runCommand } = require('../utils/cli');
6
+ const { readConfig, validateFor } = require('../utils/config');
7
+ const { writeJson } = require('../utils/fsx');
8
+ const { IntrospectionService } = require('../services/introspect');
9
+ const { showBetaBanner } = require('../index');
23
10
 
24
- try {
25
- // Obter projectId (da opção ou da configuração)
26
- const projectId = options.projectId || getProjectId();
11
+ const checkCommand = new Command('check')
12
+ .description('Verificar integridade do projeto Supabase após restauração')
13
+ .option('-o, --output <file>', 'Arquivo de saída do relatório', 'check-report.json')
14
+ .action(async (options) => {
15
+ showBetaBanner();
27
16
 
28
- if (!projectId) {
29
- console.error(chalk.red.bold('❌ Erro: Project ID não encontrado'));
30
- console.log(chalk.yellow('💡 Opções:'));
31
- console.log(chalk.gray(' 1. Use: smoonb check --project-id <seu-project-id>'));
32
- console.log(chalk.gray(' 2. Configure: smoonb config --init'));
33
- console.log(chalk.gray(' 3. Ou defina SUPABASE_PROJECT_ID no ambiente'));
34
- console.log(chalk.gray(' 4. Ou edite ~/.smoonbrc e configure o projectId'));
35
- process.exit(1);
36
- }
17
+ try {
18
+ // Verificar se psql está disponível
19
+ const psqlPath = await ensureBin('psql');
20
+ if (!psqlPath) {
21
+ console.error(chalk.red(' psql não encontrado'));
22
+ console.log(chalk.yellow('💡 Instale PostgreSQL:'));
23
+ console.log(chalk.yellow(' https://www.postgresql.org/download/'));
24
+ process.exit(1);
25
+ }
26
+
27
+ // Carregar configuração
28
+ const config = await readConfig();
29
+ validateFor(config, 'backup'); // Usar mesma validação do backup
37
30
 
38
- console.log(chalk.blue('🆔 Project ID:'), projectId);
39
- console.log(chalk.blue('📊 Modo verbose:'), options.verbose ? 'Ativado' : 'Desativado');
40
- console.log();
31
+ const databaseUrl = config.supabase.databaseUrl;
32
+ if (!databaseUrl) {
33
+ console.error(chalk.red('❌ databaseUrl não configurada'));
34
+ console.log(chalk.yellow('💡 Configure databaseUrl no .smoonbrc'));
35
+ process.exit(1);
36
+ }
41
37
 
42
- // Executar verificações
43
- const results = await runPostRestoreChecks(projectId, options.verbose);
38
+ console.log(chalk.blue(`🔍 Verificando integridade do projeto: ${config.supabase.projectId}`));
44
39
 
45
- // Mostrar resumo
46
- showCheckSummary(results);
40
+ // Executar verificações
41
+ const report = await performChecks(config, databaseUrl);
47
42
 
48
- } catch (error) {
49
- console.error(chalk.red.bold('❌ Erro durante o checklist:'), error.message);
50
- process.exit(1);
51
- }
52
- }
43
+ // Salvar relatório
44
+ const reportPath = path.resolve(options.output);
45
+ await writeJson(reportPath, report);
53
46
 
54
- /**
55
- * Executar todas as verificações pós-restore
56
- */
57
- async function runPostRestoreChecks(projectId, verbose = false) {
58
- const checks = [
59
- { name: 'Database Connection', category: 'database', status: 'pending', details: [] },
60
- { name: 'Database Schema', category: 'database', status: 'pending', details: [] },
61
- { name: 'Database Extensions', category: 'database', status: 'pending', details: [] },
62
- { name: 'Edge Functions', category: 'functions', status: 'pending', details: [] },
63
- { name: 'Auth Providers', category: 'auth', status: 'pending', details: [] },
64
- { name: 'Auth Policies', category: 'auth', status: 'pending', details: [] },
65
- { name: 'Storage Buckets', category: 'storage', status: 'pending', details: [] },
66
- { name: 'Storage Objects', category: 'storage', status: 'pending', details: [] },
67
- { name: 'Realtime Settings', category: 'realtime', status: 'pending', details: [] },
68
- { name: 'API Endpoints', category: 'api', status: 'pending', details: [] }
69
- ];
47
+ // Mostrar resumo
48
+ showCheckSummary(report);
70
49
 
71
- console.log(chalk.blue.bold('🔍 Executando verificações...\n'));
50
+ console.log(chalk.green('\n🎉 Verificação concluída!'));
51
+ console.log(chalk.blue(`📋 Relatório salvo em: ${reportPath}`));
72
52
 
73
- // Executar verificações por categoria
74
- for (const check of checks) {
75
- try {
76
- await performCheck(check, projectId, verbose);
77
53
  } catch (error) {
78
- check.status = 'error';
79
- check.details.push(`Erro: ${error.message}`);
54
+ console.error(chalk.red(`❌ Erro na verificação: ${error.message}`));
55
+ process.exit(1);
80
56
  }
81
- }
57
+ });
82
58
 
83
- return checks;
84
- }
59
+ // Executar todas as verificações
60
+ async function performChecks(config, databaseUrl) {
61
+ const report = {
62
+ timestamp: new Date().toISOString(),
63
+ project_id: config.supabase.projectId,
64
+ checks: {}
65
+ };
85
66
 
86
- /**
87
- * Executar verificação individual
88
- */
89
- async function performCheck(check, projectId, verbose) {
90
- if (verbose) {
91
- console.log(chalk.gray(` - Verificando ${check.name}...`));
92
- }
67
+ // 1. Verificar conexão com database
68
+ console.log(chalk.blue('\n🔌 1/6 - Verificando conexão com database...'));
69
+ report.checks.database_connection = await checkDatabaseConnection(databaseUrl);
93
70
 
94
- switch (check.name) {
95
- case 'Database Connection':
96
- await checkDatabaseConnection(check, projectId, verbose);
97
- break;
98
- case 'Database Schema':
99
- await checkDatabaseSchema(check, projectId, verbose);
100
- break;
101
- case 'Database Extensions':
102
- await checkDatabaseExtensions(check, projectId, verbose);
103
- break;
104
- case 'Edge Functions':
105
- await checkEdgeFunctions(check, projectId, verbose);
106
- break;
107
- case 'Auth Providers':
108
- await checkAuthProviders(check, projectId, verbose);
109
- break;
110
- case 'Auth Policies':
111
- await checkAuthPolicies(check, projectId, verbose);
112
- break;
113
- case 'Storage Buckets':
114
- await checkStorageBuckets(check, projectId, verbose);
115
- break;
116
- case 'Storage Objects':
117
- await checkStorageObjects(check, projectId, verbose);
118
- break;
119
- case 'Realtime Settings':
120
- await checkRealtimeSettings(check, projectId, verbose);
121
- break;
122
- case 'API Endpoints':
123
- await checkAPIEndpoints(check, projectId, verbose);
124
- break;
125
- }
71
+ // 2. Verificar extensões
72
+ console.log(chalk.blue('\n🔧 2/6 - Verificando extensões...'));
73
+ report.checks.extensions = await checkExtensions(databaseUrl);
74
+
75
+ // 3. Verificar tabelas
76
+ console.log(chalk.blue('\n📊 3/6 - Verificando tabelas...'));
77
+ report.checks.tables = await checkTables(databaseUrl);
78
+
79
+ // 4. Verificar políticas RLS
80
+ console.log(chalk.blue('\n🔒 4/6 - Verificando políticas RLS...'));
81
+ report.checks.rls_policies = await checkRLSPolicies(databaseUrl);
82
+
83
+ // 5. Verificar Realtime
84
+ console.log(chalk.blue('\n🔄 5/6 - Verificando Realtime...'));
85
+ report.checks.realtime = await checkRealtime(databaseUrl);
86
+
87
+ // 6. Verificar Storage
88
+ console.log(chalk.blue('\n📦 6/6 - Verificando Storage...'));
89
+ report.checks.storage = await checkStorage(config);
90
+
91
+ return report;
126
92
  }
127
93
 
128
- /**
129
- * Verificar conexão com database
130
- */
131
- async function checkDatabaseConnection(check, projectId, verbose) {
94
+ // Verificar conexão com database
95
+ async function checkDatabaseConnection(databaseUrl) {
132
96
  try {
133
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
134
-
135
- // Tentar conectar via psql
136
- const testCmd = `psql "${dbUrl}" -c "SELECT 1;"`;
137
- execSync(testCmd, { stdio: 'pipe' });
97
+ const { stdout } = await runCommand(
98
+ `psql "${databaseUrl}" -t -c "SELECT 1 as test_connection;"`
99
+ );
138
100
 
139
- check.status = 'ok';
140
- check.details.push('Conexão estabelecida com sucesso');
141
-
142
- if (verbose) {
143
- console.log(chalk.gray(' ✅ Conexão com database OK'));
101
+ if (stdout.trim() === '1') {
102
+ return { status: 'ok', message: 'Conexão estabelecida com sucesso' };
103
+ } else {
104
+ return { status: 'error', message: 'Resposta inesperada da database' };
144
105
  }
145
106
  } catch (error) {
146
- check.status = 'warning';
147
- check.details.push('Conexão falhou (credenciais não configuradas)');
148
-
149
- if (verbose) {
150
- console.log(chalk.gray(' ⚠️ Conexão com database falhou'));
151
- }
107
+ return { status: 'error', message: `Falha na conexão: ${error.message}` };
152
108
  }
153
109
  }
154
110
 
155
- /**
156
- * Verificar schema da database
157
- */
158
- async function checkDatabaseSchema(check, projectId, verbose) {
111
+ // Verificar extensões
112
+ async function checkExtensions(databaseUrl) {
159
113
  try {
160
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
161
-
162
- // Verificar tabelas principais
163
- const schemaCmd = `psql "${dbUrl}" -c "SELECT schemaname, tablename FROM pg_tables WHERE schemaname = 'public';"`;
164
- const output = execSync(schemaCmd, { encoding: 'utf8', stdio: 'pipe' });
114
+ const query = `
115
+ SELECT extname, extversion
116
+ FROM pg_extension
117
+ ORDER BY extname;
118
+ `;
165
119
 
166
- const lines = output.split('\n').filter(line => line.trim() && !line.includes('schemaname'));
167
- const tableCount = lines.length;
120
+ const { stdout } = await runCommand(
121
+ `psql "${databaseUrl}" -t -c "${query}"`
122
+ );
168
123
 
169
- check.status = 'ok';
170
- check.details.push(`${tableCount} tabelas encontradas no schema public`);
124
+ const extensions = stdout.trim().split('\n')
125
+ .filter(line => line.trim())
126
+ .map(line => {
127
+ const [name, version] = line.trim().split('|');
128
+ return { name: name?.trim(), version: version?.trim() };
129
+ });
171
130
 
172
- if (verbose) {
173
- console.log(chalk.gray(` ✅ Schema OK (${tableCount} tabelas)`));
174
- }
131
+ return {
132
+ status: 'ok',
133
+ message: `${extensions.length} extensões encontradas`,
134
+ data: extensions
135
+ };
175
136
  } catch (error) {
176
- check.status = 'warning';
177
- check.details.push('Não foi possível verificar schema (credenciais não configuradas)');
178
-
179
- if (verbose) {
180
- console.log(chalk.gray(' ⚠️ Verificação de schema falhou'));
181
- }
137
+ return { status: 'error', message: `Erro ao verificar extensões: ${error.message}` };
182
138
  }
183
139
  }
184
140
 
185
- /**
186
- * Verificar extensões da database
187
- */
188
- async function checkDatabaseExtensions(check, projectId, verbose) {
141
+ // Verificar tabelas
142
+ async function checkTables(databaseUrl) {
189
143
  try {
190
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
144
+ const query = `
145
+ SELECT schemaname, tablename, tableowner
146
+ FROM pg_tables
147
+ WHERE schemaname IN ('public', 'auth', 'storage')
148
+ ORDER BY schemaname, tablename;
149
+ `;
191
150
 
192
- // Verificar extensões instaladas
193
- const extensionsCmd = `psql "${dbUrl}" -c "SELECT extname FROM pg_extension;"`;
194
- const output = execSync(extensionsCmd, { encoding: 'utf8', stdio: 'pipe' });
151
+ const { stdout } = await runCommand(
152
+ `psql "${databaseUrl}" -t -c "${query}"`
153
+ );
195
154
 
196
- const lines = output.split('\n').filter(line => line.trim() && !line.includes('extname'));
197
- const extensionCount = lines.length;
155
+ const tables = stdout.trim().split('\n')
156
+ .filter(line => line.trim())
157
+ .map(line => {
158
+ const [schema, table, owner] = line.trim().split('|');
159
+ return {
160
+ schema: schema?.trim(),
161
+ table: table?.trim(),
162
+ owner: owner?.trim()
163
+ };
164
+ });
198
165
 
199
- check.status = 'ok';
200
- check.details.push(`${extensionCount} extensões instaladas`);
201
-
202
- if (verbose) {
203
- console.log(chalk.gray(` ✅ Extensões OK (${extensionCount} instaladas)`));
204
- }
166
+ return {
167
+ status: 'ok',
168
+ message: `${tables.length} tabelas encontradas`,
169
+ data: tables
170
+ };
205
171
  } catch (error) {
206
- check.status = 'warning';
207
- check.details.push('Não foi possível verificar extensões (credenciais não configuradas)');
208
-
209
- if (verbose) {
210
- console.log(chalk.gray(' ⚠️ Verificação de extensões falhou'));
211
- }
172
+ return { status: 'error', message: `Erro ao verificar tabelas: ${error.message}` };
212
173
  }
213
174
  }
214
175
 
215
- /**
216
- * Verificar Edge Functions
217
- */
218
- async function checkEdgeFunctions(check, projectId, verbose) {
176
+ // Verificar políticas RLS
177
+ async function checkRLSPolicies(databaseUrl) {
219
178
  try {
220
- // Verificar se Supabase CLI está disponível
221
- execSync('supabase --version', { stdio: 'pipe' });
179
+ const query = `
180
+ SELECT COUNT(*) as policy_count
181
+ FROM pg_policies;
182
+ `;
222
183
 
223
- // Listar functions remotas
224
- const listCmd = 'supabase functions list';
225
- const output = execSync(listCmd, { encoding: 'utf8', stdio: 'pipe' });
184
+ const { stdout } = await runCommand(
185
+ `psql "${databaseUrl}" -t -c "${query}"`
186
+ );
226
187
 
227
- if (output.trim()) {
228
- const lines = output.split('\n').filter(line => line.trim());
229
- const functionCount = lines.length;
230
-
231
- check.status = 'ok';
232
- check.details.push(`${functionCount} Edge Functions encontradas`);
233
-
234
- if (verbose) {
235
- console.log(chalk.gray(` ✅ Edge Functions OK (${functionCount} encontradas)`));
236
- }
237
- } else {
238
- check.status = 'warning';
239
- check.details.push('Nenhuma Edge Function encontrada');
240
-
241
- if (verbose) {
242
- console.log(chalk.gray(' ⚠️ Nenhuma Edge Function encontrada'));
243
- }
244
- }
245
- } catch (error) {
246
- check.status = 'warning';
247
- check.details.push('Supabase CLI não encontrado ou projeto não configurado');
188
+ const policyCount = parseInt(stdout.trim());
248
189
 
249
- if (verbose) {
250
- console.log(chalk.gray(' ⚠️ Verificação de Edge Functions falhou'));
251
- }
252
- }
253
- }
254
-
255
- /**
256
- * Verificar Auth Providers
257
- */
258
- async function checkAuthProviders(check, projectId, verbose) {
259
- // TODO: Implementar verificação real via Supabase API
260
- check.status = 'warning';
261
- check.details.push('Verificação de Auth Providers em desenvolvimento');
262
-
263
- if (verbose) {
264
- console.log(chalk.gray(' ⚠️ Verificação de Auth Providers em desenvolvimento'));
265
- }
266
- }
267
-
268
- /**
269
- * Verificar Auth Policies
270
- */
271
- async function checkAuthPolicies(check, projectId, verbose) {
272
- // TODO: Implementar verificação real via Supabase API
273
- check.status = 'warning';
274
- check.details.push('Verificação de Auth Policies em desenvolvimento');
275
-
276
- if (verbose) {
277
- console.log(chalk.gray(' ⚠️ Verificação de Auth Policies em desenvolvimento'));
278
- }
279
- }
280
-
281
- /**
282
- * Verificar Storage Buckets
283
- */
284
- async function checkStorageBuckets(check, projectId, verbose) {
285
- // TODO: Implementar verificação real via Supabase API
286
- check.status = 'warning';
287
- check.details.push('Verificação de Storage Buckets em desenvolvimento');
288
-
289
- if (verbose) {
290
- console.log(chalk.gray(' ⚠️ Verificação de Storage Buckets em desenvolvimento'));
291
- }
292
- }
293
-
294
- /**
295
- * Verificar Storage Objects
296
- */
297
- async function checkStorageObjects(check, projectId, verbose) {
298
- // TODO: Implementar verificação real via Supabase API
299
- check.status = 'warning';
300
- check.details.push('Verificação de Storage Objects em desenvolvimento');
301
-
302
- if (verbose) {
303
- console.log(chalk.gray(' ⚠️ Verificação de Storage Objects em desenvolvimento'));
190
+ return {
191
+ status: 'ok',
192
+ message: `${policyCount} políticas RLS encontradas`,
193
+ data: { policy_count: policyCount }
194
+ };
195
+ } catch (error) {
196
+ return { status: 'error', message: `Erro ao verificar políticas RLS: ${error.message}` };
304
197
  }
305
198
  }
306
199
 
307
- /**
308
- * Verificar Realtime Settings
309
- */
310
- async function checkRealtimeSettings(check, projectId, verbose) {
311
- // TODO: Implementar verificação real via Supabase API
312
- check.status = 'warning';
313
- check.details.push('Verificação de Realtime Settings em desenvolvimento');
314
-
315
- if (verbose) {
316
- console.log(chalk.gray(' ⚠️ Verificação de Realtime Settings em desenvolvimento'));
200
+ // Verificar Realtime
201
+ async function checkRealtime(databaseUrl) {
202
+ try {
203
+ const query = `
204
+ SELECT pubname
205
+ FROM pg_publication
206
+ ORDER BY pubname;
207
+ `;
208
+
209
+ const { stdout } = await runCommand(
210
+ `psql "${databaseUrl}" -t -c "${query}"`
211
+ );
212
+
213
+ const publications = stdout.trim().split('\n')
214
+ .filter(line => line.trim())
215
+ .map(line => line.trim());
216
+
217
+ return {
218
+ status: 'ok',
219
+ message: `${publications.length} publicações Realtime encontradas`,
220
+ data: { publications }
221
+ };
222
+ } catch (error) {
223
+ return { status: 'error', message: `Erro ao verificar Realtime: ${error.message}` };
317
224
  }
318
225
  }
319
226
 
320
- /**
321
- * Verificar API Endpoints
322
- */
323
- async function checkAPIEndpoints(check, projectId, verbose) {
227
+ // Verificar Storage
228
+ async function checkStorage(config) {
324
229
  try {
325
- const supabaseUrl = process.env.SUPABASE_URL || `https://${projectId}.supabase.co`;
230
+ const introspection = new IntrospectionService(config);
231
+ const storageInventory = await introspection.getStorageInventory();
326
232
 
327
- // Verificar endpoint de health
328
- const healthUrl = `${supabaseUrl}/rest/v1/`;
233
+ const bucketCount = storageInventory.buckets?.length || 0;
234
+ const totalObjects = storageInventory.buckets?.reduce(
235
+ (total, bucket) => total + (bucket.objects?.length || 0), 0
236
+ ) || 0;
329
237
 
330
- // Simular verificação (TODO: implementar verificação real)
331
- check.status = 'ok';
332
- check.details.push('API endpoints respondendo');
333
-
334
- if (verbose) {
335
- console.log(chalk.gray(' ✅ API endpoints OK'));
336
- }
238
+ return {
239
+ status: 'ok',
240
+ message: `${bucketCount} buckets e ${totalObjects} objetos encontrados`,
241
+ data: storageInventory
242
+ };
337
243
  } catch (error) {
338
- check.status = 'warning';
339
- check.details.push('Não foi possível verificar API endpoints');
340
-
341
- if (verbose) {
342
- console.log(chalk.gray(' ⚠️ Verificação de API endpoints falhou'));
343
- }
244
+ return { status: 'error', message: `Erro ao verificar Storage: ${error.message}` };
344
245
  }
345
246
  }
346
247
 
347
- /**
348
- * Mostrar resumo das verificações
349
- */
350
- function showCheckSummary(results) {
351
- console.log(chalk.blue.bold('\n📊 Resumo das Verificações:\n'));
352
-
353
- // Agrupar por categoria
354
- const categories = {};
355
- results.forEach(check => {
356
- if (!categories[check.category]) {
357
- categories[check.category] = [];
358
- }
359
- categories[check.category].push(check);
360
- });
361
-
362
- // Mostrar por categoria
363
- Object.entries(categories).forEach(([category, checks]) => {
364
- const categoryName = category.charAt(0).toUpperCase() + category.slice(1);
365
- console.log(chalk.cyan.bold(`📁 ${categoryName}:`));
248
+ // Mostrar resumo das verificações
249
+ function showCheckSummary(report) {
250
+ console.log(chalk.blue('\n📋 RESUMO DAS VERIFICAÇÕES:'));
251
+ console.log(chalk.blue('═'.repeat(50)));
252
+
253
+ for (const [checkName, result] of Object.entries(report.checks)) {
254
+ const icon = result.status === 'ok' ? '✅' : '❌';
255
+ const color = result.status === 'ok' ? chalk.green : chalk.red;
366
256
 
367
- checks.forEach(check => {
368
- const icon = check.status === 'ok' ? '✅' :
369
- check.status === 'warning' ? '⚠️' : '❌';
370
- const statusColor = check.status === 'ok' ? chalk.green :
371
- check.status === 'warning' ? chalk.yellow : chalk.red;
372
-
373
- console.log(` ${icon} ${statusColor(check.name)}`);
374
-
375
- if (check.details.length > 0) {
376
- check.details.forEach(detail => {
377
- console.log(chalk.gray(` - ${detail}`));
378
- });
379
- }
380
- });
381
- console.log();
382
- });
383
-
384
- // Estatísticas gerais
385
- const totalChecks = results.length;
386
- const okChecks = results.filter(c => c.status === 'ok').length;
387
- const warningChecks = results.filter(c => c.status === 'warning').length;
388
- const errorChecks = results.filter(c => c.status === 'error').length;
389
-
390
- console.log(chalk.blue.bold('📈 Estatísticas:'));
391
- console.log(chalk.green(`✅ OK: ${okChecks}/${totalChecks}`));
392
- console.log(chalk.yellow(`⚠️ Avisos: ${warningChecks}/${totalChecks}`));
393
- console.log(chalk.red(`❌ Erros: ${errorChecks}/${totalChecks}`));
394
-
395
- // Status geral
396
- if (errorChecks === 0 && warningChecks === 0) {
397
- console.log(chalk.green.bold('\n🎉 Todas as verificações passaram com sucesso!'));
398
- } else if (errorChecks === 0) {
399
- console.log(chalk.yellow.bold('\n⚠️ Verificações concluídas com avisos'));
400
- console.log(chalk.gray(' - Projeto funcional, mas algumas verificações precisam de atenção'));
257
+ console.log(`${icon} ${color(checkName.replace(/_/g, ' ').toUpperCase())}: ${result.message}`);
258
+ }
259
+
260
+ const okCount = Object.values(report.checks).filter(c => c.status === 'ok').length;
261
+ const totalCount = Object.keys(report.checks).length;
262
+
263
+ console.log(chalk.blue('═'.repeat(50)));
264
+ console.log(chalk.blue(`📊 Resultado: ${okCount}/${totalCount} verificações passaram`));
265
+
266
+ if (okCount === totalCount) {
267
+ console.log(chalk.green('🎉 Todas as verificações passaram!'));
401
268
  } else {
402
- console.log(chalk.red.bold('\n❌ Verificações encontraram problemas críticos'));
403
- console.log(chalk.gray(' - Alguns componentes podem não estar funcionando corretamente'));
269
+ console.log(chalk.yellow('⚠️ Algumas verificações falharam. Verifique o relatório completo.'));
404
270
  }
405
-
406
- console.log(chalk.yellow('\n💡 Dicas:'));
407
- console.log(chalk.gray(' - Configure credenciais: smoonb config --init'));
408
- console.log(chalk.gray(' - Instale Supabase CLI: npm install -g supabase'));
409
- console.log(chalk.gray(' - Execute verificações detalhadas: smoonb check --verbose'));
410
271
  }
411
272
 
412
- module.exports = checkCommand;
273
+ module.exports = checkCommand;