Watchtower-Course-Project

WatchTower

CI Node Playwright Jest Backend Database Auth

WatchTower is a lightweight observability platform for web applications. A small browser SDK embedded in a monitored app captures JavaScript errors, user interactions, and performance metrics and streams them to a Node.js backend, which persists them to Postgres (Supabase) and renders them in a real-time, per-user dashboard. It is built by CSE 110 Team 09 as a course project, but it is structured and documented to run as a real, deployable product.

Overview

Modern web teams need to know what is actually happening in production: which errors users hit, how fast pages load, which routes are slow, and what users do. WatchTower provides that visibility without a heavy agent or vendor lock-in. Drop the SDK into any web page, point it at a WatchTower backend, and the dashboard fills with live error feeds, latency charts, active-user counts, and deploy-version breakdowns. Dashboard access is authenticated with Clerk and data is scoped per user.

Demo GIF/Screenshot: TODO - add short GIF or screenshot before final submission if available.

Key Features

Architecture

External monitored app
   │  (embeds src/sdk/watchtower.js)
   ▼
WatchTower SDK  ──POST /api/events──►  Node.js backend (Render)
                                          │  src/backend/server.js
                                          ▼
                                 Supabase / Postgres
                                          │
                                          ▼
                          WatchTower dashboard (Clerk-authenticated)

See docs/architecture/auth-workflow.md for the full authentication and data-scoping flow.

Repository Structure

.github/        # Issue templates, Dependabot, and CI workflows
archive/        # Historical Prototype 1 & 2 code (kept for project history)
docs/           # Product, architecture, ADRs, process, research, sprint docs
scripts/        # Build/startup helpers (e.g. Clerk config generation)
src/
├── backend/    # Node.js HTTP server, event store, mailer, alert logic
├── frontend/   # dashboard/, landing/, auth/, demo/, dashboard-demo/, assets/
├── sdk/         # Browser SDK (watchtower.js)
└── shared/      # Shared utilities (event-utils.js)
tests/          # unit/ (Jest) and e2e/ (Playwright)

See src/README.md for the source layout and docs/README.md for the documentation index.

Getting Started

Prerequisites: Node.js 18 or later and npm.

  1. Clone the repository

    git clone https://github.com/cse110-sp26-group09/Watchtower-Course-Project.git
    cd Watchtower-Course-Project
    
  2. Install dependencies

    npm install
    
  3. Create your environment file

    cp .env.example .env
    
  4. Configure Clerk / Supabase / alerts as needed (all optional for a basic local run; see Environment Variables). Without Supabase the server uses in-memory storage; without a real Clerk key it runs in prototype/header-trust mode so tests and local development work.

  5. Start the server

    npm start
    

    The start script runs npm run config:clerk to generate src/frontend/auth/clerk-config.js from CLERK_PUBLISHABLE_KEY, then boots src/backend/server.js.

  6. Open the app

    URL Description
    http://localhost:3000/ Redirects to the landing page
    http://localhost:3000/landing/ Public landing page
    http://localhost:3000/dashboard Dashboard (requires Clerk sign-in)
    http://localhost:3000/demo/ Monitored demo app that sends events
    http://localhost:3000/dashboard-demo/ Static dashboard preview (no sign-in)

Environment Variables

All configuration is via environment variables. Copy .env.example to .env and fill in the values you need; it documents every variable with comments. Highlights:

Variable Required Description
CLERK_PUBLISHABLE_KEY For real auth Clerk publishable key (pk_test_... / pk_live_...).
SUPABASE_URL For persistence Supabase project URL.
SUPABASE_SERVICE_ROLE_KEY For persistence Supabase service-role key.
SUPABASE_ANON_KEY Optional Supabase anon key (fallback when no service-role key).
SUPABASE_P3_EVENTS_TABLE No Events table name (default prototype3_events).
DEFAULT_INGEST_OWNER_USER_ID No Temporary demo-only owner for unauthenticated external events. Replace with project/app keys for production.
GMAIL_ADDRESS / GMAIL_CLIENT_ID / GMAIL_CLIENT_SECRET / GMAIL_REFRESH_TOKEN For alerts Gmail OAuth credentials for threshold alert emails.
PORT No Server port (Render sets this automatically; default 3000).

Never commit .env or a generated clerk-config.js containing a real key. Only .env.example and clerk-config.example.js carry placeholders.

Database setup (Supabase only)

If using Supabase, run the SQL in docs/architecture/auth-workflow.md (or the snippet below) once in the Supabase SQL editor to create the prototype3_events and app_users tables and grant the service role access:

create table if not exists public.prototype3_events (
  id text primary key,
  type text not null,
  event_name text,
  timestamp timestamptz not null,
  session_id text,
  user_id text,
  route text,
  deploy_version text,
  app_name text,
  environment text,
  sdk_version text,
  data jsonb default '{}'::jsonb,
  received_at timestamptz not null
);
create index if not exists idx_prototype3_events_type on public.prototype3_events(type);
create index if not exists idx_prototype3_events_user_received_at on public.prototype3_events(user_id, received_at);

create table if not exists public.app_users (
  clerk_user_id text primary key,
  email text not null default '',
  display_name text not null default '',
  timezone text not null default '',
  last_seen_at timestamptz not null
);

grant usage on schema public to service_role;
grant select, insert, update, delete on public.prototype3_events to service_role;
grant select, insert, update, delete on public.app_users to service_role;

Running Tests

npm run test:unit   # Jest unit tests for src/backend pure modules (no server needed)
npm run test:e2e    # Playwright end-to-end tests (start the server first; see below)
npm run docs:js     # Generate JSDoc API docs into docs/api/ (gitignored)

The end-to-end tests target a running server. Start it in one terminal (npm start) and run npm run test:e2e in another, or set BASE_URL to point at a different host. CI starts the server in the background automatically; see .github/workflows/ci.yml, which also runs HTML/CSS/JS validation and a dependency audit. More detail in tests/README.md.

Deployment

Documentation

Start at the documentation index: docs/README.md.

Known Limitations / Future Work

Team / Course Context

WatchTower is the CSE 110 (Spring 2026) Team 09 course project. Roles:

Role Member
Technical Lead / CI-CD / Architecture Aditya
Product / Process / Sprint Documentation Lead Fahad
Frontend Lead James
UI/UX Lead Hieu
Instrumentation / Backend Prototype Lead Daniel
JavaScript Instrumentation Owner Jason
Data / Backend Logic Owner Waleed
Documentation / Communication / Requirements Support Josh
Research / QA / AI Tools Support Woosik
Frontend Prototype Support Alex
Frontend Components / Styling Support Hemendra

The video should cover:

Contributing

  1. Review the workflow guidelines.
  2. Follow the git workflow and Conventional Commits.
  3. Update documentation in the same PR as the code change.
  4. Major decisions get an ADR in docs/adr/.