My Daily Routine is a polished, production-grade full-stack productivity SaaS that helps users plan weekly routines, track long-term goals, and analyze daily completion stats. Architected on Next.js 16 (App Router, React Compiler) with React 19.2 and strict TypeScript, the platform combines a high-fidelity drag-and-drop weekly timeline, a Gemini-backed AI routine assistant, Recharts-powered analytics, image-resized profile uploads to S3-compatible storage, and a hardened Paddle one-time payment flow with HMAC-SHA256 webhook signature verification. It ships two parallel authentication systems — NextAuth v5 for Google OAuth and a custom jose-signed JWT cookie for email/password users with hashed-OTP email verification — unified behind middleware route protection and a `getActionActor()` server-action guard that re-derives the caller from cookies and never trusts client-passed identifiers. Backed by MongoDB via Mongoose with global connection caching, MongoDB-backed fixed-window rate limiting, a strict CSP, deep server-side response sanitization, and a daily cron job that prunes unverified accounts, the project demonstrates real-world security, observability, and product-completeness end-to-end. Live at mydailyroutine.app, shipped 20 April 2026.

A polished marketing surface — landing page, pricing page, testimonials, and full legal coverage (privacy, terms, refund) — built to convert first-time visitors and satisfy Paddle merchant-of-record requirements.
Fully SEO-equipped with App Router metadata, dynamic sitemap, robots, and PWA manifest. Responsive across mobile, tablet, and desktop with class-based dark mode powered by a custom `ThemeProvider`.
Animated hero, feature reveals, and micro-interactions delivered with Framer Motion 12 for a premium feel without sacrificing performance.


Two identity systems run in parallel. Google users sign in through NextAuth v5 beta. Email/password users authenticate against a custom flow that verifies passwords with `bcrypt` and issues an HS256 JWT (7-day expiry) signed via `jose`, stored in an httpOnly `authToken` cookie.
A single `src/middleware.ts` protects every authenticated route (`/dashBoard`, `/goals`, `/stats`, `/profile`, `/billing`, `/ai-routine`, `/admin`, `/changePassword`, `/color`). It checks for a NextAuth session first, then falls back to verifying the JWT cookie with `jwtVerify`, and redirects to `/login?callbackUrl=...` on failure.
Every server action re-derives the caller server-side via `getActionActor()` and `assertActorCanAccessEmail()` — the client-passed `email` argument is treated as untrusted input. Non-admin callers can only mutate their own data; admins are explicitly elevated.




New email/password registrations trigger a hashed one-time-password emailed via Brevo SMTP through `nodemailer`. Codes live in a dedicated `OtpCode` collection with `expiresAt` and `attempts` counters to defeat brute-force and replay.
An authenticated cron endpoint (`GET /api/cron/cleanup-unverified`, Bearer `CRON_SECRET`) runs daily to delete unverified accounts older than 30 days, keeping the user collection clean and compliant.
Transactional email templates also drive welcome and password-reset flows, all routed through the same hardened SMTP layer.

The dashboard is the heart of the product: a full seven-day timeline rendered side-by-side with a continuous midnight-to-midnight time axis and a colored 'now' line that ticks live to the user's current position in the day.
Tasks are draggable up, down, and (on desktop) across day columns with a blue drop preview that shows the exact landing slot before release. A `sync drag` mode shifts a task by the same delta across every day it appears, making bulk routine adjustments effortless.
Each task carries a category (work, health, sleep, meals, etc.), start/end time, and color coding. Zoom controls expand the day for fine-grained editing, a 'jump to now' button snaps the viewport to the current time, and undo / redo (Ctrl+Z / Ctrl+Y) are wired through Redux.
When a task's start time arrives, the app fires an audible chime and a toast notification with `Mark complete` / `Dismiss` actions that log straight to the user's stats.



A sidebar editor opens when adding a new task or clicking any task on the timeline. Pre-filled fields drive a fast edit loop: rename, recategorize, retime, and apply changes to the current day or to any subset of weekdays in one save.
The form supports adding the same task to multiple days at once (`Add task in multiple days`), deleting a task from a single day or from every day at once (`Delete from every day`), and a dedicated swap-time-slots feature that exchanges the time windows of two tasks atomically.
Conflict detection prevents overlapping schedules; duplicate-name prevention per day keeps things tidy; minimum and maximum duration are validated server-side. Save persists to MongoDB through Server Actions.


Premium members unlock `/ai-routine`, a separate timeline where users converse with Google Gemini (`@google/genai`) to draft and refine an entire weekly routine. The system prompt automatically references the user's real routine and the current AI-generated draft so suggestions always stay grounded in their actual life.
Each conversation is persisted per-user in a dedicated `AIRoutine` collection alongside the AI-generated routine. Gemini returns a reply plus an optional `updatedRoutine`, which is rendered live on the AI timeline as the chat unfolds.
When the user is happy, a single click in the dashboard sidebar copies the AI routine into their main routine — closing the loop between agentic suggestion and committed schedule.


The goals page lets users capture longer-horizon objectives — each with a name, priority, due date, optional time, subtasks, repeat rule, tags, and a reminder date. Tap the status pill to cycle a goal through to-do → in progress → done; pin important goals so they stay at the top.
Goals that carry a specific time appear as markers directly on the routine timeline on the day they are due — so the user's long-term ambitions and short-term schedule remain visually connected in one view.
All goal data lives on the same User document used for routine and stats, so reads stay fast and writes stay atomic.


Every completion the user logs (manual check, notification action, or automatic completion) feeds a per-day stats record on the User document. The `/stats` page renders four tabs of analytics powered by Recharts 3.
The Overview tab shows daily completion percentage, current streak, best-ever streak, and overall average. The Monthly tab breaks performance down by month with detailed tables. The Tasks tab reveals which tasks the user completes most often. The Insights tab generates personalized analysis — strongest day, three-month trend lines, and habit observations driven by the user's own data.
Charts include all-time trend, daily performance, weekly averages, and a calendar heat map for an at-a-glance feel for any month of the year.




The profile page lets users edit their display name and upload a profile photo. Photos are processed entirely server-side: a `uploadPhoto(email, FormData)` Server Action streams the file through `sharp`, which resizes it to 256×256 WebP, then writes it to S3-compatible storage (MinIO via `@aws-sdk/client-s3`) under `profiles/<userId>/<uuid>.webp` with `ACL: public-read`.
The previous `photoKey` is deleted on replacement so storage stays tidy. The Server Action body limit is intentionally raised to 10 MB in `next.config.ts` to accommodate the upload pipeline without weakening other action paths.
Mongoose documents are always run through `cleanUserForClient` before being serialized to Redux or into a JWT, stripping `_id`, version keys, and Buffer internals — a deliberate guard against leaking ORM internals to the browser.


Premium uses a one-time purchase model via Paddle. The frontend opens Paddle Checkout through `@paddle/paddle-js`; a 100% discount path exists for the Test plan to keep QA and demos friction-free.
`POST /api/paddle/webhooks` validates the `Paddle-Signature` header (`ts=...;h1=...`) by computing HMAC-SHA256 over `ts:rawBody` and comparing with `crypto.timingSafeEqual` to defeat timing attacks. Every event is deduplicated through a `PaddleWebhookEvent` collection so retries never double-extend access.
On a verified successful payment the webhook calls the `updatePaymentType` Server Action, which extends the user's `expiredAt` and updates `paymentType`. The `/billing` page surfaces the user's current plan, expiry, and a fresh checkout CTA.


An admin-gated `/admin` route gives privileged users a dashboard for managing the user base and triaging product feedback. Access is enforced both at the middleware layer and inside every Server Action via the `isAdmin` flag on `getActionActor()`.
Admins can list users, inspect account state (verified, premium, expiry), and respond to feedback submissions stored in a dedicated `Feedback` collection — closing the loop between user signal and product iteration.


Strict Content Security Policy in `next.config.ts` allowlists Paddle frames only, locks `frame-ancestors` to `'none'`, and sets `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, and a `Permissions-Policy` that disables camera, microphone, and geolocation by default.
MongoDB-backed fixed-window rate limiting protects sensitive endpoints (`enforceRateLimit(req, { route, max, windowMs, keyParts })`) keyed by IP plus optional context. A TTL index expires counters automatically — no cron required.
The Mongoose connection is cached on `globalThis._mongoosePromise` to survive Next.js HMR and serverless invocation churn. React Compiler is enabled (`reactCompiler: true`) so explicit `useMemo` / `useCallback` is reserved for cases the compiler can't see through.
Redux Toolkit holds three slices — `auth` (user, routine, goals, stats), `price` (Paddle pricing), `response` (AI conversation) — with `cleanUserForClient` enforced on every server-to-client boundary.
App Router Server Actions are colocated in a single `src/app/actions/index.ts` (~970 LOC, banner-organized by domain) so the action surface is auditable and easy to grep.


Next.js 16 (App Router, React Compiler) · React 19.2 · TypeScript 5.9 (strict) · Tailwind CSS 3.4 (class-based dark mode) · Framer Motion 12 · Redux Toolkit 2 + react-redux 9.
NextAuth v5 beta (Google) · custom JWT via `jose` + `bcrypt` · MongoDB / Mongoose 8 · `@aws-sdk/client-s3` + `sharp` (MinIO) · Paddle (`@paddle/paddle-js`) · `@google/genai` (Gemini) · `nodemailer` over Brevo SMTP · Recharts 3 · Sonner 2 · ESLint 9 (flat config).