A cross-platform activity tracking system that aggregates digital activity from Windows and Android into a single, searchable chronological timeline. Built with TypeScript end-to-end, containerized with Docker, and authenticated via Supabase Auth.
Live Demo · Viewing demo data when the backend is asleep — sign in to explore the full UI.
You can download the latest Windows and Android clients directly from the GitHub Releases Page.
- 🪟 Windows x64 Client: Download the
Setup.exeorUniversalTimeline-Windows-x64.exefrom the latest release assets. - 📱 Android Client: Download the
.apkfile from the latest release assets.
┌──────────────┐ ┌──────────────┐
│ Windows PC │ │ Android │
│ (.NET 9) │ │ (Kotlin) │
│ │ │ │
│ GetForeground│ │ UsageStats │
│ Window() │ │ Manager │
│ + Idle Det. │ │ + Notif. │
│ + SyncQueue │ │ + SyncQueue │
└──────┬───────┘ └──────┬───────┘
│ Batched POST /events │
│ (offline-tolerant) │
└───────────┬───────────────┘
▼
┌─────────────────┐
│ NestJS Backend │
│ (TypeScript) │
│ │
│ • JWT Auth Guard │
│ • Merge Intervals│
│ • Idempotency │
│ • Aggregations │
└────────┬─────────┘
│
┌─────────┴─────────┐
▼ ▼
┌───────────┐ ┌──────────────┐
│ PostgreSQL │ │ Supabase Auth│
│ (Neon/ │ │ (JWT tokens) │
│ TimescaleDB│ └──────────────┘
│ locally) │
└───────────┘
│
▼
┌─────────────────┐
│ Next.js Frontend│
│ (React 19) │
│ │
│ • Timeline View │
│ • Summary Charts │
│ • Search/Filter │
│ • Demo Fallback │
└─────────────────┘
| Layer | Technology | Purpose |
|---|---|---|
| Backend | NestJS, TypeORM, PostgreSQL | REST API, event processing, aggregations |
| Frontend | Next.js 16, React 19, Recharts | Timeline visualization, summary dashboards |
| Windows Client | .NET 9, WinForms, Win32 API | Foreground app tracking, idle detection |
| Android Client | Kotlin, Jetpack Compose, WorkManager | UsageStats tracking, notification capture |
| Auth | Supabase Auth | JWT-based authentication across all clients |
| Database | TimescaleDB (local), Neon (prod) | Time-series optimized storage |
| Infra | Docker, Render, Vercel, GitHub Actions | Containerization, deployment, CI/CD |
- Windows: Polls
GetForegroundWindow()every 5 seconds to detect active application, window title, and process name. Detects idle state viaGetLastInputInfo()after 2 minutes of inactivity. - Android: Queries
UsageStatsManagerevery 60 seconds via a foreground service. Captures notification metadata and screen on/off events via broadcast receivers.
- Events are queued locally in a
SyncQueueand flushed in batches of up to 50 every 60 seconds. - Failed syncs retry with exponential backoff (1s → 2s → 4s → ... → 60s max).
- Queue caps at 10,000 events and drops oldest on overflow.
- Content-based idempotency hashing prevents duplicate events from network retries.
- An O(n log n) merge algorithm consolidates adjacent same-activity events with gaps ≤ 60 seconds into unified segments, reducing noise and storage.
- Color-coded horizontal bars on a time axis for each day.
- Activity type filtering (coding, browsing, communication, design, productivity).
- Full-text search across activity names.
- Daily, weekly, and monthly summary views with pie charts and bar charts.
- Period-over-period comparison toggle.
- Graceful demo fallback: when the backend is unreachable, the UI renders realistic sample data with a subtle banner instead of an error page.
UniversalTimeline/
├── backend/universal-timeline/ # NestJS API
│ └── src/
│ ├── common/ # Auth guard, exception filter, logger
│ ├── events/ # Event entity, controller, service
│ ├── processing/ # Merge intervals algorithm
│ ├── summary/ # Aggregation queries
│ ├── sync/ # Sync queue (shared logic)
│ └── timeline/ # Timeline query endpoint
├── frontend/ # Next.js 16 web app
│ └── src/
│ ├── app/ # Pages (login, timeline)
│ ├── components/ # TimelineView, SummaryView
│ ├── context/ # AuthContext (Supabase)
│ └── lib/ # API client, demo data, Supabase client
├── client/windows/ # .NET 9 Windows client
│ └── UniversalTimeline.Client/
│ ├── ActivityTracker.cs # Win32 foreground window polling
│ ├── SyncQueue.cs # Offline queue with retry
│ ├── SupabaseAuth.cs # Auth integration
│ └── TrayApplicationContext.cs # System tray app
├── clients/android/ # Kotlin Android client
│ └── app/src/main/java/.../
│ ├── tracking/ # UsageStats, notifications, screen
│ ├── sync/ # SyncQueue, SupabaseAuth
│ └── ui/ # Jetpack Compose screens
├── docker-compose.yml # Local dev: backend + TimescaleDB
├── render.yaml # Render deployment blueprint
└── .github/workflows/ci.yml # CI: backend tests + frontend build
- Node.js 20+
- Docker (for local PostgreSQL)
- .NET 9 SDK (for Windows client)
- Android Studio (for Android client)
git clone https://github.com/YourUsername/UniversalTimeline.git
cd UniversalTimelineCopy the example env files and fill in your credentials:
# Backend
cp backend/universal-timeline/.env.example backend/universal-timeline/.env
# Frontend
# Create frontend/.env.local with:
# NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
# NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
# NEXT_PUBLIC_API_URL=http://localhost:3001
# Android
# Create clients/android/local.properties with:
# supabase.url=your_supabase_url
# supabase.anon_key=your_anon_keydocker compose up -d dbcd backend/universal-timeline
npm install
npm run start:devcd frontend
npm install
npm run devVisit http://localhost:3000 for the frontend.
| Service | Platform | URL |
|---|---|---|
| Frontend | Vercel | Auto-deploys on push to main |
| Backend | Render | Auto-deploys on push to main |
| Database | Neon (prod) / TimescaleDB (local) | Managed PostgreSQL |
| Auth | Supabase | Hosted auth service |
| CI/CD | GitHub Actions | Runs backend tests + frontend build checks |
This project is unlicensed — built as a personal portfolio project.
