# ๐Ÿš€ BREATHE โ€” Future Enhancements A living document of planned and possible improvements to the BREATHE platform. --- ## 1. PostgreSQL โ€” Persistent Production Database SQLite is fine for development but it resets or corrupts when the server restarts on many cloud platforms. PostgreSQL is a proper production-grade database where your data persists independently of the server. ### Why switch? - Data survives server restarts, crashes, and re-deployments - Multiple workers can read/write simultaneously (SQLite locks) - You can inspect, back up, and query data directly from any Postgres client - Required by most cloud platforms (Railway, Render, Supabase, AWS RDS, etc.) ### Step-by-step setup (local) **1. Install PostgreSQL** ```bash # macOS (Homebrew) brew install postgresql@16 brew services start postgresql@16 # Ubuntu / Debian sudo apt install postgresql postgresql-contrib sudo systemctl start postgresql ``` **2. Create the database and user** ```bash psql postgres ``` ```sql CREATE USER breathe_user WITH PASSWORD 'your_strong_password'; CREATE DATABASE breathe_db OWNER breathe_user; GRANT ALL PRIVILEGES ON DATABASE breathe_db TO breathe_user; \q ``` **3. Install the Python driver** ```bash source venv/bin/activate pip install psycopg2-binary ``` **4. Update `.env`** ``` DATABASE_URL=postgresql://breathe_user:your_strong_password@localhost:5432/breathe_db ``` **5. Run the app โ€” tables are created automatically** ```bash python app.py ``` Flask's `db.create_all()` will create all tables in Postgres on first run. **6. Verify** ```bash psql -U breathe_user -d breathe_db -c "\dt" # Should list: users, assessments, gratitude_entries ``` ### Step-by-step setup (cloud โ€” Supabase, free tier) 1. Go to [supabase.com](https://supabase.com) โ†’ New project 2. In **Settings โ†’ Database** copy the **Connection string** (URI format) 3. Paste it into `.env` as `DATABASE_URL` 4. The app connects and creates tables on next start โ€” no other changes needed ### Step-by-step setup (cloud โ€” Railway) 1. Go to [railway.app](https://railway.app) โ†’ New project โ†’ Add PostgreSQL 2. Click the Postgres service โ†’ **Connect** tab โ†’ copy the `DATABASE_URL` 3. Add it as an environment variable in your BREATHE service on Railway 4. Re-deploy โ€” done ### Keeping data safe with backups ```bash # Dump the entire database pg_dump -U breathe_user breathe_db > backup_$(date +%Y%m%d).sql # Restore from a dump psql -U breathe_user breathe_db < backup_20260502.sql ``` --- ## 2. Sign Up / Log In with Google (OAuth 2.0) Let users authenticate with their Google account โ€” no password to remember. ### How it works 1. User clicks "Continue with Google" 2. Browser redirects to Google's OAuth consent screen 3. Google returns an authorization code to your callback URL 4. Flask exchanges the code for an access token and reads the user's profile (name, email, avatar) 5. Your app creates or logs in the user automatically ### Backend โ€” Flask-Dance (simplest approach) **Install** ```bash pip install flask-dance[sqla] ``` **Register a Google OAuth app** 1. Go to [console.cloud.google.com](https://console.cloud.google.com) 2. Create a new project โ†’ **APIs & Services โ†’ Credentials** 3. Click **Create Credentials โ†’ OAuth client ID** 4. Application type: **Web application** 5. Authorised redirect URI: `http://localhost:5000/login/google/authorized` 6. Copy the **Client ID** and **Client Secret** into `.env`: ``` GOOGLE_CLIENT_ID=your_client_id GOOGLE_CLIENT_SECRET=your_client_secret ``` **Add to `backend/__init__.py`** ```python from flask_dance.contrib.google import make_google_blueprint, google google_bp = make_google_blueprint( client_id=os.environ.get("GOOGLE_CLIENT_ID"), client_secret=os.environ.get("GOOGLE_CLIENT_SECRET"), scope=["openid", "email", "profile"], redirect_url="/api/auth/google/callback", ) app.register_blueprint(google_bp, url_prefix="/login") ``` **Add a callback route in `auth.py`** ```python from flask_dance.contrib.google import google @auth_bp.route("/google/callback") def google_callback(): if not google.authorized: return jsonify({"error": "Not authorized"}), 401 resp = google.get("/oauth2/v2/userinfo") info = resp.json() user = User.query.filter_by(email=info["email"]).first() if not user: user = User(username=info["name"], email=info["email"]) user.avatar = info.get("picture") db.session.add(user) db.session.commit() session["user_id"] = user.id return redirect("http://localhost:5173/app/breathe") ``` **Frontend โ€” add a Google button to `AuthPage.jsx`** ```jsx Continue with Google ``` --- ## 3. Improved UI & UX ### Ideas to implement | Area | Enhancement | |------|-------------| | Onboarding | First-time walkthrough tooltip tour (using `driver.js` or `intro.js`) | | Themes | Light mode toggle + system preference detection | | Animations | Framer Motion page transitions and micro-interactions | | Mobile | Full PWA support โ€” installable on phone home screen | | Accessibility | ARIA labels, keyboard navigation, high-contrast mode | | Charts | Hover annotations, zoom on timeline, weekly/monthly toggle | | Notifications | Browser push notifications for daily assessment reminders | | Streaks | Gamification โ€” show journaling streak counter on dashboard | | Data export | Download your assessment + journal history as CSV or PDF | ### Quick win โ€” dark/light theme toggle ```js // in index.css: add a [data-theme="light"] block overriding --bg, --surface, etc. // in a ThemeToggle component: document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light') localStorage.setItem('theme', isDark ? 'dark' : 'light') ``` --- ## 4. Calm Background Music Play ambient/calming audio tracks inside the app to accompany breathing and journaling sessions. ### Option A โ€” Self-hosted audio files (simplest) 1. Download royalty-free tracks from [freemusicarchive.org](https://freemusicarchive.org) or [pixabay.com/music](https://pixabay.com/music/) 2. Place `.mp3` files in `frontend/public/audio/` 3. Build a `MusicPlayer` component: ```jsx // frontend/src/components/MusicPlayer.jsx import { useState, useRef } from 'react' const TRACKS = [ { title: 'Forest Rain', src: '/audio/forest-rain.mp3' }, { title: 'Ocean Waves', src: '/audio/ocean-waves.mp3' }, { title: 'Tibetan Bowls', src: '/audio/tibetan-bowls.mp3' }, ] export default function MusicPlayer() { const [playing, setPlaying] = useState(false) const [track, setTrack] = useState(0) const audioRef = useRef(null) function togglePlay() { if (playing) { audioRef.current.pause() } else { audioRef.current.play() } setPlaying(!playing) } function changeTrack(i) { setTrack(i) setPlaying(false) setTimeout(() => { audioRef.current.load(); audioRef.current.play(); setPlaying(true) }, 50) } return (
) } ``` 4. Add `` to `BreathePage.jsx` or the guided exercise modal ### Option B โ€” Streaming via YouTube IFrame API (no file hosting needed) ```jsx // Embed a YouTube ambient playlist