Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


Python FastAPI React Vite Supabase Gemini TailwindCSS


An AI-powered emotional analysis chatbot that understands what's really behind your words.
Chat naturally. Get empathetic replies. See your emotional patterns visualized in real time.



✨ What is Behind Your Words?

Behind Your Words is a full-stack emotional wellness app that combines:

  • πŸ€– Gemini AI β€” empathetic, context-aware conversational replies
  • 🧠 HuggingFace NLP β€” real-time sentiment & emotion detection on every message
  • πŸ“Š Live Dashboard β€” pie charts, trend lines, and emotional insights
  • πŸ”’ Privacy-first β€” raw messages are never stored. Only daily aggregated summaries.
  • πŸ“„ PDF Reports β€” download your emotional journey as a beautifully formatted report

🎬 Features at a Glance

Feature Description
πŸ’¬ Smart Chat Gemini-powered empathetic replies with strict emotional focus
🎭 Emotion Detection Detects joy, sadness, anger, fear, love, surprise per message
πŸ“ˆ Sentiment Tracking Positive / Neutral / Negative classification in real time
πŸ—‚οΈ Dashboard Panel Slide-in panel with pie chart + trend line chart
πŸ“… Date Range Filter View emotional history across any date range
πŸ”„ Daily Comparison "You're X% happier than yesterday" motivational messages
πŸ“„ PDF Export Download full emotional report with all historical data
πŸ” Auth Smart login β€” auto-detects new vs existing users
🌐 Guest Mode Chat & see session stats without signing in
πŸ”‘ API Key Rotation Auto-rotates through 13 Gemini keys to maximize uptime

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     FRONTEND (React + Vite)                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ ChatPage β”‚  β”‚ DashboardPanelβ”‚  β”‚    LoginModal         β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚       β”‚               β”‚                      β”‚               β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚           Zustand Store  +  Axios API Service           β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚ HTTP
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    BACKEND (FastAPI)                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ /chat       β”‚  β”‚ /save-daily  β”‚  β”‚ /report (PDF)      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚                β”‚                    β”‚               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ NLP Service β”‚  β”‚        Supabase Service Client        β”‚  β”‚
β”‚  β”‚ + Chatbot   β”‚  β”‚     (bypasses RLS for backend ops)    β”‚  β”‚
β”‚  β”‚   Service   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    EXTERNAL SERVICES                          β”‚
β”‚   Google Gemini API  β”‚  HuggingFace Models  β”‚  Supabase DB   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Quick Start

Prerequisites

1. Clone & Setup

git clone https://github.com/yourusername/behind-your-words.git
cd behind-your-words

2. Backend Setup

cd backend
pip install -r requirements.txt
cp .env.example .env
# Fill in your keys in .env

backend/.env

GEMINI_API_KEY=your_gemini_key_here
GEMINI_API_KEYS_EXTRA=key2,key3,key4   # optional β€” for key rotation
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_anon_key
SUPABASE_SERVICE_KEY=your_service_role_key

3. Frontend Setup

cd frontend
npm install
cp .env.example .env
# Fill in your Supabase keys

frontend/.env

VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key
VITE_API_BASE_URL=http://localhost:8000

4. Supabase Database

Run this in your Supabase SQL Editor:

CREATE TABLE daily_emotions (
  id              uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id         uuid REFERENCES auth.users(id) ON DELETE CASCADE,
  date            date NOT NULL,
  happy_percent   numeric(5,2) DEFAULT 0,
  sad_percent     numeric(5,2) DEFAULT 0,
  neutral_percent numeric(5,2) DEFAULT 0,
  top_emotions    jsonb DEFAULT '[]',
  UNIQUE(user_id, date)
);

ALTER TABLE daily_emotions ENABLE ROW LEVEL SECURITY;

5. Launch πŸš€

# Windows β€” just double-click or run:
start.bat

# Manual:
# Terminal 1
cd backend && python -m uvicorn app.main:app --reload --port 8000

# Terminal 2
cd frontend && npm run dev

Open http://localhost:5173 πŸŽ‰


🧠 How It Works

User types a message
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  FastAPI /chat endpoint               β”‚
β”‚                                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Gemini AI      β”‚  β”‚ NLP Models β”‚  β”‚
β”‚  β”‚  (reply)        β”‚  β”‚ (emotion + β”‚  β”‚
β”‚  β”‚                 β”‚  β”‚ sentiment) β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                    β–Ό                  β”‚
β”‚         { reply, sentiment, emotion } β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
Frontend stores in Zustand (in-memory)
        β”‚
        β–Ό
Dashboard reads from same store β†’ live charts
        β”‚
        β–Ό
On dashboard open β†’ saves to Supabase daily_emotions
        β”‚
        β–Ό
PDF report fetches from Supabase β†’ full history

πŸ“ Project Structure

behind-your-words/
β”œβ”€β”€ 🐍 backend/
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ api/          # chat, auth, analysis routes
β”‚   β”‚   β”œβ”€β”€ services/     # chatbot (Gemini) + nlp (HuggingFace)
β”‚   β”‚   β”œβ”€β”€ schemas/      # Pydantic models
β”‚   β”‚   β”œβ”€β”€ core/         # config (env vars)
β”‚   β”‚   └── db/           # Supabase client
β”‚   β”œβ”€β”€ tests/            # pytest + Hypothesis property tests
β”‚   └── requirements.txt
β”‚
β”œβ”€β”€ βš›οΈ  frontend/
β”‚   └── src/
β”‚       β”œβ”€β”€ components/   # ChatWindow, DashboardPanel, LoginModal, Navbar
β”‚       β”œβ”€β”€ pages/        # ChatPage
β”‚       β”œβ”€β”€ services/     # api.js, supabaseClient.js
β”‚       β”œβ”€β”€ store/        # Zustand chatStore
β”‚       └── utils/        # formatters.js
β”‚
└── πŸš€ start.bat          # One-click launcher (Windows)

πŸ§ͺ Testing

# Backend β€” property-based tests with Hypothesis
cd backend
pytest tests/ -v

# Frontend β€” Vitest + Testing Library
cd frontend
npm test

Test coverage includes:

  • Property 1: NLP always returns valid classifications
  • Property 2: Daily percentages are bounded [0, 100]
  • Property 3: Upsert idempotency (one row per user per day)
  • Property 4 & 5: Comparison message correctness
  • Property 6: PDF contains required fields
  • Property 7: Chat response schema completeness

πŸ” Privacy & Security

  • βœ… Raw chat messages are never stored in any database
  • βœ… Only daily aggregated summaries (percentages + emotion counts) are saved
  • βœ… Row Level Security (RLS) on Supabase β€” users can only access their own data
  • βœ… JWT authentication on all protected endpoints
  • βœ… All secrets loaded from environment variables β€” nothing hardcoded

πŸ› οΈ Tech Stack

Layer Technology
Frontend React 18, Vite, Tailwind CSS, Recharts, Zustand, Axios
Backend FastAPI, Python 3.11, Uvicorn
AI / NLP Google Gemini 2.5 Flash, HuggingFace Transformers
Database Supabase (PostgreSQL + Auth)
PDF ReportLab
Testing pytest, Hypothesis, Vitest, fast-check

πŸ“„ License

MIT Β© 2026 Behind Your Words


"Every word you share carries a feeling. I'm here to understand it."