Skip to content

vincentmakes/ServiceNow-Project-Dashboard

Repository files navigation

IT Project Health Dashboard

A portfolio-level project health dashboard that pulls data from ServiceNow and displays it in a single-page web view. Built with Flask and Bootstrap 5.

Dashboard screenshot Python 3.9+ Flask 3.0+ Docker

Screenshot 2026-02-28 at 22 38 58

Features

  • Portfolio view -- projects grouped by portfolio with per-portfolio and grand totals
  • Financial tracking -- planned vs. actual CapEx and OpEx with progress bars (kCHF)
  • RAG status indicators -- schedule, cost, and scope health from monthly status reports
  • Timeline visualization -- Gantt-style bars with quarter labels and a "today" marker
  • Key Project filter -- toggle to show only projects tagged [Key Project]
  • Advanced view -- reveals PM column, per-project email reminders, and bulk "mail all PMs" link
  • Dark / light theme -- toggle in the header, persisted in localStorage
  • Excel export -- download all active project data as a formatted .xlsx
  • Print-optimized -- landscape layout with forced light theme and proper page breaks
  • Demo mode -- run the dashboard with realistic generated data, no ServiceNow instance required

Quick Start

Option 1: Demo mode with Python

Demo mode runs the full dashboard with 63 generated sample projects across 8 IT portfolios (Cloud & Infrastructure, Cybersecurity, Data & Analytics, Digital Workplace, ERP & Finance Systems, Manufacturing & OT, Customer Experience, Integration & API Platform). No ServiceNow instance or credentials are needed.

# 1. Clone the repository
git clone https://github.com/vincentmakes/ServiceNow-Project-Dashboard.git
cd ServiceNow-Project-Dashboard

# 2. (Recommended) Create a virtual environment
python -m venv venv
source venv/bin/activate        # Linux / macOS
# venv\Scripts\activate         # Windows

# 3. Install dependencies
pip install -r requirements.txt

# 4. Start in demo mode
DEMO_MODE=1 python app_oauth.py

On Windows Command Prompt set the variable first:

set DEMO_MODE=1
python app_oauth.py

On Windows PowerShell:

$env:DEMO_MODE="1"
python app_oauth.py

Open http://localhost:5080 in your browser. You will see:

  • 8 portfolio sections with 5-8 projects each
  • ~20% of projects marked as Key Projects (filterable via toggle)
  • Realistic financial data (CapEx / OpEx with varied spend ratios)
  • RAG status indicators (green / yellow / red) on schedule, cost, and scope
  • Timeline bars spanning across quarters
  • Executive summaries in tooltips (hover over report dates)
  • A few projects with stale reports (red dot) to demonstrate the email reminder feature

All interactive features work in demo mode: Key Projects filter, Advanced view, dark/light theme toggle, Excel export, and print layout.

Option 2: Demo mode with Docker

# Build and start in demo mode — single command, nothing else needed
docker compose --profile demo up --build

Open http://localhost:5080.

To stop: Ctrl+C or docker compose --profile demo down.

Option 3: Demo mode with Docker (no compose)

# Build the image
docker build -t project-dashboard .

# Run in demo mode
docker run -p 5080:5080 -e DEMO_MODE=1 project-dashboard

Live Mode (ServiceNow)

Live mode connects to a ServiceNow instance via OAuth 2.0 and queries real project data from the pm_project, pm_portfolio, sys_user, project_status, and fm_expense_line tables.

Prerequisites

  • A ServiceNow instance with the Project Portfolio Management (PPM) plugin
  • An OAuth 2.0 application registered in ServiceNow
  • A service account with read access to the tables listed above

With Python

  1. Create a .env file in the project root:
SN_INSTANCE=yourco.service-now.com
SN_CLIENT_ID=your_oauth_client_id
SN_CLIENT_SECRET=your_oauth_client_secret
SN_SVC_USER=your_service_account_username
SN_SVC_PASSWORD=your_service_account_password

# Optional
FLASK_SECRET=a_random_secret_string
CACHE_TTL=300
  1. Install and run:
pip install -r requirements.txt
python app_oauth.py

With Docker Compose

  1. Create the same .env file as above.

  2. Start with the live profile:

docker compose --profile live up --build

With Docker (no compose)

docker build -t project-dashboard .

docker run -p 5080:5080 \
  -e SN_INSTANCE=yourco.service-now.com \
  -e SN_CLIENT_ID=your_client_id \
  -e SN_CLIENT_SECRET=your_client_secret \
  -e SN_SVC_USER=your_username \
  -e SN_SVC_PASSWORD=your_password \
  project-dashboard

Or mount a .env file:

docker run -p 5080:5080 --env-file .env project-dashboard

Project Structure

app_oauth.py             Main application (Flask routes, SN integration, Excel export)
demo_data.py             Demo data generator (~63 projects, 8 portfolios)
templates/
  dashboard.html         Jinja2 template (Inter font, Material Symbols)
static/
  css/
    dashboard-ui.css     Main stylesheet (light/dark themes, design system)
    print.css            Print-optimized layout (landscape A4)
  js/
    dashboard.js         Client-side logic (theme, filters, tooltips)
requirements.txt         Python dependencies
Dockerfile               Container image definition
docker-compose.yml       Compose profiles for demo and live modes
.env                     Credentials for live mode (not committed)
CLAUDE.md                Technical documentation for AI-assisted development

Configuration

Environment Variable Required Default Description
DEMO_MODE No (unset) Set to 1, true, or yes to use generated demo data
SN_INSTANCE Live mode -- ServiceNow instance hostname (e.g. yourco.service-now.com)
SN_CLIENT_ID Live mode -- ServiceNow OAuth client ID
SN_CLIENT_SECRET Live mode -- ServiceNow OAuth client secret
SN_SVC_USER Live mode -- Service account username
SN_SVC_PASSWORD Live mode -- Service account password
FLASK_SECRET No random Flask session secret key
CACHE_TTL No 300 Data cache TTL in seconds (live mode only)

ServiceNow Tables & Required Fields

The dashboard reads from five ServiceNow tables. The service account used in live mode needs read access to all fields listed below.

pm_project — Project master data

Field Type Description
sys_id GUID Unique project identifier
number String Project number (e.g. PRJ0012345)
short_description String Project name. Projects containing [Key Project] are flagged as key projects. Bracket tokens like [CT] cross-list the project into matching portfolios
project_manager Reference → sys_user Project manager (sys_id)
u_business_project_manager Reference → sys_user Business project manager (sys_id). This is a custom field — adjust if your instance uses a different column
capex_cost Currency Planned CapEx budget
opex_cost Currency Planned OpEx budget
primary_portfolio Reference → pm_portfolio Portfolio the project belongs to (sys_id)
start_date Date Planned start date
end_date Date Planned end date
work_end Date Actual completion date (used for closed projects)
active Boolean Queried with active=true for active projects
state Integer Queried with stateIN3,7 for recently closed projects

pm_portfolio — Portfolio definitions

Field Type Description
sys_id GUID Unique portfolio identifier
name String Portfolio display name (used as section header)

sys_user — User directory

Field Type Description
sys_id GUID Unique user identifier
name String Display name (shown in PM / Business PM columns)
email String Email address (used for reminder mailto links)

project_status — Monthly status reports

Field Type Description
sys_id GUID Status report identifier (used for deep-link into ServiceNow)
project Reference → pm_project Parent project (sys_id)
as_on Date Report "as of" date. Falls back to sys_updated_on if empty
sys_updated_on DateTime Last modification timestamp (fallback for report date)
schedule String Schedule RAG status (green, yellow, red)
cost String Cost RAG status (green, yellow, red)
scope String Scope RAG status (green, yellow, red)
executive_summary String Free-text summary (shown in tooltip on hover)

fm_expense_line — Actual expenses

Field Type Description
source_id Reference → pm_project Parent project (sys_id)
amount Currency Expense amount
expense_type String Expense category. Lines containing cap (case-insensitive) are counted as CapEx; all others as OpEx
state String Expense state. Lines with state=cancelled are excluded

Production Deployment

# Using gunicorn (Linux / macOS)
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:5080 app_oauth:app

# Using waitress (Windows)
pip install waitress
waitress-serve --host=0.0.0.0 --port=5080 app_oauth:app

# Using Docker
docker build -t project-dashboard .
docker run -d -p 5080:5080 --env-file .env --restart unless-stopped project-dashboard

Consider adding:

  • A reverse proxy (nginx / Apache) with HTTPS
  • An authentication layer (SSO, basic auth, or Azure AD)
  • Cache TTL tuned to your data freshness needs (default: 5 minutes)

License

Internal use.

About

Project Dashboard using standard tables in ServiceNow

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors