Skip to content

Latest commit

 

History

History
135 lines (105 loc) · 4.62 KB

File metadata and controls

135 lines (105 loc) · 4.62 KB

IT Project Health Dashboard

Project Overview

Flask web application that displays an IT project health dashboard sourced from ServiceNow. Shows project portfolios with financial tracking (CapEx/OpEx), timeline visualization, and RAG status indicators.

Can run in two modes:

  • Live mode – connects to a ServiceNow instance via OAuth 2.0
  • Demo mode – uses generated sample data (no ServiceNow required)

Quick Start

# Install dependencies
pip install -r requirements.txt

# Demo mode (no ServiceNow needed)
DEMO_MODE=1 python app_oauth.py

# Live mode (requires .env with ServiceNow credentials)
python app_oauth.py

Dashboard runs at http://localhost:5080

File Structure

app_oauth.py           Main Flask application (routes, ServiceNow integration, Excel export)
demo_data.py           Demo data generator (50+ realistic projects across 8 portfolios)
templates/
  dashboard.html       Jinja2 template (Bootstrap 5.3.3, Inter font, Material Symbols)
static/
  css/
    dashboard-ui.css   Main stylesheet (light/dark themes, design system variables)
    print.css          Print-optimized layout (landscape A4)
  js/
    dashboard.js       Client-side logic (theme toggle, filters, tooltips)
requirements.txt       Python dependencies
Dockerfile             Container image definition
docker-compose.yml     Compose profiles for demo and live modes
.env                   ServiceNow credentials (not committed)

Key Architecture Decisions

  • Single-file backendapp_oauth.py contains all routes, ServiceNow API logic, and the Excel export builder. Kept intentionally compact.
  • Separated frontendtemplates/dashboard.html is a Jinja2 template. Styles live in static/css/ and JS in static/js/. Uses Bootstrap 5.3.3, Inter font, and Material Symbols from CDN.
  • Demo mode – when DEMO_MODE=1 env var is set, demo_data.py supplies pre-built section/totals data so the app never contacts ServiceNow.
  • Caching – in-memory _cached() helper with configurable TTL. Set TTL > 0 for production use to avoid hitting ServiceNow on every request.

Environment Variables

Required for live mode

Variable Description
SN_INSTANCE ServiceNow instance hostname (e.g. yourco.service-now.com)
SN_CLIENT_ID ServiceNow OAuth client ID
SN_CLIENT_SECRET ServiceNow OAuth client secret
SN_SVC_USER Service account username
SN_SVC_PASSWORD Service account password

Optional

Variable Default Description
DEMO_MODE (unset) Set to 1 to use generated demo data
FLASK_SECRET random Flask session secret key
CACHE_TTL 300 Cache TTL in seconds for live mode

ServiceNow Tables Used

Table Purpose
pm_project Project master data (name, PM, budget, dates)
pm_portfolio Portfolio definitions
sys_user User names and emails
project_status Monthly RAG status reports
fm_expense_line Actual CapEx/OpEx expense records

Data Flow (Live Mode)

  1. OAuth 2.0 Password Grant to get access token
  2. Query pm_project for active (or recently closed) projects
  3. Batch-query portfolios, users, status reports, and expense lines
  4. Aggregate into portfolio sections with totals
  5. Render via Jinja2 template

Data Flow (Demo Mode)

  1. demo_data.py generates deterministic sample data on import
  2. app_oauth.py reads pre-built sections from the demo module
  3. No network calls are made

Template Features

  • Dark/light theme toggle (persisted in localStorage)
  • Key Projects filter toggle
  • Advanced view toggle (shows PM column + email links)
  • Timeline bars with quarter labels and "today" marker
  • CapEx/OpEx progress bars with kCHF labels
  • RAG status circles (green/yellow/red/grey)
  • Bootstrap tooltips showing executive summaries
  • Print-optimized layout (landscape, forced light theme)
  • Excel export (Advanced view)

Common Tasks

Add a new portfolio to demo data

Edit PORTFOLIOS list in demo_data.py.

Change cache TTL

Set CACHE_TTL environment variable, or edit the _cached() calls in routes.

Modify timeline range

Timeline constants are computed in section 4 of app_oauth.py from rng_start and rng_end. Adjust the year offsets there.

Export to Excel

Enable Advanced view in the UI, then click the Export button. Route is /export/excel.

Testing

No test suite currently exists. Key functions to test:

  • _to_f() – currency string parsing
  • _pos() – timeline date positioning
  • grand_totals() – deduplication across cross-listed projects
  • demo_data.generate_demo_sections() – demo data structure correctness