Mood Tracker AI
A full-stack extension of the Frontend Mentor Mood Tracking App with authenticated persistence, mood and sleep trends, AI-assisted mood identification, and personalized suggestions.
- Next.js
- React
- TypeScript
- Tailwind CSS
- Recharts
- Clerk
- Neon PostgreSQL
- Drizzle ORM
- Zod
- Vercel AI SDK
- Google Gemini
- Vitest
- React Testing Library
- Playwright
Overview
Mood Tracker AI extends the Frontend Mentor Mood Tracking App into a complete authenticated application with persistent user data, statistics, trend visualization, and optional AI assistance. I deliberately started from an existing visual design so I could focus on the application architecture and product behavior: authentication, relational persistence, API design, responsive state management, AI integration, usage limits, and graceful fallback behavior. The core mood tracker does not depend on AI. Users can always log their mood manually, while AI is introduced only at specific points where it can add useful personalization.
Motivation
After Web Dictionary AI, I wanted to explore AI integration in an application with richer user state and persistent domain data. The main design constraint was that AI should enhance an existing workflow rather than replace it. Mood entries, statistics, trends, authentication, and persistence all work independently of the model. AI is used for two deliberately narrow interactions: helping a user identify a mood from their own reflection and generating optional suggestions from an existing mood entry. This kept the architecture understandable while introducing real concerns such as structured model output, quotas, failure handling, persistence boundaries, and user confirmation of AI-generated values.
Features
Mood tracking
- Five mood levels from Very Sad to Very Happy
- Up to three feelings per entry
- Short journal reflection
- Sleep-range tracking
- One mood entry per user per calendar day
- Recent mood history
- Average mood and sleep comparisons
- Mood and sleep trend visualization
- Responsive desktop and mobile experience
AI-assisted mood identification
- Optional alternative to manually choosing a mood
- Uses the user's journal reflection to suggest a mood and feelings
- Suggestions are presented for review before saving
- Users can edit the suggested mood and feelings
- One optional second suggestion is available
- AI never silently persists inferred values
- Manual mood logging remains available without using AI
Personalized suggestions
- Optional activity suggestions based on a recently logged entry
- Short supportive phrases
- Personalized recommendations can be generated for the current and three preceding entries
- Generated recommendations are persisted
- Deterministic mood-based suggestions remain available before personalized generation
- AI failure or quota exhaustion does not break the underlying experience
Architecture
The application uses a conventional full-stack architecture with explicit boundaries between authentication, persistence, domain logic, and AI functionality. Clerk handles authentication while the application maintains its own user record in PostgreSQL. Mood entries and generated recommendations are stored in Neon using Drizzle ORM, with authenticated server endpoints enforcing ownership and validation. AI requests are executed only on the server. Inputs are deliberately constrained for each feature, Gemini responses use structured output validated with Zod, and a shared per-user daily quota limits provider usage. The mood-identification feature sends only the user's current reflection to the model. Personalized recommendations use only the selected mood entry's mood, feelings, sleep range, and reflection. Neither feature sends mood history, database identifiers, or account information to the model. Conceptual flow: Authenticated user → Next.js application → Validated server API → PostgreSQL / AI service → Validated application state → User interface. The completed v1.0 implementation passed 180 automated tests covering domain validation, persistence, authenticated API behavior, AI quota enforcement, and fallback behavior, together with linting, TypeScript validation, and a production build before deployment.
AI as an optional layer
AI is intentionally an optional layer rather than a requirement for using the application. When no personalized recommendation has been generated, the application displays deterministic suggestions based on the selected mood. If Gemini is unavailable or the daily quota has been exhausted, mood tracking continues normally. The same principle applies during logging: users can select their mood and feelings manually without making any AI request. When AI-assisted identification is used, its result is treated as a suggestion that must be reviewed before persistence.
AI usage boundaries
- All AI calls execute server-side.
- AI output is validated before entering application state.
- AI usage is limited by a shared per-user daily quota.
- The quota resets daily at 00:00 UTC.
- Mood identification is limited to two attempts per open logging session.
- Personalized recommendations can be generated only once per eligible mood entry.
- Provider failures consume no additional application complexity: the normal workflow remains available.
- The project does not use agents, RAG, embeddings, vector databases, AI memory, or autonomous workflows.
Dashboard overview
The dashboard surfaces recent mood entries, running averages, and mood and sleep trends at a glance.
Logging a mood
Manual mood logging captures a mood level, up to three feelings, a short reflection, and a sleep range in a single guided step.
Describing your mood
Instead of selecting a mood directly, a user can describe how they feel in their own words.
AI-inferred result
Gemini suggests a mood and feelings from that reflection, presented for review and editing before anything is saved.
Default suggestions
Before any personalized generation, the application already offers deterministic, mood-based suggestions.
Personalized suggestions
Generating a personalized suggestion replaces the deterministic default with a result tailored to that specific entry, and the result is persisted.
Technology stack
- Next.js (App Router)
- React
- TypeScript
- Tailwind CSS
- Recharts
- Clerk
- Neon PostgreSQL
- Drizzle ORM
- Zod
- Vercel AI SDK
- Google Gemini
- Vitest
- React Testing Library
- Playwright
- Vercel
Lessons learned
- AI features are easier to reason about when they are optional enhancements to an already complete workflow.
- Structured model output still requires application-level validation and domain constraints.
- Quotas and failure behavior are product concerns, not only infrastructure concerns.
- AI-inferred user data should remain reviewable and editable before persistence.
- Deterministic fallbacks can preserve a useful experience when personalized AI is unavailable.
- Small, explicit server/client boundaries make AI integration easier to test and maintain.