jramos 7af44608d0 feat(compliance): add 'View in Reporting' link for 2.3.x Ivanti metrics
In ComplianceDetailPanel, active metrics with a metric_id starting with
'2.3' and an Ivanti_Vulnerability_ID in extra_json now surface the ID
prominently alongside a 'View in Reporting →' button. Clicking navigates
directly to the Reporting page. onNavigate prop threaded through
App → CompliancePage → ComplianceDetailPanel → MetricRow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 09:20:30 -06:00

CVE Dashboard

A self-hosted vulnerability management dashboard for tracking CVE remediation status, managing vendor documentation, monitoring Ivanti host findings, and overseeing False Positive (FP) workflows.


Table of Contents


Overview

The CVE Dashboard answers a common problem in vulnerability management: tracking which CVEs have been addressed, whether supporting vendor documentation exists, and where each finding is in the remediation or exception workflow.

The application provides:

  • A searchable, filterable CVE list with per-vendor tracking and document storage
  • NVD API integration to auto-populate CVE metadata
  • Ivanti/RiskSense integration to sync open and closed host findings with live FP workflow tracking
  • Reporting page with donut charts, advanced per-column filtering, inline editing, and CSV/XLSX export
  • Archer risk acceptance ticket tracking (EXC numbers) linked to CVE/vendor pairs
  • Weekly vulnerability report upload and processing
  • A knowledge base for internal documentation and policies
  • Role-based access control with a full audit trail

Tech Stack

Layer Technology
Backend Node.js, Express 5
Database SQLite3
File uploads Multer 2
Auth bcryptjs, cookie-based sessions
Frontend React 19, lucide-react, xlsx
Report processing Python 3 (stdlib only — no extra packages required for notes import)
Weekly report processing Python 3, pandas, openpyxl

Prerequisites

  • Node.js 18 or later
  • npm
  • Python 3 (required for weekly report processing and bulk notes import)

Installation

1. Clone the repository

git clone <repo-url>
cd cve-dashboard

2. Install backend dependencies

cd backend
npm install

3. Install frontend dependencies

cd frontend
npm install

4. Install Python dependencies (for weekly report processing)

cd backend/scripts
pip install -r requirements.txt

Required packages: pandas>=2.0.0, openpyxl>=3.0.0

The bulk notes import script (import_notes_from_csv.py) uses only Python stdlib and does not require these packages.

5. Initialize the database

Run once from the backend/ directory to create the SQLite database, all tables, indexes, and a default admin user:

cd backend
node setup.js

This creates backend/cve_database.db and a default admin account:

  • Username: admin
  • Password: admin123

Change the admin password immediately after first login.

6. Run database migrations

After the initial setup, apply feature migrations in order:

cd backend
node migrations/add_weekly_reports_table.js
node migrations/add_knowledge_base_table.js
node migrations/add_archer_tickets_table.js
node migrations/add_ivanti_sync_table.js
node migrations/add_ivanti_findings_tables.js

The Ivanti findings tables migration also handles adding the fp_workflow_counts_json and fp_id_counts_json columns idempotently on each server start — no manual re-run is needed after the first run.


Configuration

The application is configured via .env files. These files are gitignored and must be created manually per environment.

Backend: backend/.env

PORT=3001
API_HOST=localhost
CORS_ORIGINS=http://YOUR_IP:3000
SESSION_SECRET=change-this-to-a-long-random-string
NODE_ENV=production

# Optional: NVD API key for higher rate limits (50 req/30s vs 5 req/30s)
# Register at https://nvd.nist.gov/developers/request-an-api-key
NVD_API_KEY=your-key-here

# Ivanti / RiskSense integration (required for Reporting page sync)
IVANTI_API_KEY=your-ivanti-api-key
IVANTI_CLIENT_ID=1550
# Optional: filter workflows to a specific person's submissions
IVANTI_FIRST_NAME=
IVANTI_LAST_NAME=
# Set to 'true' if your network has SSL inspection / self-signed certs
IVANTI_SKIP_TLS=false

Frontend: frontend/.env

REACT_APP_API_BASE=http://YOUR_IP:3001/api
REACT_APP_API_HOST=http://YOUR_IP:3001

Replace YOUR_IP with the machine's IP address or hostname. Use localhost for local-only access.

Important: React caches environment variables at build/start time. After changing frontend/.env, fully restart the frontend process — a browser refresh alone is not sufficient.


Running the Application

From the project root:

./start-servers.sh   # Starts backend and frontend in the background
./stop-servers.sh    # Stops all servers

The start script saves PIDs to backend.pid and frontend.pid. Logs are written to backend/backend.log and frontend/frontend.log.

Running manually

# Terminal 1 — backend
cd backend
node server.js

# Terminal 2 — frontend
cd frontend
npm start

Default ports

Service URL
Frontend http://localhost:3000
Backend API http://localhost:3001

Features

Authentication and User Roles

All routes require authentication. Three roles are supported:

Role Permissions
viewer Read-only: CVEs, documents, findings, reports, knowledge base, Archer tickets
editor All viewer permissions plus: create/update CVEs, upload documents, sync Ivanti findings, save notes and overrides, manage knowledge base articles, manage Archer tickets, upload weekly reports
admin All editor permissions plus: delete documents, delete reports, manage users, view audit logs

Sessions expire after 24 hours. Session tokens are stored in httpOnly cookies.


Home Dashboard — CVE Management

The home page is the primary CVE workflow tool.

CVE List

  • Search CVEs by keyword (matches CVE ID, vendor, description)
  • Filter by vendor, severity (Critical / High / Medium / Low), and status
  • Color-coded severity badges: Critical (red), High (amber), Medium (sky blue), Low (green)
  • Paginated list view

CVE Operations (editor/admin)

  • Add a new CVE entry — NVD auto-fill populates description, severity, and published date automatically
  • Edit any field on an existing CVE entry
  • Update status for all vendor rows matching a CVE ID in one click
  • Delete a single vendor entry or all vendor entries for a CVE ID
  • The same CVE ID can be tracked across multiple vendors independently

Document Management

  • Upload documents attached to a CVE/vendor pair
  • Supported document types: advisory, email, screenshot, patch, other
  • Allowed file extensions: PDF, images (PNG, JPG, GIF, BMP, TIFF), Office documents (DOC, DOCX, XLS, XLSX, PPT, PPTX), text files (TXT, MD, CSV, LOG), email files (MSG, EML), and others (RTF, HTML, XML, JSON, YAML, ODF variants, ZIP, GZ, TAR, 7Z)
  • File size limit: 10 MB per upload
  • Admins can delete documents

NVD Integration

  • Auto-fill CVE description, severity, and published date from the NIST NVD API 2.0 when adding a new CVE
  • Bulk NVD Sync (editor/admin): fetch updated metadata for all CVEs in the database in one operation
  • CVSS severity cascade: v3.1 preferred, then v3.0, then v2.0
  • Rate-limit aware: respects NVD's 5 req/30s unauthenticated limit; with NVD_API_KEY the limit increases to 50 req/30s

Archer Ticket Quick Navigation

  • Archer EXC numbers shown on CVE rows
  • Clicking an EXC badge navigates to the Reporting page with that EXC number pre-filtered

Calendar Widget

  • Shows current month with red dot indicators on dates where Ivanti findings are due
  • Click a date to navigate to the Reporting page filtered to that due date

Reporting — Host Findings

The Reporting page is the core operational view for remediation tracking. It integrates with Ivanti/RiskSense to show all host findings for the configured business units.

Syncing Data

Click Sync in the top-right of the page to pull the latest findings from Ivanti. The sync:

  1. Fetches all open host findings matching your BU filters and severity range (8.59.9)
  2. Fetches the closed finding count separately
  3. Sweeps all closed findings to capture FP workflow states (including Approved FPs that are now closed)
  4. Stores everything in the local SQLite cache

Findings are auto-synced on a 24-hour schedule. The last sync timestamp and status are shown at the top of the page.

Note: The Reporting page will show "No data — click Sync to load" until the first sync completes. IVANTI_API_KEY must be set in backend/.env.

Metric Charts

Four donut charts are shown at the top of the page.

Chart What it shows
Open vs Closed Total open vs closed host findings. Counts come from the Ivanti API directly (not from the local cache) so closed findings are always reflected even though they aren't stored locally.
Action Coverage Findings broken down by action taken: FP Request (has an FP# workflow ticket) · Archer Exception (has an EXC- number in notes) · Pending (no action yet). Click any segment to filter the table.
FP Finding Status How many findings fall into each FP workflow state (Actionable, Requested, Reworked, Approved, Rejected, Expired, Unknown). Includes closed findings — an Approved FP closes the finding and would be invisible otherwise.
FP Workflow Status How many unique FP# ticket IDs are in each state. One FP# ticket can cover many findings; this chart counts tickets, not findings.

Findings Table

The table shows all open findings from the cache. Each row represents a single host finding.

Columns

Column Description
Finding ID Ivanti finding identifier
Severity Numerical VRR score with group label (CRITICAL / HIGH)
Title Vulnerability title
CVEs Associated CVE IDs — up to 2 shown, remainder as "+N"
Host Hostname — inline editable (see Overrides below)
IP Address Host IP address
DNS DNS/FQDN — inline editable
Due Date Remediation due date; red if overdue, amber if within 30 days
SLA SLA status: OVERDUE / AT_RISK / WITHIN_SLA
BU Business unit; STEAM rows are highlighted
Workflow FP# ticket ID and state badge — color-coded by state
Last Found Last detection date from Ivanti
Notes Free-form notes field — inline editable, persists across syncs

Column Management

Click the Columns button to open the column manager:

  • Toggle column visibility with the eye icon
  • Drag rows to reorder columns
  • Column order and visibility persist to localStorage

Sorting

Click any sortable column header to sort ascending; click again to sort descending.

Filtering

Click the filter icon (⊙) on any filterable column header to open a filter dropdown:

  • Search box to narrow options
  • Multi-select checkboxes — all values are selected by default
  • — empty — option at the top: selects findings where the cell has no value (e.g., filter the Workflow column to — empty — to see all findings with no FP ticket assigned)
  • "Select All" and "Clear" bulk buttons
  • Multiple column filters work as AND (all must match)
  • Active filter badge and "Clear Filters" button appear when filters are applied

The Action Coverage donut chart also acts as a filter — click a segment to filter the table to that action type.

Inline Editing

  • Hostname / DNS: Click a cell to edit. An amber dot (●) indicates the value has been overridden from what Ivanti reported. Use the revert button (↻) to restore the original value. Changes save on blur or Enter; Escape cancels.
  • Notes: Click to edit. Saves on blur. Maximum 255 characters. Notes survive cache refreshes.

Exporting

Click the Export button to download the current view (filtered, sorted, visible columns only):

  • CSV — UTF-8 with BOM for Excel compatibility
  • Excel (.xlsx) — Auto-fitted column widths

Filename format: findings-export-YYYY-MM-DD.csv / .xlsx


Knowledge Base

A document library for internal reference material such as policies, runbooks, and vendor advisories.

  • Upload documents with a title, optional description, and category
  • View documents inline in the browser (PDFs render in an iframe; Markdown files are rendered as HTML)
  • Download any document
  • Filter and browse by category
  • Editors and admins can upload and delete; all authenticated users can view

Allowed file types: PDF, Markdown, TXT, Office documents (DOC, DOCX, XLS, XLSX, PPT, PPTX), HTML, JSON, YAML, and images (PNG, JPG, GIF).


Archer Risk Acceptance Tickets

Track Archer exception tickets (EXC numbers) linked to specific CVE/vendor pairs.

  • EXC number format: EXC-NNNNN
  • Statuses: Draft, Open, Under Review, Accepted
  • Optional Archer URL field for deep-linking to the Archer record
  • Filter tickets by CVE ID, vendor, or status
  • EXC numbers are unique across the system
  • Clicking an EXC number on the home page navigates directly to the Reporting page with that EXC pre-filtered

Weekly Reports

Editors and admins can upload weekly vulnerability reports as .xlsx files. The report is processed by a Python script (backend/scripts/split_cve_report.py) that:

  1. Reads the Vulnerabilities sheet
  2. Splits rows where multiple CVE IDs are comma-separated in the CVE ID column into individual rows
  3. Saves the processed file alongside the original

Both the original and processed files can be downloaded from the weekly reports list. Only the most recently uploaded report is marked as current. Admins can delete old report records and their associated files.


User Management (Admin)

Admins can manage user accounts from the UI:

  • Create users with a role assignment
  • Change username, email, password, role, or active status
  • Deactivating a user immediately invalidates all their active sessions
  • Admins cannot demote themselves or deactivate their own account

Audit Log (Admin)

Every state-changing action is recorded with the user identity, IP address, action type, target entity, and a before/after details payload. Admins can view the log with filtering by user, action type, entity type, and date range. Results are paginated (25 per page).


Scripts

backend/scripts/import_notes_from_csv.py

Bulk-import notes into the findings cache from a CSV file. Useful for onboarding existing notes or migrating from a spreadsheet.

CSV format:

ID,NOTES
12345678,EXC-5754
87654321,Patched in Feb maintenance window

Usage:

cd backend/scripts

# Preview what would be imported (no writes)
python3 import_notes_from_csv.py input.csv --dry-run

# Import against the default database path
python3 import_notes_from_csv.py input.csv

# Import against a specific database
python3 import_notes_from_csv.py input.csv --db /path/to/cve_database.db
Argument Description
csv_file Path to the input CSV (required)
--db Path to the SQLite database (default: ../cve_database.db)
--dry-run Preview changes without writing to the database
  • Notes longer than 255 characters are truncated with a warning
  • Finding IDs not present in the active Ivanti cache are skipped
  • Uses UPSERT — running the same CSV twice is safe

Dependencies: Python stdlib only (no pip install required).


backend/scripts/split_cve_report.py

Called automatically by the weekly report upload flow. Not intended to be run manually. Splits multi-CVE rows in the uploaded Excel report into one row per CVE ID.

Dependencies: pandas>=2.0.0, openpyxl>=3.0.0


API Reference

All endpoints are prefixed with /api. All endpoints except /api/auth/login and /api/auth/logout require a valid session cookie.

Auth

Method Path Auth Description
POST /api/auth/login Public Log in, receive session cookie
POST /api/auth/logout Public Invalidate session
GET /api/auth/me Session Get current user info
POST /api/auth/cleanup-sessions Session Delete expired sessions

CVEs

Method Path Role Description
GET /api/cves viewer+ List CVEs; query params: search, vendor, severity, status
POST /api/cves editor+ Create a new CVE entry
PUT /api/cves/:id editor+ Update a CVE entry by row ID
PATCH /api/cves/:cveId/status editor+ Update status for all vendor rows matching a CVE ID
DELETE /api/cves/:id editor+ Delete a single CVE vendor entry
DELETE /api/cves/by-cve-id/:cveId editor+ Delete all vendor entries for a CVE ID
GET /api/cves/check/:cveId viewer+ Quick check: existence and status of a CVE
GET /api/cves/distinct-ids viewer+ All distinct CVE IDs (used by NVD sync)
GET /api/cves/:cveId/vendors viewer+ All vendor entries for a specific CVE ID

Documents

Method Path Role Description
GET /api/cves/:cveId/documents viewer+ List documents for a CVE; optional ?vendor= filter
POST /api/cves/:cveId/documents editor+ Upload a document for a CVE/vendor pair
DELETE /api/documents/:id admin Delete a document and its file from disk

NVD

Method Path Role Description
GET /api/nvd/lookup/:cveId viewer+ Look up a single CVE in the NVD 2.0 API
POST /api/cves/nvd-sync editor+ Bulk update CVE metadata from NVD

Ivanti / RiskSense — Workflows

Method Path Role Description
GET /api/ivanti/workflows viewer+ Get cached workflow data (total, list, sync status)
POST /api/ivanti/workflows/sync viewer+ Trigger an immediate workflow sync from Ivanti

Ivanti / RiskSense — Host Findings

Method Path Role Description
GET /api/ivanti/findings viewer+ Get cached findings with notes and overrides merged in
POST /api/ivanti/findings/sync viewer+ Trigger an immediate findings sync from Ivanti
GET /api/ivanti/findings/counts viewer+ Open vs closed finding totals
GET /api/ivanti/findings/fp-workflow-counts viewer+ FP workflow state breakdown — returns findingCounts, findingTotal, idCounts, idTotal
PUT /api/ivanti/findings/:findingId/override editor+ Override hostName or dns for a finding; empty value clears the override
PUT /api/ivanti/findings/:findingId/note viewer+ Save or update a finding note (max 255 chars)

Weekly Reports

Method Path Role Description
POST /api/weekly-reports/upload editor+ Upload and process a .xlsx vulnerability report
GET /api/weekly-reports viewer+ List all uploaded reports
GET /api/weekly-reports/:id/download/:type viewer+ Download original or processed file
DELETE /api/weekly-reports/:id admin Delete a report record and its files

Knowledge Base

Method Path Role Description
POST /api/knowledge-base/upload editor+ Upload a new knowledge base document
GET /api/knowledge-base viewer+ List all articles
GET /api/knowledge-base/:id viewer+ Get article metadata
GET /api/knowledge-base/:id/content viewer+ Get file content for inline display
GET /api/knowledge-base/:id/download viewer+ Download the file
DELETE /api/knowledge-base/:id editor+ Delete article and file

Archer Tickets

Method Path Role Description
GET /api/archer-tickets viewer+ List tickets; optional filters: cve_id, vendor, status
POST /api/archer-tickets editor+ Create a new Archer ticket
PUT /api/archer-tickets/:id editor+ Update an Archer ticket
DELETE /api/archer-tickets/:id editor+ Delete an Archer ticket

Users (Admin only)

Method Path Role Description
GET /api/users admin List all users
GET /api/users/:id admin Get a single user
POST /api/users admin Create a user
PATCH /api/users/:id admin Update a user
DELETE /api/users/:id admin Delete a user

Audit Logs (Admin only)

Method Path Role Description
GET /api/audit-logs admin Paginated audit log; filters: user, action, entityType, startDate, endDate
GET /api/audit-logs/actions admin List distinct action types for filter dropdowns

Utility

Method Path Role Description
GET /api/vendors viewer+ List all distinct vendor names
GET /api/stats viewer+ Dashboard statistics (total, critical count, addressed count, document count)

Architecture

cve-dashboard/
├── start-servers.sh          # Start backend + frontend in background
├── stop-servers.sh           # Stop all servers
│
├── backend/
│   ├── server.js             # Express app — routes, middleware, file upload, security headers
│   ├── setup.js              # One-time DB initialization and default admin creation
│   ├── cve_database.db       # SQLite database (gitignored)
│   ├── uploads/              # File storage root (gitignored)
│   │   ├── <CVE-ID>/
│   │   │   └── <vendor>/     # CVE documents stored here
│   │   ├── weekly_reports/   # Uploaded vulnerability reports
│   │   ├── knowledge_base/   # Knowledge base documents
│   │   └── temp/             # Temporary upload staging directory
│   ├── routes/
│   │   ├── auth.js               # Login, logout, session check
│   │   ├── users.js              # User CRUD (admin)
│   │   ├── auditLog.js           # Audit log viewer (admin)
│   │   ├── nvdLookup.js          # NVD API proxy
│   │   ├── weeklyReports.js      # Weekly report upload and management
│   │   ├── knowledgeBase.js      # Knowledge base document management
│   │   ├── archerTickets.js      # Archer EXC ticket CRUD
│   │   ├── ivantiWorkflows.js    # Ivanti workflow batch sync and cache
│   │   └── ivantiFindings.js     # Ivanti host findings sync, notes, overrides, FP counts
│   ├── middleware/
│   │   └── auth.js               # requireAuth and requireRole middleware
│   ├── helpers/
│   │   ├── auditLog.js           # logAudit helper (fire-and-forget)
│   │   └── excelProcessor.js     # Calls Python script for report processing
│   ├── migrations/
│   │   ├── add_weekly_reports_table.js
│   │   ├── add_knowledge_base_table.js
│   │   ├── add_archer_tickets_table.js
│   │   ├── add_ivanti_sync_table.js       # Ivanti workflow cache table
│   │   └── add_ivanti_findings_tables.js  # Findings cache, notes, counts, overrides tables
│   └── scripts/
│       ├── split_cve_report.py       # Splits multi-CVE rows in Excel reports
│       ├── import_notes_from_csv.py  # Bulk-import finding notes from CSV
│       └── requirements.txt          # pandas, openpyxl (weekly report processing only)
│
└── frontend/
    └── src/
        ├── App.js                    # Home dashboard — CVE list, filters, modals, calendar
        ├── App.css                   # Global styles and CSS variables
        ├── contexts/
        │   └── AuthContext.js        # Auth state provider (login, logout, role helpers)
        └── components/
            ├── LoginForm.js              # Login page
            ├── NavDrawer.js              # Side navigation drawer
            ├── UserMenu.js               # User dropdown in header
            ├── CalendarWidget.js         # Due-date calendar with Ivanti finding indicators
            ├── UserManagement.js         # Admin user management panel
            ├── AuditLog.js               # Admin audit log viewer
            ├── NvdSyncModal.js           # Bulk NVD sync dialog with review/apply flow
            ├── KnowledgeBaseModal.js     # Knowledge base upload/list modal
            ├── KnowledgeBaseViewer.js    # Inline document viewer
            └── pages/
                ├── ReportingPage.js      # Host findings: charts, table, filters, export
                ├── KnowledgeBasePage.js  # Knowledge base page (placeholder)
                └── ExportsPage.js        # Exports page (placeholder)

Database Schema

Core tables (created by setup.js)

cves — One row per CVE/vendor pair. UNIQUE(cve_id, vendor).

documents — Files attached to a CVE/vendor pair. Foreign key to cves(cve_id).

required_documents — Vendor-specific document requirements.

users — Accounts with roles: admin, editor, viewer.

sessions — Active sessions with 24-hour expiry.

audit_logs — Append-only log of all state-changing actions.

Feature tables (added by migrations)

weekly_reports — Metadata for uploaded vulnerability reports. Tracks original and processed file paths, row counts, uploader, and a is_current flag.

knowledge_base — Document library entries with title, slug, category, description, and file metadata.

archer_tickets — Archer EXC exception tickets linked to CVE/vendor pairs. UNIQUE(exc_number). Foreign key (cve_id, vendor) with CASCADE delete.

ivanti_sync_state — Single-row cache (id=1) for Ivanti workflow batch data: total count, JSON array of workflows, sync timestamp, sync status.

ivanti_findings_cache — Single-row cache (id=1) for Ivanti host findings: total count, JSON array of slimmed finding objects, sync timestamp, sync status.

ivanti_finding_notes — Persistent per-finding notes keyed by finding ID. Survives findings cache refreshes. UNIQUE(finding_id).

ivanti_counts_cache — Single-row cache (id=1) for finding metrics:

  • open_count / closed_count — total open and closed findings
  • fp_workflow_counts_json — JSON object mapping FP workflow state → number of findings
  • fp_id_counts_json — JSON object mapping FP workflow state → number of unique FP# ticket IDs

ivanti_finding_overrides — Editor-applied overrides for hostName and dns fields. UNIQUE(finding_id, field).

View

cve_document_status — Aggregates document counts per CVE/vendor and derives a compliance_status (Complete when an advisory is present, otherwise Missing Required Docs).


Security Model

File upload security

  • Extension allowlist enforced by Multer; executables (.exe, .js, .sh, .py, .bat, etc.) are blocked
  • MIME type prefix validation in addition to extension checking
  • 10 MB per-file size limit
  • Filenames are sanitized: path separators, .. sequences, null bytes, and non-alphanumeric characters are removed

Path traversal prevention

  • sanitizePathSegment() strips /, \, .., and null bytes from any value used in path.join()
  • isPathWithinUploads() verifies resolved paths stay within the uploads root before any file operation

Input validation

  • CVE ID must match /^CVE-\d{4}-\d{4,}$/
  • Severity must be one of: Critical, High, Medium, Low
  • Status must be one of: Open, Addressed, In Progress, Resolved
  • Archer EXC numbers must match /^EXC-\d+$/
  • Finding override field must be one of: hostName, dns
  • All database operations use prepared statements (no string interpolation in SQL)

Error handling

  • 500 responses never expose internal error messages to the client
  • Full errors are logged server-side only
  • Descriptive 400/409 responses are safe as they contain only application-authored validation messages

Security headers

Applied to all responses:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy: camera=(), microphone=(), geolocation=()

Session cookies

httpOnly: true, sameSite: lax, secure: true in production (NODE_ENV=production).


Migrations

Migrations are standalone Node.js scripts that modify the database directly. Run them in the listed order on a fresh install. They use CREATE TABLE IF NOT EXISTS so they are safe to re-run if needed.

cd backend
node migrations/add_weekly_reports_table.js
node migrations/add_knowledge_base_table.js
node migrations/add_archer_tickets_table.js
node migrations/add_ivanti_sync_table.js
node migrations/add_ivanti_findings_tables.js

For an existing deployment upgrading from an earlier schema, check the legacy migration scripts in backend/:

  • migrate_multivendor.js — Adds multi-vendor support to an older single-vendor schema
  • migrate-audit-log.js — Adds the audit_logs table to pre-auth deployments
  • migrate-to-1.1.js — General 1.0 → 1.1 schema update

The Ivanti FP workflow count columns (fp_workflow_counts_json, fp_id_counts_json) are added automatically via ALTER TABLE ... ADD COLUMN each time the server starts. These statements are idempotent — the error for a duplicate column is silently ignored.

Description
No description provided
Readme 20 MiB
Languages
JavaScript 98.5%
CSS 0.6%
Python 0.5%
Shell 0.3%
HTML 0.1%