feat: instrumentar métricas de allowed_groups, admin, commands y sync

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
pull/1/head
borja 1 month ago
parent cdab9da161
commit 662c335824

@ -67,6 +67,23 @@ export class WebhookServer {
if (!Metrics.enabled()) {
return new Response('Metrics disabled', { status: 404 });
}
// Gauges de allowed_groups por estado (best-effort)
try {
const rows = WebhookServer.dbInstance
.prepare(`SELECT status, COUNT(*) AS c FROM allowed_groups GROUP BY status`)
.all() as any[];
let pending = 0, allowed = 0, blocked = 0;
for (const r of rows) {
const s = String(r?.status || '');
const c = Number(r?.c || 0);
if (s === 'pending') pending = c;
else if (s === 'allowed') allowed = c;
else if (s === 'blocked') blocked = c;
}
Metrics.set('allowed_groups_total_pending', pending);
Metrics.set('allowed_groups_total_allowed', allowed);
Metrics.set('allowed_groups_total_blocked', blocked);
} catch {}
const format = (process.env.METRICS_FORMAT || 'prom').toLowerCase() === 'json' ? 'json' : 'prom';
const body = Metrics.render(format as any);
return new Response(body, {

@ -2,6 +2,7 @@ import type { Database } from 'bun:sqlite';
import { db } from '../db';
import { AllowedGroups } from './allowed-groups';
import { normalizeWhatsAppId, isGroupId } from '../utils/whatsapp';
import { Metrics } from './metrics';
type AdminContext = {
sender: string; // normalized user id (digits only)
@ -82,7 +83,8 @@ export class AdminService {
if (!isGroupId(ctx.groupId)) {
return [{ recipient: sender, message: ' Este comando se debe usar dentro de un grupo.' }];
}
AllowedGroups.setStatus(ctx.groupId, 'allowed');
const changed = AllowedGroups.setStatus(ctx.groupId, 'allowed');
try { if (changed) Metrics.inc('admin_actions_total_allow'); } catch {}
return [{ recipient: sender, message: `✅ Grupo habilitado: ${ctx.groupId}` }];
}
@ -91,7 +93,8 @@ export class AdminService {
if (!isGroupId(ctx.groupId)) {
return [{ recipient: sender, message: ' Este comando se debe usar dentro de un grupo.' }];
}
AllowedGroups.setStatus(ctx.groupId, 'blocked');
const changed = AllowedGroups.setStatus(ctx.groupId, 'blocked');
try { if (changed) Metrics.inc('admin_actions_total_block'); } catch {}
return [{ recipient: sender, message: `✅ Grupo deshabilitado: ${ctx.groupId}` }];
}
@ -101,7 +104,8 @@ export class AdminService {
if (!isGroupId(arg)) {
return [{ recipient: sender, message: '⚠️ Debes indicar un group_id válido terminado en @g.us' }];
}
AllowedGroups.setStatus(arg, 'allowed');
const changed = AllowedGroups.setStatus(arg, 'allowed');
try { if (changed) Metrics.inc('admin_actions_total_allow'); } catch {}
return [{ recipient: sender, message: `✅ Grupo habilitado: ${arg}` }];
}
@ -111,7 +115,8 @@ export class AdminService {
if (!isGroupId(arg)) {
return [{ recipient: sender, message: '⚠️ Debes indicar un group_id válido terminado en @g.us' }];
}
AllowedGroups.setStatus(arg, 'blocked');
const changed = AllowedGroups.setStatus(arg, 'blocked');
try { if (changed) Metrics.inc('admin_actions_total_block'); } catch {}
return [{ recipient: sender, message: `✅ Grupo bloqueado: ${arg}` }];
}

@ -8,6 +8,7 @@ import { ICONS } from '../utils/icons';
import { padTaskId, codeId, formatDDMM, bold, italic } from '../utils/formatting';
import { IdentityService } from './identity';
import { AllowedGroups } from './allowed-groups';
import { Metrics } from './metrics';
type CommandContext = {
sender: string; // normalized user id (digits only), but accept raw too
@ -1068,6 +1069,7 @@ export class CommandService {
if (mode === 'enforce') {
try {
if (!AllowedGroups.isAllowed(context.groupId)) {
try { Metrics.inc('commands_blocked_total'); } catch {}
return [];
}
} catch {

@ -620,6 +620,7 @@ export class GroupSyncService {
try {
if (!AllowedGroups.isAllowed(groupId)) {
// Saltar grupos no permitidos en modo enforce
try { Metrics.inc('sync_skipped_group_total'); } catch {}
continue;
}
} catch {
@ -821,6 +822,7 @@ export class GroupSyncService {
try {
(AllowedGroups as any).dbInstance = this.dbInstance;
if (!AllowedGroups.isAllowed(groupId)) {
try { Metrics.inc('sync_skipped_group_total'); } catch {}
return { added: 0, updated: 0, deactivated: 0 };
}
} catch {

Loading…
Cancel
Save