Back to projects

Candor

An AI-coached anonymous-feedback platform

2024 – 2026Solo project — design, development & deployment
Candor preview

Overview 

Candor lets anyone collect anonymous feedback through a personal link — but instead of stopping at "you got a message," it uses an AI coach to turn that feedback into a structured, trackable growth plan. It ships with a credit economy, real-time updates, AI moderation, and a full admin console.

The problem 

Most anonymous-message apps dump feedback on you and stop there — no moderation, no structure, and no way to actually act on what you hear. Honest feedback is valuable, but raw and unorganized it rarely turns into real change.

The solution 

Candor treats feedback as the start of a loop, not the end. Incoming messages are screened by Gemini for abuse, then an AI coach clusters your inbox into themes and drafts a concrete growth plan that flows through To Do → In Progress → Completed — every task mapped back to the exact feedback that inspired it. An idempotent credit ledger and per-user AI quotas keep the AI usage sustainable, and a real-time inbox streams new messages the moment they arrive.

Architecture 

A Next.js App Router app where API routes stream a real-time inbox over Server-Sent Events (backed by MongoDB change streams) and call Google Gemini for AI moderation and coaching, with Upstash Redis enforcing per-user AI quotas and rate limits.

Next.js SPA

App Router · shadcn/ui

API Routes + SSE

NextAuth · Zod · rate limiting

MongoDB Atlas

Mongoose · change streams

Redis + Gemini

AI quotas · moderation & coach

Key features 

  • Anonymous messaging through a shareable personal link (/user/{username}), with an accept-messages toggle to pause your inbox
  • Real-time inbox streamed via Server-Sent Events backed by MongoDB change streams
  • Inbox analytics — total volume, a 7-day trend, and status breakdowns from a MongoDB aggregation pipeline
  • AI safety moderation (Gemini) that flags abusive content before it reaches you, failing open and backstopped by an admin review queue
  • AI Feedback Coach that clusters messages into themes and drafts a trackable growth board (To Do → In Progress → Completed), each task mapped to the feedback that inspired it
  • Progress check-ins against plan tasks, plus a Gemini-powered composer that streams message suggestions to senders
  • Idempotent, append-only credit ledger with per-user daily AI quotas, redeemable credit bundles, and graceful degradation
  • NextAuth (email + password and Google OAuth) with email verification and password reset via one-time codes, plus one-click guest login
  • Admin console — user management, moderation queue, roadmap editor, app settings, platform stats, and a full audit log
  • Pluggable KV store — Upstash Redis for shared rate limiting, caching and quotas, with an in-memory fallback for single-instance dev
  • Dark / light / system theme, and production-grade SEO — Metadata API, sitemap, robots, JSON-LD, and an auto-generated Open Graph image
  • Server-side rate limiting on messaging, sign-up and OTP endpoints, with Zod validation shared across client forms and API routes

Tech stack 

Frontend

Next.js 14 (App Router)React 18TypeScriptTailwind CSSshadcn/ui

Backend

Next.js API RoutesMongoDB + MongooseUpstash RedisZod

AI

Google Gemini (gemini-2.5-flash)Vercel AI SDK

Auth & Email

NextAuthResendReact Email

Testing & CI

VitestPlaywrightGitHub Actions

My role & impact 

  • Designed feedback as a loop rather than a dead end — an AI coach turns a raw inbox into a themed, trackable growth board, with every task traceable back to the message that prompted it
  • Built the real-time inbox on Server-Sent Events over MongoDB change streams, so new messages stream in live without polling
  • Made the credit ledger idempotent and append-only with a unique index on userId + reason + refId, so retries and races can never double-award or double-spend
  • Treated AI as a metered resource — per-user daily quotas granted atomically, moderation that fails open for availability, and structured Gemini output (generateObject) so coach and moderation results are typed
  • Hardened one-time codes end to end — generated with a CSPRNG, bcrypt-hashed at rest, compared in constant time, single-use, and rate-limited even on the consuming request
  • Abstracted scale infra behind a pluggable KV store (Upstash Redis with an in-memory fallback) and validated every environment variable at startup, so the app degrades gracefully and misconfiguration fails fast