Skip to content

s360-reporter: fix broken item links and enforce full pagination, Fixes AB#3683197#446

Open
shahzaibj wants to merge 1 commit into
masterfrom
shjameel-microsoft-verify-s360-first-user-bugs
Open

s360-reporter: fix broken item links and enforce full pagination, Fixes AB#3683197#446
shahzaibj wants to merge 1 commit into
masterfrom
shjameel-microsoft-verify-s360-first-user-bugs

Conversation

@shahzaibj

@shahzaibj shahzaibj commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Fixes AB#3683197 — two first-user bugs in the s360-reporter skill reported by Sowmya Malayanur (Jun 2026, ★4).

Bugs

Bug 1 — Broken links to S360 items. generate-report.js rendered every item title as <a href="${item.s360Url}"> unconditionally. When the S360 API returned no URL field, the anchor shipped as literal href="undefined" (404 on click). Verified in Sowmya's actual report at ~/Desktop/s360-report-2026-04-08.html — zero item links pointed to s360.msftcloudes.com.

Bug 2 — Incomplete item coverage. SKILL.md said "If more than 50 items, paginate using the nextCursor field" but there was no enforcement. A first-time user who missed that step shipped a report with only page 1 of the MCP response.

Fixes

Link safety (generate-report.js)

  • New safeHref(url) — only accepts non-empty http(s) URLs. Rejects null, undefined, literal "undefined", empty, javascript:, etc.
  • New linkOrText(url, innerHtml, style) — wraps in <a> only when safeHref returns a URL; else renders plain text so the reviewer notices.
  • Replaced the 3 unsafe <a href="${item.s360Url}"> call sites (item card + table row).
  • Red banner + stderr WARN listing every item that ended up without a link, so a broken run is visible in-report instead of shipping silently.

Coverage enforcement

  • New fetch-items.js — consolidates paginated MCP responses into one JSON file. Exits non-zero if the last input page still has a populated nextCursor.
  • merge-items.js — refuses to run against any input JSON that still has a populated nextCursor (defense-in-depth).
  • SKILL.md Steps 1a/1b/1c updated: pagination is mandatory and routed through fetch-items.js.

Self-check (AC#3)

  • Coverage summary printed to stderr on every run: Coverage summary: N active items rendered (X out-of-SLA, Y approaching, Z in SLA, W missing ETA). N resolved. N new this week.
  • Broken-link WARN + in-report red banner.

Verification

Ran end-to-end against a synthetic fixture:

Test Expected Result
fetch-items.js with page1-only (cursor present) exit ≠ 0 ✅ exit=1
fetch-items.js with page1+page2 (last cursor null) exit 0, 3 items consolidated
merge-items.js with unspent-cursor input throw
merge-items.js with clean input exit 0
generate-report.js with mix of valid + broken URLs banner + WARN, plain text for bad, anchor for good
Rendered HTML contains no href="undefined" / href="null" / href="" 0 matches
All hrefs are valid http(s) ✅ aka.ms, dev.azure.com, s360.msftcloudes.com

Notes for reviewers

  • The 3rd link site in the resolved-list uses pbiUrl(r.pbi) — builds the URL from an ID and is guaranteed safe, so no change needed there.
  • No changes to reduce-items.js grouping/dedup logic. Fix is additive.
  • No new MCP tools. fetch-items.js is a pure Node consolidator — the actual MCP calls still happen from the model per SKILL.md.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

Fixes AB#3683197 — two first-user bugs reported by Sowmya Malayanur (Jun 2026).

Bug 1 — Broken item links
- generate-report.js rendered every item title as an anchor around item.s360Url
  unconditionally, so a missing S360 URL shipped as literal href="undefined"
  (404 on click).
- Added safeHref() and linkOrText() helpers: only wrap the title in an anchor
  when s360Url is a non-empty http(s) URL. Otherwise render plain text so the
  reviewer notices before sending.
- Added a red banner and stderr WARN listing every item that ended up without a
  link, so a broken run is visible in-report rather than shipping silently.

Bug 2 — Incomplete item coverage
- Pagination was only a manual instruction in SKILL.md, so a first-time user
  could ship the report using only page 1 of the MCP response (up to 50 items).
- New fetch-items.js consolidator loops through paginated response files and
  hard-fails if the last page still has a populated nextCursor.
- merge-items.js now refuses to run against any input JSON that still has a
  populated nextCursor (defense-in-depth).
- SKILL.md Steps 1a/1b/1c updated to require fetch-items.js and document both
  guards.

Self-check (AC#3)
- Coverage summary printed to stderr on every run (item counts by SLA plus
  resolved and new-this-week counts).
- In-report banner + stderr WARN when any item has no valid link.

Verified end-to-end against a synthetic fixture:
- fetch-items.js exits 1 when last page has nextCursor; exits 0 when exhausted.
- merge-items.js exits 1 on unspent-cursor input.
- generate-report.js emits banner and WARN for the broken URLs, valid URLs
  still render as anchors, and no href="undefined" or href="null" appears in
  the output HTML.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@shahzaibj shahzaibj requested a review from a team as a code owner July 9, 2026 23:07
@github-actions github-actions Bot changed the title s360-reporter: fix broken item links and enforce full pagination s360-reporter: fix broken item links and enforce full pagination, Fixes AB#3683197 Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

✅ Work item link check complete. Description contains link AB#3683197 to an Azure Boards work item.

1 similar comment
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

✅ Work item link check complete. Description contains link AB#3683197 to an Azure Boards work item.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant