soulwise_persons
Entradas del álbum. Índices en userId, status, deletedAt. Primero borrado lógico; borrado físico de los datos personales a los 30 días.
Para ingenieros, PMs, periodistas y exploradores de alianzas. El pipeline completo, cuatro colecciones de MongoDB, eventos EDA, el rigor del modelo en V, objetivos de rendimiento, seguridad y accesibilidad: todo en una sola página.
Cada paso tiene un servicio, un contrato y un evento.
Una acción del usuario —«genera el capítulo de hoy para Hermana»— o un cron programado, como el resumen del domingo a las 9 a. m., o la actualización del clima cada 6 horas.
El trabajo llega a una cola de BullMQ llamada soulwise-chapter-generation, con un tiempo de espera máximo de 28 segundos. Los trabajos que se prolongan se cancelan y se le informan al usuario como «inténtalo de nuevo».
El ChapterGenerationService ensambla el prompt de cuatro factores —contexto de la persona, astrología, señal, ritmo— en una sola entrada. Ningún dato personal en bruto del usuario entra al prompt de forma literal; todo se depura primero.
Se invoca a un proveedor de IA mediante el token simbólico AI_GENERATION_ADAPTER, y el proveedor es intercambiable. Antes de continuar, se verifica la longitud, la forma y la seguridad de la respuesta.
Suceden cuatro cosas: un clasificador de crisis detecta lenguaje de crisis; un extractor de chips de aspecto saca de uno a tres chips astrológicos; un filtro antiafirmaciones elimina las formulaciones prohibidas; y el cuerpo se cifra con AES-256 usando una clave gestionada por la plataforma.
El artefacto se escribe en la colección de MongoDB correspondiente —capítulos, entradas del diario, resonancias— con índices userId y personId para una búsqueda rápida. Primero se borra de forma lógica; el borrado definitivo de la información personal se realiza a los 30 días.
Un evento de EventEmitter2 —CHAPTER_COMPLETED, JOURNAL_CREATED— se dispara tras confirmarse el commit en la base de datos. El módulo de notificaciones lo recoge, crea un elemento en la bandeja de entrada y, opcionalmente, envía una notificación push (limitada a una al día y respetando las horas de silencio).
El frontend obtiene el artefacto mediante una llamada autenticada a la API. El Hub se vuelve a renderizar con el nuevo contenido. Si el usuario estaba sin conexión, la caché muestra la vista de ayer y el nuevo artefacto aparece al reconectarse.
Indexadas para las consultas que responde cada una.
Entradas del álbum. Índices en userId, status, deletedAt. Primero borrado lógico; borrado físico de los datos personales a los 30 días.
Capítulos escritos por la IA, cuerpo cifrado. Índices en personId, userId, generatedAt. Las fichas de aspectos se almacenan en un array independiente para filtrar con rapidez.
Reflexiones escritas por el usuario, cuerpo cifrado. Índices en userId, personId, createdAt. Cuerpo con índice de texto para la búsqueda. Marca por entrada «privado: no compartir con Luminara».
Puntuaciones de cuatro dimensiones por vínculo. Índice único en personId. Se recalcula mediante una llamada al servicio tras escribir un capítulo o una entrada del diario.
Regla estricta: los eventos se disparan solo después del commit en la base de datos. Las dependencias entre módulos se gestionan mediante tokens de inyección Symbol, nunca con forwardRef. Sin imports directos de servicio a servicio entre módulos de funcionalidad.
SoulwiseEvents.CHAPTER_COMPLETED — SoulwiseEvents.CHAPTER_COMPLETED — se dispara después de cifrar y persistir un capítulo. Notifications-v2 escucha; crea el elemento en la bandeja de entrada; opcionalmente envía un push.SoulwiseEvents.JOURNAL_CREATED — SoulwiseEvents.JOURNAL_CREATED — se dispara después de cifrar y persistir una entrada del diario. El servicio de resonancia escucha; activa el recálculo.SoulwiseEvents.PERSON_BIRTH_UPDATED — SoulwiseEvents.PERSON_BIRTH_UPDATED — se dispara después de que cambian los datos de nacimiento de una persona. La caché de sinastría se invalida.SoulwiseEvents.PUSH_REQUESTED — SoulwiseEvents.PUSH_REQUESTED — según el contrato de notifications-v2; respeta el presupuesto de push y las horas de silencio.119 requisitos trazables, cero brechas. Cada requisito se vincula hacia adelante con un caso de prueba (UTP, ITP, STP, E2E) y hacia atrás con una historia de usuario. 20 historias de usuario. 15 requisitos funcionales. 12 categorías no funcionales. 8 puertas de aceptación globales.
Generación de capítulos en 30 segundos o menos para el 95% de las solicitudes, medida frente a la distribución de duración de los trabajos de BullMQ. Latencia de la API p99 en GET de 500 ms o menos con 1,000 usuarios concurrentes, medida mediante una prueba de carga con k6. TTI del frontend de 3 segundos o menos en 4G simulado, medido con Lighthouse CI.
Cifrado AES-256 en reposo con claves gestionadas por la plataforma para los cuerpos de diario y capítulo. TLS 1.2+ en tránsito; redirección de HTTP→HTTPS. Tokens de acceso JWT con vida útil de 1 horas, tokens de actualización con vida útil de 30 días, con rotación al refrescar. Eliminación lógica con una ventana de 30 días antes de la eliminación definitiva de los datos personales.
prefers-reduced-motion se respeta de forma global: las animaciones de GSAP se convierten en fundidos solo de opacidad. Etiquetas de VoiceOver y TalkBack en cada elemento interactivo. Verificado manualmente en iOS y Android antes de cada lanzamiento.
Porque la especificación upstream reconstruye la función, y reconstruirla dentro de un módulo existente rompería la experiencia v1 o forzaría un fork-then-merge más adelante. Un módulo nuevo mantiene v1 intacto, deja que v2 demuestre su valía y migra de forma limpia cuando esté listo.
El backend actual de My Zodiac AI está en MongoDB; cambiar implicaría una decisión de infraestructura ajena a esta función. El modelo de documentos también encaja bien con capítulos y entradas de diario: anidados, de longitud variable, cifrados como blob.
BullMQ corre sobre Redis, que ya está en el stack para sesión y límite de tasa. Sin infraestructura nueva. Los reintentos, los timeouts y la observabilidad integrados cubren las necesidades de generación de capítulos sin tuberías a medida.
En el repositorio interno. Los números y contratos de esta página parafrasean los artefactos del Modelo en V upstream. Las entradas del blog de ingeniería de cara al público en el clúster de blogs de My Zodiac AI (con la etiqueta 'cosmic-story-v2') profundizan en partes concretas de la construcción.
Mientras Soulwise abre sus olas, nuestra app insignia de astrología ya está en tus manos.
El contenido astrológico es para la reflexión y el entretenimiento. Las funciones de Cosmic Story v2 que se describen aquí están en desarrollo; su disponibilidad puede cambiar sin previo aviso.