Feature: Mood Journal & Insights Dashboard + Adaptive Playlists (Weekly Recap)
#15 opened on Oct 12, 2025
Repository metrics
- Stars
- (80 stars)
- PR merge metrics
- (PR metrics pending)
Description
Summary
Add a first-class Mood Journal with a user-facing Insights Dashboard that visualizes mood trends over time (by day/time/activity/input-type) and generates adaptive playlists (e.g., Focus / Energize / Unwind) based on recent mood patterns. Include a Weekly Recap email/notification with top moods, variability score, and refreshed playlists.
Motivation
- You already log moods for recommendations; surfacing history + insights increases engagement and trust.
- Adaptive playlists turn passive detection into habit-forming routines (e.g., morning focus mix).
- A weekly recap drives re-activation without needing heavy backend horsepower.
Goals
- Mood Journal UI: timeline & calendar with entries from text/speech/facial inputs, editable notes & tags.
- Insights Dashboard: charts for mood distribution, volatility (std dev), time-of-day & weekday patterns, input-type accuracy mix, and listening correlation.
- Adaptive Playlists: generate & refresh 3–5 mode-based playlists (Focus/Energize/Unwind/Confidence/Calm) using the last N days + current mood.
- Weekly Recap: optional email/notification summarizing trends + one-tap “Play This Week’s Mix”.
- Privacy: local redact option for notes; easy delete/export of journal.
Non-Goals
- Wearables/biometrics integrations (future).
- Fully on-device inference (future; current models remain server-side).
Data Model (MongoDB; additive)
// existing user/mood collections remain; add:
MoodEntry {
_id, userId,
detectedMood: 'happy'|'sad'|'angry'|'fear'|'surprise'|'neutral'|string,
confidence: number, // 0..1
inputType: 'text'|'speech'|'facial',
createdAt: Date, tz?: string,
note?: string, tags?: string[], // user-entered
trackIdPlayedAfter?: string // optional link to Spotify track
}
PlaylistProfile { // adaptive playlist definition per user
_id, userId,
type: 'Focus'|'Energize'|'Unwind'|'Confidence'|'Calm',
seedMoods: string[], // learned from mood history
lastGeneratedAt: Date,
spotifyPlaylistId?: string, // if mirrored to user’s Spotify
params: { tempo?: [number,number], valence?: [number,number], energy?: [number,number] }
}
WeeklyRecap {
_id, userId, weekOf: string, // ISO week key
topMoods: Array<{ mood: string; count: number }>,
volatility: number, // std dev or similar
listeningMinutes: number,
playlistIds: string[],
sentAt?: Date
}
API (Django/DRF; additive)
GET /api/mood/journal?from&to
POST /api/mood/journal // add/override note/tags; upsert by id
DELETE /api/mood/journal/:id
GET /api/mood/insights?from&to // aggregates: distro, volatility, by hour/weekday, input mix, top tracks after mood
POST /api/playlists/adaptive/refresh // (body: { types?: [...] }) returns playlist metadata + Spotify links
GET /api/recap/weekly?weekOf=... // fetch recap data for display
POST /api/user/notifications/recap // enable/disable weekly recap; set preferred day/time
Frontend UX
-
Journal (new page under Profile):
- Calendar/timeline view of entries; quick filters by mood, input type, tags.
- Edit note/tags; delete entry; “redact note locally” toggle.
-
Insights Dashboard:
- Cards: Mood Distribution (pie), Mood Over Time (line), Volatility score, Time-of-Day heatmap, Input-Type accuracy mix, Top “mood→tracks” correlations.
- “Create Adaptive Playlists” CTA.
-
Adaptive Playlists modal: select modes → preview tracks → “Save to Spotify” (OAuth) & “Pin on Home”.
-
Weekly Recap: in-app card + (optional) email; one-tap to open playlists.
Adaptive Playlist Logic (initial heuristic; ML-ready)
-
Compute rolling 7–14 day features: dominant moods, volatility, circadian peaks, session lengths.
-
Map to target audio features (Spotify):
- Focus: low valence range, medium-low energy, low danceability, instrumentalness↑
- Energize: high energy, higher tempo, medium-high valence
- Unwind/Calm: lower tempo/energy, valence medium, acousticness↑
-
Seed artists/tracks from user history when available; otherwise seed by mood→genre map.
-
Store
PlaylistProfileand re-use for refresh; allow per-user tuning via sliders.
Weekly Recap Generation
-
Cron (Celery/Beat or GitHub Action) each Sunday 17:00 local:
- Aggregate MoodEntry + listening history →
WeeklyRecap; send email if opted-in. - Include “This week’s Focus/Energize/Unwind” deep links.
- Aggregate MoodEntry + listening history →
Privacy & Compliance
- Journal notes are optional and excluded from model inputs by default.
- Provide Delete All Journal and Export JSON/CSV.
- Respect existing JWT auth; add per-user recap opt-in.
- Rate-limit insights endpoints.
Acceptance Criteria
- Journal page lists entries with search/filter; add/edit/delete works and respects auth.
- Insights endpoint returns: distribution, volatility, hourly & weekday breakdown, input-type mix, top post-mood tracks.
- Adaptive playlist generation produces at least 3 modes with sensible audio-feature ranges; “Save to Spotify” works via existing OAuth.
- Weekly recap job creates recap docs and (if enabled) sends email with playlist links.
- Export/Delete journal actions function and are confirmed with user prompts.
- Unit tests: aggregation math (volatility, time-bucket), playlist mapper, permissions.
- Basic e2e flow: record moods → view insights → generate playlists → receive recap.
- README updated with screenshots, env flags, and endpoints.
Config (.env additions)
RECAP_CRON="0 17 * * SUN"
INSIGHTS_WINDOW_DAYS=14
PLAYLIST_TRACKS_PER_MODE=25
PRIVACY_REDACT_NOTES_DEFAULT=true
Implementation Plan (High-Level)
- Models & Migrations for
MoodEntry,PlaylistProfile,WeeklyRecap. - Insights service: aggregation queries + caching (Redis).
- Playlist service: mood→audio-feature mapping, Spotify client, persistence.
- Endpoints & Auth; rate-limit & pagination.
- Frontend pages/components: Journal, Insights, Playlist modal, Recap card.
- Background job for weekly recap + email template.
- Tests and Docs.