Aprende a planificar, construir y lanzar una app web de anuncios internos con recibos de lectura, roles, segmentación y analítica sencilla.

Una app de anuncios internos resuelve un problema sencillo pero costoso: las actualizaciones importantes se pierden y nadie puede responder con confianza “¿lo vio todo el mundo?”. Hilos de correo, canales de chat y publicaciones en la intranet generan ruido, y la rendición de cuentas se vuelve borrosa —especialmente para cambios de política, avisos de seguridad, cierres de oficina y plazos de beneficios.
Con recibos de lectura integrados, el resultado cambia de “lo enviamos” a “podemos confirmar que se leyó”. Esa claridad ayuda a los equipos a actuar más rápido, reduce preguntas repetidas y da a RR. HH. y managers una forma fiable de hacer seguimiento sin adivinar.
No es solo una herramienta de RR. HH. Es un sistema de comunicaciones internas usado por distintos grupos por distintas razones:
La clave es que cada audiencia se beneficia: los editores saben qué pasó y los empleados saben dónde mirar para no perder anuncios críticos.
Define el propósito de la app en una frase: entregar anuncios clave a los empleados correctos y confirmar quién los leyó.
Eso implica algunas decisiones de producto que tomarás más adelante (segmentación, control de acceso por roles, registro de auditoría), pero mantén el “por qué” nítido. Si no puedes explicar por qué un recibo de lectura importa en tu organización, te costará decidir qué datos almacenar y qué informes construir.
Elige métricas que reflejen tanto la efectividad de la entrega como el comportamiento de los empleados:
Establece objetivos según el tipo de anuncio. Un post de “almuerzo gratis el viernes” no debe tener la misma meta que un “nuevo requisito de seguridad”. Para mensajes críticos, puedes apuntar al 95% de lecturas en 24–48 horas, y usar esa meta para diseñar notificaciones y seguimientos.
Si buscas una métrica norte, usa: % de anuncios críticos leídos por la audiencia objetivo completa dentro del periodo requerido.
Un alcance claro evita que tu app de anuncios se convierta en un portal “hacer-de-todo”. Empieza escribiendo quién la usará (comunicaciones, RR. HH., TI, managers, todo el personal) y qué se considera éxito (por ejemplo, actualizaciones críticas reconocidas en 24 horas).
Define una primera versión que resuelva el problema central: publicar anuncios dirigidos y confirmar que se leyeron.
Características imprescindibles (v1):
Características deseables (posteriores):
Si quieres validar el alcance rápidamente, un prototipo rápido puede reducir el riesgo en las partes complejas (segmentación, lógica de recibos, paneles) antes de invertir en una implementación completa. Por ejemplo, los equipos a menudo usan Koder.ai para generar una app interna vía chat: así pueden iterar en los flujos (feed, vista detallada, reconocer) y exportar el código fuente cuando los requisitos estén estables.
Diferentes anuncios necesitan expectativas distintas. Acordad un pequeño conjunto de tipos desde el principio:
Para cada tipo, captura los campos requeridos (fecha de caducidad, reconocimiento requerido, prioridad) y quién puede publicar.
Sé específico para que ingeniería y stakeholders se alineen:
Este documento de alcance será tu plan de construcción y referencia de control de cambios cuando lleguen nuevas solicitudes.
Roles y permisos claros mantienen los anuncios confiables, previenen publicaciones accidentales a toda la empresa y hacen que los recibos de lectura sean defendibles si surgen dudas.
Admin gestiona el sistema: aprovisionamiento de usuarios, ajustes org, reglas de retención e integraciones. Los admins no necesitan crear anuncios en el día a día.
Publisher crea y publica anuncios. Normalmente Comunicación, RR. HH. o TI.
Manager puede redactar o solicitar anuncios para su equipo y ver recibos de los anuncios que poseen (o de su línea de reporte).
Employee lee anuncios y puede reconocerlos (si se requiere). Los empleados normalmente no deberían ver los recibos de otras personas.
Auditor (opcional) tiene acceso de solo lectura a anuncios publicados, registro de auditoría y exportaciones para revisiones de cumplimiento.
Como mínimo, define permisos para: crear, editar, publicar, archivar, ver recibos y exportar. Implementa permisos a nivel de acción (no solo por rol) para poder adaptar reglas sin reescribir la lógica.
Un valor por defecto práctico:
Si las aprobaciones importan, separa redacción de publicación:
Documenta estas reglas en una página corta de “política de acceso” y enlázala internamente (por ejemplo, /help/access-policy).
Antes de dibujar características, imagina momentos: qué necesita hacer un empleado en menos de 10 segundos y qué necesita hacer un admin sin formación. Una UX clara reduce disputas de “no lo vi” cuando añades recibos de lectura.
Login debe ser sin fricciones: inicio con un botón único (si está disponible), estados de error claros y un camino directo de regreso a donde el usuario quedó.
Feed es la base. Prioriza la escaneabilidad: título, vista previa corta, categoría/etiqueta, distintivo de segmentación (opcional) y estado (No leído/Leído/Requiere reconocimiento). Añade un filtro sencillo para No leídos y una barra de búsqueda.
Detalle del anuncio es donde se ganan los recibos. Muestra el contenido completo, adjuntos/enlaces y un estado de lectura evidente. El “marcar como leído al abrir” es tentador, pero considera aperturas accidentales. Si los reconocimientos son obligatorios, separa “Leer” de “Reconocer” con un texto claro.
Componer debe sentirse como un editor ligero: título, cuerpo, selector de audiencia, programación de publicación y vista previa. Mantén las opciones avanzadas ocultas por defecto.
Admin puede empezar como una sola página: gestionar usuarios/roles, crear grupos y ver rendimiento de anuncios.
Usa tipografía legible, contraste fuerte y contornos de foco visibles. Asegura que todas las acciones funcionen con teclado.
Diseña para lecturas rápidas en móvil: objetivos de toque grandes, botón “Reconocer” fijo cuando sea necesario y estados de carga que no bloqueen el contenido.
Un modelo de datos claro hace que los recibos sean fiables, la segmentación predecible y los informes rápidos. No necesitas decenas de tablas: unas pocas entidades bien elegidas y reglas sobre cómo se relacionan bastan.
Como mínimo, modela estas:
Para Announcement, incluye:
Considera también metadatos útiles más adelante: created_by, updated_by, status (draft/scheduled/published) y timestamps. Esto soporta auditoría sin tablas adicionales.
La segmentación es donde muchas herramientas internas se complican. Elige una estrategia pronto:
Lista explícita de usuarios: almacena el conjunto exacto de user IDs para un anuncio.
Ideal para audiencias pequeñas y precisas. Complicado para orgs grandes.
Filtros por grupo: almacena reglas tipo “Team = Soporte” o “Location = Berlín”.
Útil para patrones recurrentes, pero las audiencias cambian cuando la gente se mueve.
Snapshots (recomendado para recibos): almacena filtros durante la redacción y luego resuélvelos en la publicación a una lista fija de destinatarios.
Esto mantiene estables los informes y recibos: las personas objetivo en el momento de publicar siguen siendo la audiencia, aunque alguien cambie de equipo después.
Los recibos pueden crecer rápido. Hazlos fáciles de consultar:
Esto evita duplicados y acelera pantallas comunes (por ejemplo, “¿Alex leyó esto?” o “¿Cuántas lecturas tiene el Anuncio #42?”).
Los recibos parecen simples (“¿lo leyó?”), pero los detalles determinan si tus informes son fiables. Empieza por definir qué significa “leído” en tu organización y luego impleméntalo de manera consistente.
Elige una señal primaria y mantena la consistencia:
Muchas organizaciones almacenan read y acknowledged: “read” es pasivo; “acknowledged” es una confirmación intencional.
Crea un registro de recibo dedicado por usuario por anuncio. Campos típicos:
user_idannouncement_idread_at (timestamp, nullable)acknowledged_at (timestamp, nullable)Diagnósticos opcionales como device_type, app_version o ip_hash deben añadirse solo si de verdad los necesitas y tienes aprobación de políticas.
Para evitar doble conteo, impón una restricción única en (user_id, announcement_id) y trata las actualizaciones de recibo como upserts. Esto evita inflar los números por aperturas repetidas, refrescos o clicks en notificaciones.
Los anuncios se actualizan a menudo. Decide desde el principio si las ediciones deben reiniciar los recibos:
Un enfoque sencillo es almacenar announcement_version (o content_hash) en el recibo. Si la versión cambia y se marca el cambio como “requiere re-reconocimiento”, puedes borrar acknowledged_at (y opcionalmente read_at) mientras mantienes la pista de auditoría de versiones anteriores.
Bien hecho, los recibos se convierten en una medida fiable sin transformarse en vigilancia o datos inconsistentes y ruidosos.
Una app interna mantenible es menos sobre perseguir herramientas nuevas y más sobre escoger piezas bien documentadas, con comunidad y fácil de hospedar. Apunta a una pila con buena documentación, abundante talento y hosting sencillo.
Una base probada es un framework web mainstream junto a una base de datos relacional:
Las BD relacionales facilitan modelar anuncios, audiencias y recibos con relaciones claras, restricciones e consultas amigables para informes.
Si prefieres moverte rápido con una configuración moderna, Koder.ai suele generar frontends React con backend en Go y PostgreSQL —útil cuando quieres una base mantenible sin montar cada pantalla CRUD y control de permisos desde cero.
Aunque construyas una app renderizada en servidor, define endpoints REST limpios para que la UI e integraciones futuras sean simples:
GET /announcements (lista + filtros)POST /announcements (crear)POST /announcements/{id}/publish (flujo de publicación)POST /announcements/{id}/receipts (marcar lectura)GET /announcements/{id}/receipts (vistas de reporte)Esto mantiene responsabilidades claras y facilita auditoría más adelante.
Tiempo real es deseable, no imprescindible. Si necesitas insignias de “nuevo anuncio” instantáneas, considera:
Empieza con polling; mejora solo si los usuarios notan retrasos.
Evita guardar archivos grandes en la base de datos. Prefiere object storage (por ejemplo compatible con S3) y guarda solo metadatos (nombre de archivo, tamaño, URL, permisos) en la BD. Si los adjuntos son raros y pequeños, puedes comenzar con almacenamiento local y migrar luego.
La autenticación es la puerta de entrada: acertar temprano hace que las funciones posteriores (segmentación, recibos, analítica) hereden el mismo modelo de confianza.
Para la mayoría de entornos, SSO es la opción por defecto porque reduce riesgos de contraseña y coincide con cómo ya inician sesión los empleados.
Elige un enfoque y sé consistente:
HttpOnly, Secure y SameSite=Lax/Strict. Rota el session ID en login y cambios de privilegio.Define tanto un timeout por inactividad como una duración absoluta de sesión para que dispositivos compartidos no queden logueados indefinidamente.
Autenticación prueba identidad; autorización prueba permiso. Aplica comprobaciones de autorización en:
Trata estas comprobaciones como reglas obligatorias en servidor, no sugerencias en UI.
Incluso apps internas necesitan protecciones:
Un buen editor preocupa menos por formato y más por evitar errores. Trata cada anuncio como un mini proceso editorial: propiedad clara, estados previsibles y forma de arreglar problemas sin estropear el historial.
Usa un modelo de estado simple y visible:
Para mantener responsabilidad, registra quién movió entre estados y cuándo (una auditoría fácil de leer).
La programación evita la presión de “enviar ahora” y ayuda a equipos globales.
Haz la UI explícita: muestra la zona horaria actual y advierte si expire_at es anterior a publish_at.
Elige un formato y mantente con él:
Para la mayoría, Markdown básico (títulos, listas, enlaces) es un buen equilibrio.
Si admites adjuntos, fija expectativas:
Si tu proveedor de almacenamiento ofrece escaneo de virus, actívalo; si no, al menos restringe tipos ejecutables y registra subidas para seguimiento.
La entrega es el puente entre “publicamos” y “los empleados realmente lo vieron”. Apunta a unos pocos canales claros, reglas coherentes y preferencias sencillas.
Empieza con una experiencia in-app: una insignia “Nuevo” en el encabezado, un contador de no leídos y un feed que destaque primero los no leídos. Esto mantiene el sistema autocontenido y evita depender solo del correo.
Después añade notificaciones por correo para quienes no viven en la app todo el día. Mantén los emails cortos: título, primera línea y un botón que enlace al detalle del anuncio.
Las push pueden ser opcionales (y posteriores), porque añaden complejidad en varios dispositivos. Si las añades, trátalas como un canal adicional, no como el único.
Da control sin abrumar:
Una regla simple funciona bien: por defecto todos en in-app + correo para categorías de alta importancia; permitir que los usuarios opten por menos (salvo avisos legalmente obligatorios).
Los posts urgentes deberían ser visualmente distintos y pueden fijarse arriba hasta que se lean. Si la política lo exige, añade un botón “Reconocer” separado del recibo normal para poder reportar confirmaciones explícitas.
Añade guardrails: limitar correos masivos, exigir permisos elevados para enviar urgentes y controles admin como “limitar urgentes por semana” y “previsualizar contador de destinatarios antes de enviar”. Esto mantiene el sistema confiable en lugar de ignorado.
Los recibos sirven cuando responden preguntas prácticas: “¿llegó al público correcto?” y “¿a quién hay que recordarle?”. Mantén los informes sencillos, fáciles de entender y limitados a lo que los editores realmente necesitan.
Empieza con una vista por anuncio que muestre tres números:
Si almacenas eventos, calcula esos conteos desde la tabla de receipts en vez de mezclar lógica en la UI. Incluye también una pequeña marca de “última actualización” para que los editores confíen en lo que ven.
Añade filtros que permitan cortes operativos sin convertir la app en una herramienta BI completa:
Cuando apliques filtros, conserva el mismo resumen entregado/leído/no leído para facilitar comparaciones.
Exportar CSV es útil para auditorías y seguimientos, pero debe incluir lo mínimo necesario. Un buen predeterminado:
Evita exportar detalles de dispositivo, IPs o perfiles completos salvo que haya una política clara y aprobación.
Posiciona los recibos como forma de confirmar mensajes críticos (política, seguridad, incidencias), no para rastrear productividad. Considera mostrar a managers estadísticas agregadas por defecto y requerir permiso elevado para drill-down por usuario, con un registro de auditoría de quién accedió.
La privacidad y la fiabilidad determinan si la gente confía en tu app. Los recibos son especialmente sensibles: se pueden percibir como “seguimiento” si recopilas más de lo necesario o los mantienes para siempre.
Empieza con minimización de datos: almacena solo lo necesario para demostrar que hubo un recibo. Para muchos equipos eso es ID de usuario, ID de anuncio, marca de tiempo y la fuente cliente (web/móvil) —no direcciones IP, GPS ni huellas detalladas del dispositivo.
Define opciones de retención desde el inicio:
Documenta esto en una nota de privacidad en lenguaje llano dentro de la app (enlazada desde /settings).
Mantén un registro de auditoría para acciones clave: quién publicó, editó, archivó o restauró un anuncio y cuándo. Esto ayuda a resolver disputas (“¿se cambió esto después de enviarlo?”) y soporta cumplimiento interno.
Prueba los caminos de mayor riesgo:
Usa entornos separados (dev/staging/prod), ejecuta migraciones de BD de forma segura y configura monitorización y copias de seguridad. Rastrea errores y fallos de jobs (notificaciones, escrituras de recibos) para que los problemas afloren rápido.
Si usas un enfoque plataforma, prioriza las características operativas que necesitarás en la práctica —despliegues repetibles, separación de entornos y rollback. (Por ejemplo, Koder.ai ofrece despliegue/hospedaje más snapshots y rollback, lo que puede reducir riesgo mientras iteras en flujos internos.)
Mejoras comunes: anuncios multilenguaje, plantillas reutilizables e integraciones (Slack/Teams, email, sincronización con directorio de RR. HH.).
Un recibo de lectura responde a la pregunta operativa: quién realmente vio (y, posiblemente, reconoció) un mensaje crítico. Reduce las dudas y el trabajo de seguimiento en cosas como cambios de políticas, avisos de seguridad, cierres de oficina y plazos de beneficios; convierte “lo enviamos” en “podemos confirmar que se leyó”.
Buenas métricas para v1 son:
read_at (o acknowledged_at) registrado.Define objetivos distintos según el tipo de anuncio (por ejemplo, urgente/seguridad vs. cultura/noticias).
Un alcance v1 sólido normalmente incluye:
Deja “agradables de tener” (aprobaciones, plantillas, reacciones, analítica avanzada) para más adelante salvo que los necesites ya.
Comienza con roles claros y permisos explícitos:
Elige una definición principal y aplícala de forma consistente:
Muchas organizaciones registran ambos: read_at para lecturas pasivas y para confirmaciones requeridas.
Usa una tabla de receipts dedicada con una fila por usuario y anuncio:
user_id, announcement_idread_at (nullable)acknowledged_at (nullable)Decide de antemano cómo afectan las ediciones a los recibos:
Un patrón práctico es almacenar (o ) en el recibo y borrar solo cuando el editor marca el cambio como “requiere re-reconocimiento”, manteniendo al mismo tiempo un historial de auditoría de lo que cambió y cuándo.
Las opciones de segmentación suelen agruparse en:
El snapshot mantiene estables los recibos e informes: la audiencia es “quién fue objetivo en el momento de la publicación”, no “quién cumple el filtro hoy”.
Usa SSO (SAML/OIDC) si está disponible; reduce el riesgo de contraseñas y se integra con la gestión de identidades existente. Independientemente del método de autenticación:
Mantén los recibos útiles sin convertirlos en vigilancia:
user_id + announcement_id + marcas de tiempo suelen bastarDefine permisos por acción (crear/editar/publicar/archivar/ver recibos/exportar), no solo por nombre de rol.
acknowledged_atAplica una restricción única/índice en (announcement_id, user_id) y realiza escrituras de recibos como upserts para evitar duplicados por refrescos o múltiples dispositivos.
announcement_versioncontent_hashacknowledged_atTrate la autorización como una regla obligatoria del backend, no como una pista en la UI.
Incluye una nota de privacidad en lenguaje llano dentro de la app (por ejemplo, enlazada desde /settings).