Skip to content

feat: add git-based insights dashboard report#299

Merged
bd73-com merged 3 commits intomainfrom
claude/build-insights-dashboard-V3vmx
Mar 30, 2026
Merged

feat: add git-based insights dashboard report#299
bd73-com merged 3 commits intomainfrom
claude/build-insights-dashboard-V3vmx

Conversation

@bd73-com
Copy link
Copy Markdown
Owner

@bd73-com bd73-com commented Mar 30, 2026

Summary

Adds a standalone HTML insights report (insights-report.html) generated from the repository's actual git history. This replaces the broken Claude Code /insights report which showed zero sessions despite extensive project activity. The report uses a dark theme matching the app's design system.

Changes

  • insights-report.html — New standalone HTML dashboard with:
    • Top-level stats: 50 commits, +86K lines added, 51 PRs merged, ~25 commits/week
    • "At a Glance" summary with velocity, focus area, hotspot, and work rhythm insights
    • Bar charts: commit types (84% fixes), day-of-week activity, hour-of-day (CET), language breakdown
    • Hotspot files table showing the 10 most frequently changed files
    • Biggest commits section (top 5 by lines changed)
    • Key insights cards: shipping velocity, production hardening phase, test-driven workflow, route hotspot warning, Monday load spike, add/remove ratio

How to test

  1. Check out the branch: git checkout claude/build-insights-dashboard-V3vmx
  2. Open insights-report.html in a browser
  3. Verify all charts render correctly with the dark theme
  4. Verify stats match git history (git log --oneline | wc -l should show 50+ commits)
  5. Check responsive layout by resizing the browser window

https://claude.ai/code/session_01LQtS6mgGPiYt1BTugXsbAH

Summary by CodeRabbit

  • New Features
    • Added a standalone Git Insights report page: a dark-themed dashboard showing overall commit/line/PR counts, commits-per-week, commit-type and language distributions, day/hour activity patterns, most-changed (hotspot) files, largest commits summary, and colored "Key Insights" cards. Footer shows report source/date and commits analyzed.

claude added 2 commits March 30, 2026 09:00
Generates an HTML insights report from actual git history showing
commit velocity, type breakdown, hotspot files, day/hour activity,
language distribution, and key project insights.

https://claude.ai/code/session_01LQtS6mgGPiYt1BTugXsbAH
@github-actions github-actions bot added the feature New feature label Mar 30, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Added a new standalone static HTML report (insights-report.html) that renders a dark-themed, inline-CSS Git insights dashboard showing repository statistics, commit/time/language breakdowns, hotspot files, largest commits, and insight cards; no client-side scripts or dynamic loading. Potential risk: embedding untrusted data into static HTML could enable XSS if generation source is not sanitized.

Changes

Cohort / File(s) Summary
Git Insights Dashboard
insights-report.html
New standalone static HTML page with inline styling that displays Git-derived analytics: summary stats, commits/week, commit-type and timing grids, language/hour-of-day bars, hotspot files table, biggest commits list, and colored key-insight cards. No JS or external data fetching.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a new git-based insights dashboard report (insights-report.html). It's concise, specific, and directly reflects the primary purpose of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/build-insights-dashboard-V3vmx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@insights-report.html`:
- Line 2: Add a lang attribute to the root html element (the <html> tag) so
assistive tech and search engines can determine the document language; set it to
the document's primary language (e.g., lang="en" or the correct BCP 47 code) in
the file where the <html> element is defined and ensure any templates or
rendering code that produces <html> also emits this attribute consistently.
- Line 6: Remove the external Google Fonts link tag that loads "Inter" (the
<link href="https://fonts.googleapis.com/...Inter..."> tag) to avoid leaking
user data; update the report's CSS to use system font fallbacks (e.g., Inter →
system UI stack) or, if Inter is required, replace the external link by
self-hosting the Inter font files and referencing them via `@font-face` in your
stylesheet so no external CDN is contacted.
- Around line 3-6: Add a viewport meta element to the head so the responsive CSS
works on mobile: insert a meta with name "viewport" and content set to
width=device-width, initial-scale=1 before the <title> (i.e., within the
existing head block that contains the title and Google Fonts link) so the `@media`
rules at the responsive CSS section take effect on mobile devices.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2da1e154-9748-40f4-95ee-4cf2c1cd6168

📥 Commits

Reviewing files that changed from the base of the PR and between e39b40f and dc4ee23.

📒 Files selected for processing (1)
  • insights-report.html

- Add lang="en" to <html> for accessibility
- Add viewport meta tag for responsive rendering on mobile
- Remove external Google Fonts CDN to avoid leaking user data;
  use system font stack instead

https://claude.ai/code/session_01LQtS6mgGPiYt1BTugXsbAH
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@insights-report.html`:
- Around line 159-176: The commit messages and file paths are embedded raw into
the HTML elements with classes commit-subj and commit-meta (and author name at
lines ~66–67); sanitize all git-derived strings by applying HTML entity encoding
for &, <, >, " and ' before rendering. Add/use a single escape utility (e.g.,
escapeHtml) and call it wherever commit-subj, commit-meta, file path, or author
name values are inserted into the template/DOM so the rendered values are safe
from stored XSS.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7ff3cd85-77a2-4ef6-9e2a-6bb3028957a8

📥 Commits

Reviewing files that changed from the base of the PR and between dc4ee23 and b3a6ff3.

📒 Files selected for processing (1)
  • insights-report.html

Comment on lines +159 to +176
<div class="commit-subj">feat: add automated welcome campaign system (#275)</div>
<div class="commit-meta">2026-03-26 &bull; <span class="lines">+1,422 / -80</span> lines &bull; 8 files</div>
</div>
<div class="commit-card">
<div class="commit-subj">feat: add campaign data recovery from orphaned recipients (#295)</div>
<div class="commit-meta">2026-03-27 &bull; <span class="lines">+712 / -0</span> lines &bull; 4 files</div>
</div>
<div class="commit-card">
<div class="commit-subj">fix: resolve 6 admin bugs with input validation and filter consistency (#297)</div>
<div class="commit-meta">2026-03-27 &bull; <span class="lines">+525 / -7</span> lines &bull; 3 files</div>
</div>
<div class="commit-card">
<div class="commit-subj">Fix server startup crash when lsof is unavailable (#212)</div>
<div class="commit-meta">2026-03-16 &bull; <span class="lines">+352 / -25</span> lines &bull; 2 files</div>
</div>
<div class="commit-card">
<div class="commit-subj">fix: resolve TOCTOU race in Resend webhook handler (#226)</div>
<div class="commit-meta">2026-03-16 &bull; <span class="lines">+340 / -122</span> lines &bull; 2 files</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether the report generator escapes git-derived strings before HTML output.

set -euo pipefail

echo "== Candidate generator files =="
fd -i 'insight|report|git' .

echo
echo "== Places where git history is read =="
rg -n -C2 'git log|git show|rev-list|pretty=format|numstat|shortstat' .

echo
echo "== Places where HTML is generated/template strings are built =="
rg -n -C2 '<html|<table|<div class="commit-subj"|innerHTML|template|writeFile|fs\.writeFile|render' .

echo
echo "== Escaping/sanitization helpers present? =="
rg -n -C2 'escape|sanitize|encode|he\.escape|lodash\.escape|entities|replace\(/&|replace\(/</|replace\(/>/' .

echo
echo "Expected: dynamic git strings flow through a dedicated escape function before being inserted into HTML."

Repository: bd73-com/fetchthechange

Length of output: 161


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== All script and code files in repo ==="
git ls-files | head -50

echo
echo "=== Search for 'insights-report' references ==="
rg -n 'insights-report' . 2>/dev/null || echo "(no matches)"

echo
echo "=== GitHub Actions workflows that might generate this ==="
find . -path './.github/workflows/*.yml' -o -path './.github/workflows/*.yaml' 2>/dev/null | xargs cat 2>/dev/null || echo "(no workflows found)"

echo
echo "=== Search for report/insight generation in all code files ==="
rg -n -t js -t ts -t py 'insights-report|generateReport|writeReport|renderReport' . 2>/dev/null || echo "(no matches)"

echo
echo "=== Check package.json for build scripts ==="
cat package.json 2>/dev/null | jq '.scripts' 2>/dev/null || echo "(no package.json or no scripts key)"

echo
echo "=== Search for writeFile/fs operations that might write HTML ==="
rg -n 'writeFile|writeFileSync|write.*insights|write.*report' . 2>/dev/null || echo "(no matches)"

Repository: bd73-com/fetchthechange

Length of output: 1913


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Direct search for insights-report anywhere in repo ==="
rg -l 'insights-report' . 2>/dev/null | head -20

echo
echo "=== All files matching *insight* or *report* ==="
fd -i 'insight|report' . 2>/dev/null | head -30

echo
echo "=== Check if insights-report.html is in git tracking ==="
git ls-files | grep -i 'insight\|report'

echo
echo "=== All .js/.ts/.mjs/.mts files for code review ==="
git ls-files | grep -E '\.(js|ts|mjs|mts)$' | head -30

echo
echo "=== Search all code for git command execution or HTML template generation ==="
rg -n 'execSync|execFile|spawn|exec\(' . --type js --type ts --type py 2>/dev/null | head -20

Repository: bd73-com/fetchthechange

Length of output: 125


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== All HTML files in repo ==="
find . -name '*.html' -type f 2>/dev/null | head -20

echo
echo "=== Check if file exists and its status ==="
ls -la ./insights-report.html 2>/dev/null || echo "File not found in current directory"

echo
echo "=== Search for any HTML generation with common patterns ==="
rg -n 'innerHTML|document\.write|fs\.write|\.html|\.append|ejs|handlebars|pug' . --type js --type ts --type py 2>/dev/null | head -30

echo
echo "=== Directory structure ==="
ls -la . | head -20

echo
echo "=== All TypeScript/JavaScript files ==="
git ls-files | grep -E '\.(ts|tsx|js|jsx)$' | head -20

Repository: bd73-com/fetchthechange

Length of output: 5120


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Git history of insights-report.html (last 5 commits) ==="
git log --oneline -5 -- ./insights-report.html 2>/dev/null || echo "(no git history)"

echo
echo "=== All script files (.sh, .py, package.json scripts) ==="
find . -name '*.sh' -o -name '*.py' 2>/dev/null | grep -v node_modules | head -20

echo
echo "=== Check package.json scripts ==="
cat package.json 2>/dev/null | grep -A 50 '"scripts"' || echo "(no package.json)"

echo
echo "=== Read first 100 lines of insights-report.html to see actual content ==="
head -100 ./insights-report.html

Repository: bd73-com/fetchthechange

Length of output: 11254


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Lines 140-180 of insights-report.html to check commit subject escaping ==="
sed -n '140,180p' ./insights-report.html

echo
echo "=== Search for any occurrence of &lt; or &amp; (escaped HTML) in file ==="
rg -c '&lt;|&amp;|&quot;|&#' ./insights-report.html || echo "No escaped HTML entities found"

echo
echo "=== Check if commit subjects contain any special characters that need escaping ==="
grep -o 'commit-subj">[^<]*</div>' ./insights-report.html | head -20

Repository: bd73-com/fetchthechange

Length of output: 3478


Escape all git-derived strings before embedding in HTML to prevent stored XSS.

The report embeds commit subjects and file paths directly into HTML without escaping. Lines 159–176 show commit messages like feat: add automated welcome campaign system (#275) and lines 143–152 show file paths like server/routes.ts inserted as raw text. If git data flows through a generation pipeline, a malicious commit message (e.g., feat: <img src=x onerror="alert(1)">) or crafted file path would execute JavaScript when the report is opened. Apply HTML entity encoding for &, <, >, ", ' before inserting any git-sourced content.

Also applies to: 66–67 (author name)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@insights-report.html` around lines 159 - 176, The commit messages and file
paths are embedded raw into the HTML elements with classes commit-subj and
commit-meta (and author name at lines ~66–67); sanitize all git-derived strings
by applying HTML entity encoding for &, <, >, " and ' before rendering. Add/use
a single escape utility (e.g., escapeHtml) and call it wherever commit-subj,
commit-meta, file path, or author name values are inserted into the template/DOM
so the rendered values are safe from stored XSS.

@bd73-com bd73-com merged commit 312293b into main Mar 30, 2026
2 checks passed
@bd73-com bd73-com deleted the claude/build-insights-dashboard-V3vmx branch March 30, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants