Skip to content

~/ Personal Dashboard (personal-dashboard)

A single-user, self-hosted dashboard that brings together Habit Tracking Analytics, Fitness & Health Analytics, Homeserver Monitoring, and a Tech-Minimalist AI Chat into one unified interface.

Built with Next.js 16 (App Router + Turbopack), React 19, Tailwind CSS v4, shadcn/ui (Base UI base-nova), Drizzle ORM, PostgreSQL, and Recharts, the dashboard embraces a dense, terminal-inspired design focused on clarity, speed, and resilience.

✨ Features

  • 📊 Habit tracking analytics with streaks, trends, and achievements
  • 🏃 Fitness analytics powered by Intervals.icu
  • 🖥️ Homeserver monitoring with telemetry and uptime metrics
  • 🤖 Terminal-inspired multi-model AI chat
  • 🔒 Cloudflare Zero Trust + origin verification
  • 📱 PWA support with mobile home screen icons
  • ⚡ Graceful degradation when external services are unavailable

🧭 Architecture

The dashboard is built around five core design principles.

Principle Description
Tech-Minimalist UI Flat dark theme, strong typography, minimal chrome, and clear visual hierarchy.
Resilient Degradation Pages use Promise.allSettled() so individual service failures never take down the entire dashboard.
Lazy Database Initialization Drizzle establishes connections only on the first query, preventing startup failures when PostgreSQL or environment variables are unavailable.
Power-Window Awareness The homeserver is recognized as ASLEEP or TRANSITION outside configured schedules instead of being reported as offline.
Local Data Mirroring Intervals.icu activities are mirrored into PostgreSQL, enabling advanced analytics without API rate-limit concerns.

🛠️ Tech Stack

Category Technologies
Framework Next.js 16, React 19, TypeScript
Styling Tailwind CSS v4, shadcn/ui (Base UI)
Database PostgreSQL, Drizzle ORM
Charts Recharts
Utilities date-fns, Zod

📂 Project Structure

.
├── app/            # Route-level pages and API routes
├── components/     # Shared UI components and feature widgets
├── lib/            # Business logic, analytics, clients, config, DB, telemetry
├── scripts/        # CLI sync jobs
└── proxy.ts        # Canonical routing and origin verification

Directory Overview

Directory Purpose
app/ Route-level pages for Overview, Habits, Fitness, Server, and Chat
components/ Shared UI primitives and feature-specific widgets
lib/ Analytics, API clients, configuration, database schema, scheduling, telemetry, and chat utilities
scripts/ Background sync jobs for habits, activities, and server data
proxy.ts Canonical domain redirects and Cloudflare origin verification

Database Schema

The application uses five primary tables: - habits - habit_entries - settings - activities - activity_streams

💡 Dashboard Modules

🏠 Overview

A high-level snapshot of your daily activity and infrastructure. - Training readiness hero - Daily briefing - Habit, activity, and step summaries - Systems status board - Quick-launch links

✅ Habits

Analytics for long-term habit consistency. - Active streaks - Completion rates - Perfect weeks - Comeback rate - Automatic exercise sync from Intervals.icu

🏃 Fitness

Comprehensive endurance and training analytics. - CTL / ATL / TSB - ACWR - Foster Load - Personal Bests - Podium rankings - Activity heatmaps - GPS stream and run analysis

🖥️ Server

Self-hosted infrastructure monitoring. - Power schedule awareness - Uptime Kuma integration - Host telemetry - Backup monitoring - Cloudflare Access support

🤖 AI Chat

A terminal-inspired assistant interface. - Multi-model support - Prompt shortcuts - Live context inspection - Tech-minimalist interface

⚙️ Configuration

Environment Variables (.env)

[!IMPORTANT] All secrets are server-side only. Never expose them using the NEXT_PUBLIC_ prefix.

DATABASE_URL=postgresql://user:password@localhost:5432/dashboard

INTERVALS_API_KEY=your_intervals_api_key
INTERVALS_ATHLETE_ID=0

UPTIME_KUMA_URL=https://uptime.example.com
UPTIME_KUMA_API_KEY=your_kuma_prometheus_api_key

TELEMETRY_URL=https://telemetry.example.com/status
HABIT_TRACKER_URL=https://habits.example.com

CF_ACCESS_CLIENT_ID=your_client_id
CF_ACCESS_CLIENT_SECRET=your_client_secret

X_VERCEL_ORIGIN_SECRET=your_origin_secret

SERVER_TIMEZONE=Asia/Kolkata
SERVER_GRACE_MINUTES=5

Dashboard Configuration

Non-sensitive application settings are stored in: lib/config.ts

This includes: - Power schedule windows - Quick links - Fitness thresholds - Miscellaneous application constants

🔄 Background Sync Jobs

Three lightweight cron jobs keep the dashboard synchronized.

Job Purpose
sync-server Collects telemetry and Uptime Kuma metrics
sync-activities Mirrors recent Intervals.icu workouts
sync-habits Automatically checks today's exercise habit

Example Cron Configuration:

*/15 * * * * curl -sS "https://home.parthjain.tech/api/cron/sync-server" > /dev/null
*/15 * * * * curl -sS "https://home.parthjain.tech/api/cron/sync-activities?days=3" > /dev/null
*/15 * * * * curl -sS "https://home.parthjain.tech/api/cron/sync-habits" > /dev/null

🔒 Security

The application uses multiple layers of protection. - Allows direct access from localhost, LAN, and Tailscale. - Redirects unknown hosts to the canonical domain. - Validates the Cloudflare origin-secret header. - Prevents direct access to the underlying Vercel deployment.

For a complete explanation, see the dedicated Architecture & Security documentation.

🚀 Development

# Development
npm run dev

# Production
npm run build
npm run lint

# Database
npm run db:push
npm run db:generate
npm run db:studio

# Background Jobs
npm run cron:sync-habits
npm run cron:sync-activities
npm run cron:sync-server