~/progetti/dit/README.md

COOKIES_ADVICE PRIVACY_POLICY.

~/progetti/dit/README.md

Dit

{ fecha: “2026-05-14”, estado: “live”, módulos_stack: 11 }

Señales de presencia mínimas entre personas — sin chat, sin mensajes, solo presencia

Dit es una aplicación móvil (iOS y Android) que permite intercambiar señales de presencia mínimas entre personas. Sin texto, sin imágenes, sin mensajes de voz — solo dos primitivas inspiradas en el código Morse: un Dit (·) significa "estoy aquí", un Dah (—) significa "recibido". La aplicación es para cualquiera que quiera mantenerse en contacto con personas importantes sin la presión de una conversación.

## El concepto

Dit se basa en una observación simple: a veces quieres mostrarle a alguien que estás pensando en él — sin tener que formular un mensaje. Inspirado en el viejo hábito de llamar a alguien y colgar antes de que conteste — una señal gratuita que significaba "pienso en ti" o "llámame".

·Dit (·) — una señal corta a otra persona, con una vida útil configurable de 1 hora, 6 horas o 24 horas
·Dah (—) — una confirmación como respuesta, significa "recibido" o "también estoy aquí"
·Sin Dit simultáneamente activo por par de usuarios — una señal a la vez, no más
·Tonos de notificación codificados en código Morse: ·· (letra I = yo) para Dit, ··— (letra U = tú) para Dah

## Características principales

La aplicación incluye las siguientes áreas funcionales:

·Autenticación: Email + Contraseña, Email OTP (sin contraseña), Google OAuth, Facebook OAuth
·Sistema de contactos: Búsqueda por nombre de usuario, guardado unilateral y silencioso, apodos privados, resolución de nombre de visualización (apodo → nombre → nombre de usuario)
·Entrega en tiempo real: Las señales se entregan inmediatamente vía WebSocket cuando el destinatario está en línea
·Notificaciones push: tonos Morse personalizados, botones de acción directamente en la notificación (enviar Dah sin abrir la app), recordatorios programados antes de la expiración
·Multi-dispositivo: Notificaciones en todos los dispositivos, sincronización de descarte entre dispositivos, eliminación de token al cerrar sesión
·Privacidad: Visibilidad de perfil (Todos/Contactos/Ninguno), bloqueo de usuario con eliminación de datos inmediata e irreversible, respuestas 404 genéricas sin indicación de bloqueo
·Línea de tiempo de ping: Representación visual de diagrama de secuencia de todas las señales entre dos usuarios, renderizada con Skia en GPU

## Arquitectura

Cuatro servicios independientes que se comunican exclusivamente a través de infraestructura compartida — ningún servicio llama a otro directamente:

·dit-api (NestJS + Fastify): API REST para autenticación, usuarios, contactos, creación de ping, gestión de tokens push
·dit-ping (Go): Motor WebSocket para entrega en tiempo real, procesamiento Dah/Ignore, monitoreo TTL, gestión de presencia
·dit-notifications-worker (Node.js + BullMQ): Entrega de notificaciones push vía FCM, recordatorios programados, limpieza de tokens
·dit-mobile (React Native + Expo): Cliente multiplataforma para iOS y Android

## Stack tecnológico

Las elecciones técnicas reflejan los requisitos del producto:

·Móvil: React Native 0.83+, Expo SDK 55 (Bare Workflow), expo-router, React Native Skia, Reanimated 4, Unistyles v3, Zustand, Notifee
·Backend API: NestJS 11, Fastify, BetterAuth, Prisma, ioredis, BullMQ
·Motor en tiempo real: Go 1.23+, Fiber v3, nhooyr.io/websocket, go-redis v9, pgx v5
·Notification worker: Node.js, BullMQ, Firebase Admin SDK, Zod
·Base de datos: PostgreSQL 16 + TimescaleDB 2 (Hypertable para Pings con particionamiento de series temporales)
·Caché y cola: Redis 7 (presencia, Pub/Sub, cola BullMQ, estado TTL)
·Auth: BetterAuth (auto-hospedado), Sistema de dos tokens: Cookie de sesión (REST) + JWT HS256 de corta duración (WebSocket)
·Email: Brevo SMTP para emails transaccionales
·Push: Firebase Cloud Messaging para Android e iOS (proxy FCM-to-APNs)

## Sistema de diseño

Un sistema visual coherente recorre toda la aplicación:

·Color primario: verde tóxico (#2EF080 Dark, #00B84E Light)
·Sistema de dos fuentes: DM Mono para momentos de identidad (marcas de tiempo, códigos, señales), System UI para texto de cuerpo
·Animaciones: exclusivamente Spring-Physics (Reanimated 4), cuatro presets configurados
·DitPressable: único componente interactivo, combina Gesture Handler + Reanimated + Haptics
·PingTimeline: Canvas Skia con diseño Dot-and-Thread, halos pulsantes, puntos tocables con tooltips
·DitGlow: Efecto de gradiente radial Skia bajo la barra de acción con animación de pulso
·Floating tab bar: en forma de píldora con fondo borroso e iconos animados con spring

## Decisiones de diseño importantes

Decisiones que dan forma al producto y la arquitectura:

·Dos backends separados sin contacto de runtime directo: dit-api crea pings vía REST, dit-ping procesa actualizaciones de estado vía WebSocket — comunicación solo vía Redis Pub/Sub
·JWT validado independientemente: el servicio Go valida tokens con el mismo secreto, sin llamar a la API NestJS — Zero Runtime Coupling
·ProfileFormatterService como único aplicador de visibilidad: cada respuesta API con datos de usuario pasa por este servicio
·El bloqueo devuelve 404 genérico: el usuario bloqueado no puede distinguir entre "bloqueado" y "cuenta eliminada"
·FCM para ambas plataformas: Firebase Admin SDK enruta automáticamente — FCM directo para Android, proxy FCM-to-APNs para iOS
·TimescaleDB para Pings: particionamiento de series temporales permite consultas eficientes basadas en tiempo y limpieza automática de datos

## Lo que estoy aprendiendo

Perspectivas del desarrollo de un sistema en tiempo real con cuatro servicios independientes:

·Definir límites claros de propiedad entre servicios desde el primer día — quién escribe qué en qué tabla
·Redis Pub/Sub como bus de comunicación entre servicios heterogéneos (TypeScript y Go) sin contacto directo
·Privacidad como restricción arquitectónica: errores genéricos, visibilidad centralizada, bloqueo destructivo
·Preferir animaciones Spring sobre withTiming — la diferencia en calidad percibida es significativa
·Sonidos de notificación como elemento de marca: los tonos en código Morse hacen que la aplicación sea instantáneamente reconocible sin marcadores visuales

Dit está disponible en Google Play Store. Un producto europeo con sede en Italia. Say nothing. Mean everything.

// stack
[react-native”, expo”, nestjs”, go”, postgres”, redis”, timescaledb”, websocket”, mobile”, real-time”, presence”, ]