Unsaid is a discussion platform where verified Northeastern students post under anonymous personas, giving them privacy from peers without losing community trust. The product is live at unsaidhub.xyz with a full backend, real-time notifications, and ranked feeds in production.
Privacy-preserving data model
The core design decouples identity verification from posting identity. Northeastern email verification gates access, but every post, comment, and like attaches to a user-owned persona, never directly to the real user identity. Notifications route by user_id internally while API responses render only the actor's persona, preserving moderation, routing, and self-action suppression without exposing verified emails.
Real-time notification system
I built notification delivery over FastAPI WebSockets with JWT-over-query-string authentication, application-defined close codes for actionable client recovery, and a per-user multi-tab connection manager. HTTP handlers persist data, schedule pushes through BackgroundTasks, and return immediately, keeping real-time delivery off the request path.
Performance and ranking
I built newest- and hot-ranked feeds from likes, comments, and post age, then precomputed ranked results into Redis with write-event-driven invalidation. This removed repeated sort work from the hot path and reduced feed read p50 latency by 30%.
Deployment
The platform runs with a React and TypeScript frontend, a containerized FastAPI backend on Fly.io, and PostgreSQL on Supabase. I also configured production CORS, JWT-based auth, automated Alembic migrations, environment-scoped secrets, and custom-domain setup.
Engineering takeaway
The hardest part was preserving anonymity end-to-end across a social graph while still routing notifications to the right user. Privacy had to be a structural property of the data model, API responses, and runtime behavior; real-time push likewise needed decoupling from HTTP writes instead of being optimized after the fact.