Skip to content

feat(career-admin): journey funnel report + tests on every PR (+ .NET 10.0.13 security pins) - #454

Closed
alanw707 wants to merge 3 commits into
mainfrom
feat/career-funnel-analytics
Closed

alanw707 wants to merge 3 commits into
mainfrom
feat/career-funnel-analytics

Conversation

@alanw707

@alanw707 alanw707 commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Summary

Two changes from the 2026-10-14 status review: (1) a way to see how far people get in the career workspace, (2) tests on every PR instead of only after merge.

1. Journey funnel (admin only, counts only)

 /admin/career-usage
+  Journey funnel            ← GET /api/admin/career/funnel?from&to
+    started (profiles created in [from,to))
+    profile → goal → occupation → brief → pay → roadmap → accepted
+      → resume → export → photo selected → photo package bought after starting
+    coming back: active on 2+ days · active again 7+ days after start · median/max active days
   Controls
   Usage by action

Derived from saved career records, not browser events: GA4 only runs after cookie consent, so a browser funnel would miss everyone who declines. Exports are counted from the usage ledger because export files expire. Sources and limits are in docs/career/api-funnel.md. scripts/career/stage3-usage.sh now pulls the funnel too, ready for the Stage 3 decision.

2. PR CI

 PR Static Analysis
   static-analysis   (build, analyzers, eslint, tsc, axe)
+  tests             dotnet test (all but Performance, #446) + Karma

Evidence

  • New CareerFunnelReportTests run against SQLite (proves the queries translate to SQL; the in-memory provider would not). Seeds 4 people: one outside the window, a pre-start purchase, a refunded purchase, a failed export. None of those may count, and all four tests pass.
  • CareerAdminFunnelEndpointTests: non-admin 403; admin 200 with no owner ids; reversed window 400.
  • Playwright career-usage.spec.ts: 12/12 pass, including the new panel and axe + 320px no-overflow on /admin/career-usage.
  • Local, CI filter: dotnet test -c Release --filter "FullyQualifiedName!~Performance" → 1381 passed, 1 skipped, 0 failed (56 s). Karma → 746/748, 2 skipped, 0 failed.
  • The new tests job on this PR is its own first run.

Merge Danger

Door: two-way. The change adds one read-only GET endpoint and one admin panel, with no schema change and no writes.

Blast Radius: admin-only. PRs take a few minutes longer to check, and a red test now blocks the merge instead of failing the deploy.

3. Fixes needed to make CI pass (third commit)

  • On 2026-10-13 Microsoft published five .NET DoS advisories on transitive packages, and they broke the restore. Pinned to the fixed 10.0.13: System.Security.Cryptography.Pkcs in the API (it comes in through SqlClient and PDFsharp). System.Security.Cryptography.Xml is pinned in the test project only, because the Web SDK API gets it from the ASP.NET Core shared framework (NU1510), so the runtime patch covers it there. Both pins should be removed once the parent packages move to 10.0.13 or later.
  • The -warnaserror analyzer step ran incrementally after the reviewdog build, so it never compiled anything and always passed. It now uses --no-incremental. That turned up 7 existing warnings in CareerSummariesExportsApiTests.cs (nullable dereferences and the obsolete PdfPig GlyphRectangle, now BoundingBox), which this commit fixes.
  • Production runtime: the deployed container uses aspnet:10.0-preview. Check that the image the deploy pulls includes the 10.0.13 servicing fix for the shared-framework copy of Xml.

CI on this PR: Static Analysis ✅, Tests (API + UI) ✅, CodeQL ✅.

…ether they come back

GET /api/admin/career/funnel (admin only, counts only) derives the funnel from saved career records:
cohort = profiles created in [from,to); steps profile → goal → occupation → brief → pay → roadmap →
accepted → resume → export → photo selected → photo package bought after starting; plus active-day returns.
Server-side so it covers users who decline analytics cookies. Shown on /admin/career-usage and pulled by
scripts/career/stage3-usage.sh. Tests: SQLite funnel math + endpoint auth/shape; Playwright panel + axe.
Tests previously ran only in Simple Deploy after the merge to main. Performance tests stay out (#446).
…ET advisories; make the -warnaserror analyzer step actually rebuild

Pkcs (GHSA-2fmv-rv2c-59x7, GHSA-846f-f764-76mx) pinned in the API (via SqlClient, PDFsharp). Xml (GHSA-7hqp-7c5m-4vq6,
GHSA-c399-9853-6jmj, GHSA-r955-8q5j-3h83) pinned in the test project only: in the Web SDK project it is in the shared
framework (NU1510). The analyzer step ran incrementally after the reviewdog build and never compiled; --no-incremental
exposed 7 existing test warnings (nullable, obsolete PdfPig GlyphRectangle), fixed here.
@alanw707 alanw707 changed the title feat(career-admin): journey funnel report + tests on every PR feat(career-admin): journey funnel report + tests on every PR (+ .NET 10.0.13 security pins) Oct 15, 2026
@alanw707

Copy link
Copy Markdown
Owner Author

Closing: the service was shut down on 2026-10-21 (see docs/operations/SHUTDOWN-CHECKLIST.md). The branch is kept for reference.

@alanw707 alanw707 closed this Oct 22, 2026
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