~/progetti/dit/README.md

COOKIES_ADVICE PRIVACY_POLICY.

~/progetti/dit/README.md

Dit

{ Datum: “2026-05-14”, Status: “live”, Stack_Module: 11 }

Minimale Präsenzsignale zwischen Menschen — kein Chat, keine Nachrichten, nur Anwesenheit

Dit ist eine mobile App (iOS und Android), die es ermöglicht, minimale Präsenzsignale zwischen Menschen auszutauschen. Kein Text, keine Bilder, keine Sprachnachrichten — nur zwei Primitiven inspiriert vom Morsecode: ein Dit (·) bedeutet "ich bin da", ein Dah (—) bedeutet "empfangen". Die App richtet sich an alle, die den Kontakt zu wichtigen Menschen halten wollen, ohne den Druck einer Konversation.

## Das Konzept

Dit basiert auf einer einfachen Beobachtung: Manchmal möchte man jemandem zeigen, dass man an ihn denkt — ohne eine Nachricht formulieren zu müssen. Inspiriert von der alten Gewohnheit, jemanden anzurufen und aufzulegen bevor er abnimmt — ein kostenloses Signal, das "denke an dich" oder "ruf mich zurück" bedeutete.

·Dit (·) — ein kurzes Signal an eine andere Person, mit einer konfigurierbaren Lebensdauer von 1 Stunde, 6 Stunden oder 24 Stunden
·Dah (—) — eine Bestätigung als Antwort, bedeutet "empfangen" oder "bin auch da"
·Kein gleichzeitig aktives Dit pro Nutzerpaar — ein Signal auf einmal, nicht mehr
·Benachrichtigungstöne kodiert in Morsecode: ·· (Buchstabe I = ich) für Dit, ··— (Buchstabe U = du) für Dah

## Kernfunktionen

Die App umfasst folgende Funktionsbereiche:

·Authentifizierung: E-Mail + Passwort, E-Mail-OTP (passwortlos), Google OAuth, Facebook OAuth
·Kontaktsystem: Suche per Benutzername, einseitiges und stilles Speichern, private Spitznamen, Display-Name-Auflösung (Spitzname → Name → Benutzername)
·Echtzeit-Zustellung: Signale werden sofort über WebSocket zugestellt, wenn der Empfänger online ist
·Push-Benachrichtigungen: benutzerdefinierte Morsetöne, Aktionsbuttons direkt in der Benachrichtigung (Dah senden ohne App zu öffnen), geplante Erinnerungen vor Ablauf
·Multi-Device: Benachrichtigungen auf allen Geräten, geräteübergreifendes Dismiss-Sync, Token-Löschung bei Logout
·Datenschutz: Profilsichtbarkeit (Alle/Kontakte/Niemand), Benutzerblockierung mit sofortiger und irreversibler Datenlöschung, generische 404-Antworten ohne Hinweis auf Blockierung
·Ping-Timeline: visuelle Sequenzdiagramm-Darstellung aller Signale zwischen zwei Nutzern, gerendert mit Skia auf der GPU

## Architektur

Vier unabhängige Services, die ausschließlich über gemeinsame Infrastruktur kommunizieren — kein Service ruft einen anderen direkt auf:

·dit-api (NestJS + Fastify): REST-API für Auth, Benutzer, Kontakte, Ping-Erstellung, Push-Token-Verwaltung
·dit-ping (Go): WebSocket-Engine für Echtzeit-Zustellung, Dah/Ignore-Verarbeitung, TTL-Überwachung, Präsenz-Management
·dit-notifications-worker (Node.js + BullMQ): Push-Benachrichtigungszustellung über FCM, geplante Erinnerungen, Token-Bereinigung
·dit-mobile (React Native + Expo): Cross-Platform-Client für iOS und Android

## Tech-Stack

Die technischen Entscheidungen spiegeln die Produktanforderungen wider:

·Mobile: 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
·Echtzeit-Engine: Go 1.23+, Fiber v3, nhooyr.io/websocket, go-redis v9, pgx v5
·Notification Worker: Node.js, BullMQ, Firebase Admin SDK, Zod
·Datenbank: PostgreSQL 16 + TimescaleDB 2 (Hypertable für Pings mit Zeitreihen-Partitionierung)
·Cache und Queue: Redis 7 (Präsenz, Pub/Sub, BullMQ-Queue, TTL-State)
·Auth: BetterAuth (self-hosted), Zwei-Token-System: Session-Cookie (REST) + kurzlebiges HS256-JWT (WebSocket)
·E-Mail: Brevo SMTP für transaktionale E-Mails
·Push: Firebase Cloud Messaging für Android und iOS (FCM-zu-APNs-Proxy)

## Design-System

Ein kohärentes visuelles System durchzieht die gesamte App:

·Primärfarbe: toxisches Grün (#2EF080 Dark, #00B84E Light)
·Zwei-Schrift-System: DM Mono für Identitätsmomente (Timestamps, Codes, Signale), System UI für Fließtext
·Animationen: ausschließlich Spring-Physics (Reanimated 4), vier konfigurierte Presets
·DitPressable: einzige interaktive Komponente, kombiniert Gesture Handler + Reanimated + Haptics
·PingTimeline: Skia-Canvas mit Dot-and-Thread-Design, pulsierende Halos, tappbare Dots mit Tooltips
·DitGlow: Skia-Radial-Gradient-Effekt unter der Action-Bar mit Puls-Animation
·Floating Tab Bar: pillenförmig mit Blur-Hintergrund und Spring-animierten Icons

## Wichtige Design-Entscheidungen

Entscheidungen, die das Produkt und die Architektur prägen:

·Zwei getrennte Backends ohne direkten Runtime-Kontakt: dit-api erstellt Pings via REST, dit-ping verarbeitet Status-Updates via WebSocket — Kommunikation nur über Redis Pub/Sub
·JWT unabhängig validiert: Go-Service validiert Tokens mit demselben Secret, ohne die NestJS-API aufzurufen — Zero Runtime Coupling
·ProfileFormatterService als einziger Sichtbarkeits-Enforcer: jede API-Antwort mit Benutzerdaten durchläuft diesen Service
·Blockierung gibt generische 404 zurück: der blockierte Benutzer kann nicht unterscheiden zwischen "blockiert" und "Konto gelöscht"
·FCM für beide Plattformen: Firebase Admin SDK routet automatisch — FCM direkt für Android, FCM-zu-APNs-Proxy für iOS
·TimescaleDB für Pings: Zeitreihen-Partitionierung ermöglicht effiziente zeitbasierte Abfragen und automatische Datenbereinigung

## Was ich lerne

Erkenntnisse aus der Entwicklung eines Echtzeit-Systems mit vier unabhängigen Services:

·Klare Ownership-Grenzen zwischen Services vom ersten Tag an definieren — wer schreibt was in welche Tabelle
·Redis Pub/Sub als Kommunikationsbus zwischen heterogenen Services (TypeScript und Go) ohne direkten Kontakt
·Privacy als architektonische Constraint: generische Fehler, zentralisierte Sichtbarkeit, destruktive Blockierung
·Spring-Animationen über withTiming bevorzugen — der Unterschied in der wahrgenommenen Qualität ist erheblich
·Notification-Sounds als Branding-Element: Morsecode-Töne machen die App sofort erkennbar ohne visuelle Marker

Dit ist live im Google Play Store. Ein europäisches Produkt mit Sitz in Italien. Say nothing. Mean everything.

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