CodeIssuesPull RequestsActionsSecurityInsights
✨ AI
More
Settings

fix(notifications): humanize JSON bodies, collapse stale bursts, Natural Light restyle #5462

Merged⚡ AI-generatedXSccantynz wants to mergesweep/notificationsmainopened 24d ago
ccantynzcommented 24d ago

Part of the design-sweep for the visual-audit ledger — refs #211. NOTIFICATIONS slice. All fixes are render-time; stored notification rows are never mutated.

Defect 1 — raw JSON blob rendered as a notification body (BROKEN)

Before: the top notification printed its stored JSON payload verbatim — braces, keys and all — as the row body. After: humanizeNotificationBody() (new src/lib/notification-render.ts) detects a body that parses as JSON at render time and shows its message/title/summary field, or a key: value digest of primitive fields ("repo name: gluecron · pr number: 42"). An empty {}/[] hides the body entirely. Plain prose passes through untouched, including brace-leading text that isn't JSON. Raw braces never reach the user.

Defect 2 — ~200 identical ungrouped "PR #xxxx has gone quiet" rows

Before: every stale-sweep run wrote one notification per stale PR, and the inbox showed them as ~200 identical rows (capped at 50 by the query, so even the count was a lie). After: collapseNotificationRows() groups adjacent runs of the same kind + repo (kinds pr_stale, issue_stale) into one row — "234 PRs have gone quiet in owner/repo" — following the burst-collapse precedent in src/lib/recent-activity.ts. The group row has a "Show all N" <details> expander (first 20 members inline with per-item mark-read, then a link to the full list) plus a "View pull requests" link to the repo's filtered view. Fetch limit raised to 500 so the group count is honest; the page still displays at most 50 grouped rows.

Defect 3 — list styling to the Natural Light standard

Before: the old dark "2026 hero" treatment — animated blur orb, gradient headline text, glow shadows, gradient AI badge, a literal "purple-tinted" AI-row wash, and hardcoded dark-theme colors (#60a5fa, #fbbf24, #34d399, rgba(255,255,255,…)). After: .hlth-* idiom from src/routes/health.tsx — panel card (--bg-elevated + 1px --border, --r-lg), hairline --border-subtle separators, hover --bg-hover, a solid var(--accent) unread bar, token-only icon tints (--blue/--amber/--green/--accent), quiet outline AI badge and mark-all button, and an honest empty state ("No notifications" / "No unread notifications" — no fake liveness). No purple, no gradients, no hardcoded hex.

Also found while in here

  • The row-meta repo link never rendered: the old code read n.repoOwner/n.repoName, which the bare select() never populated. The query now joins repositories + users, so the link is real (and powers the group headline).
  • The "×" Dismiss button has always posted to /notifications/:id/deletewhich had no handler anywhere; every dismiss was a 404. Added the row-scoped delete handler in the same idiom as :id/read.

Tests

  • New src/__tests__/notification-render.test.ts (16 tests, pure module — no db mocks): JSON humanization incl. the never-raw-braces invariant, burst collapsing incl. repo boundaries and non-collapsible kinds, group phrasing.
  • bunx tsc --noEmit -p . — clean.
  • bun test src/__tests__ --test-name-pattern "notif" — 30 pass / 0 fail.

🤖 Generated with Claude Code

ccantynzAI Reviewcommented 24d ago

AI Triage

(no summary)

Priority: medium Risk area: mixed

Suggested labels: (no label suggestions) Suggested reviewers: (no reviewer suggestions)

Suggestions only — nothing has been applied. The PR author stays in control.

gluecron[bot]🤖 botAI Reviewcommented 24d ago

AI review unavailable

The platform's AI balance is exhausted, so AI generation is temporarily unavailable. Nothing was lost. You can queue this as a repair for the internal agent from the repository's Health page, or try again once the balance is restored. The PR is otherwise unchanged.

Cross-repo impact

See what breaks downstream if this PR merges.

Analyze →
⮌ Merged

This pull request was merged into main.

c comment · e edit title · m merge · a approve · r request changes · ? shortcuts