diff --git a/src/services/messages/help.ts b/src/services/messages/help.ts new file mode 100644 index 0000000..a754d65 --- /dev/null +++ b/src/services/messages/help.ts @@ -0,0 +1,100 @@ +/** + * Centralización de contenidos de ayuda (Help v2) + * Nota: Solo copy; no depende de flags ni del runtime. Integración en command.ts llega en Fase 4. + */ +import { section, bullets, code, italic } from '../../utils/formatting'; + +export function getQuickHelp(baseUrl?: string): string { + const parts: string[] = []; + + parts.push(section('Comandos básicos')); + parts.push( + bullets([ + `${code('/t n ...')} crear (acepta fecha y menciones)`, + `${code('/t ver')} en grupo · ${code('/t ver mis')} por DM · ${code('/t ver todos')}`, + `${code('/t x 26')} completar (máx. 10) · ${code('/t tomar 12')} · ${code('/t soltar 26')}`, + `${code('/t configurar diario|l-v|semanal|off [HH:MM]')}`, + `${code('/t web')}`, + ]) + ); + + parts.push( + italic('_El bot responde por DM, incluso si escribes desde un grupo._') + ); + + return parts.join('\n'); +} + +export function getFullHelp(baseUrl?: string): string { + const out: string[] = []; + + // Crear + out.push(section('Crear')); + out.push( + bullets([ + `${code('/t n Descripción [YYYY-MM-DD|YY-MM-DD|hoy|mañana] [@menciones...]')}`, + 'En DM: sin menciones → asignada al creador.', + 'En grupo: sin menciones → queda “sin responsable”.', + 'Fechas: usa la última válida encontrada; no acepta pasadas.', + ]) + ); + + // Listados + out.push(''); + out.push(section('Listados')); + out.push( + bullets([ + `${code('/t ver grupo')} pendientes del grupo actual (desde grupo activo).`, + `${code('/t ver mis')} tus pendientes (por DM).`, + `${code('/t ver todos')} tus pendientes + “sin responsable”.`, + 'En grupo: “sin responsable” solo del grupo actual.', + 'En DM: “sin responsable” de grupos donde eres miembro activo (si la snapshot es fresca).', + `${code('/t ver sin')} solo “sin responsable” del grupo actual (desde grupo).`, + 'Máx. 10 elementos por sección; se añade “… y N más” si hay más.', + 'Fechas en DD/MM y ⚠️ si están vencidas.', + ]) + ); + + // Fechas + out.push(''); + out.push(section('Fechas')); + out.push( + bullets([ + '`YYYY-MM-DD` o `YY-MM-DD` (se expande a `20YY-MM-DD`).', + '`hoy` y `mañana` (según TZ; por defecto Europe/Madrid).', + ]) + ); + + // Recordatorios + out.push(''); + out.push(section('Recordatorios')); + out.push( + bullets([ + `${code('/t configurar diario|l-v|semanal|off [HH:MM]')}`, + 'Alias: diario/diaria, laborables (l-v/lv), semanal, off/apagar.', + 'Si omites hora, se conserva la anterior o se usa 08:30 por defecto (semanal asume lunes).', + ]) + ); + + // Acceso web + out.push(''); + out.push(section('Acceso web')); + out.push( + bullets([ + `${code('/t web')} genera un enlace de acceso de un solo uso (10 min).`, + ]) + ); + + // Otros + out.push(''); + out.push(section('Otros')); + out.push( + bullets([ + 'IDs visibles con 4 dígitos, pero puedes escribirlos sin ceros (ej.: 26).', + 'Máx. 10 IDs en completar/tomar; separa por espacios o comas.', + 'En “gating” estricto de grupos, el bot puede no responder en grupos no permitidos.', + ]) + ); + + return out.join('\n'); +} diff --git a/tests/unit/services/help-content.test.ts b/tests/unit/services/help-content.test.ts new file mode 100644 index 0000000..2782d8c --- /dev/null +++ b/tests/unit/services/help-content.test.ts @@ -0,0 +1,38 @@ +import { describe, it, expect } from 'bun:test'; +import { getQuickHelp, getFullHelp } from '../../../src/services/messages/help'; + +describe('Help content (centralizado)', () => { + it('quick help incluye comandos básicos y /t web', () => { + const s = getQuickHelp(); + expect(s).toContain('/t n'); + expect(s).toContain('/t ver mis'); + expect(s).toContain('/t x 26'); + expect(s).toContain('/t configurar'); + expect(s).toContain('/t web'); + // Debe usar etiquetas en español para configurar + expect(s).toContain('diario|l-v|semanal|off'); + expect(s).not.toContain('daily|l-v|weekly|off'); + }); + + it('full help cubre scopes de "ver", formatos de fecha y límites', () => { + const s = getFullHelp(); + // Scopes + expect(s).toContain('/t ver grupo'); + expect(s).toContain('/t ver mis'); + expect(s).toContain('/t ver todos'); + expect(s).toContain('/t ver sin'); + + // Fechas + expect(s).toContain('YY-MM-DD'); + expect(s).toContain('20YY'); + expect(s).toContain('hoy'); + expect(s).toContain('mañana'); + + // Límites + expect(s).toContain('Máx. 10'); + + // Configuración en español + expect(s).toContain('diario|l-v|semanal|off'); + expect(s).not.toContain('daily|l-v|weekly|off'); + }); +});