Skip to content

feat(supervisor): phase 7e — call-type and distribution reports (server-side XLSX) - #12

Open
Madhav2402 wants to merge 2 commits into
feat/phase7d-allocationfrom
feat/phase7e-reports
Open

feat(supervisor): phase 7e — call-type and distribution reports (server-side XLSX)#12
Madhav2402 wants to merge 2 commits into
feat/phase7d-allocationfrom
feat/phase7e-reports

Conversation

@Madhav2402

Copy link
Copy Markdown
Contributor

📋 Description


✅ Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • New feature (non-breaking change which adds functionality)
  • 🔥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🛠 Refactor (change that is neither a fix nor a new feature)
  • ⚙️ Config change (configuration file or build script updates)
  • 📚 Documentation (updates to docs or readme)
  • 🧪 Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • 🚀 Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

What's in this PR

ReportsApiService + shared helpers

  • downloadReport(path, body): Observable<Blob> (responseType: 'blob'). The old ReportsService bypassed its interceptors with a construction-time token (a stale-token bug); ours goes through the normal chain — the response interceptor passes non-envelope bodies (blobs) through untouched.
  • getCallTypes() posts call/getCallTypesV1 with the report's plain body (no campaign flags — the report flavor).
  • Shared helpers so the two components can't drift: maxReportDay() (yesterday, native [max]), clampReportEnd(start) (old endDateChange cap), reportDatesValidator(), and saveBlob().

Call Type Report (case 9)

  • Call-type group → sub-type cascade + demographic filters (state→district, gender, language, sexual-orientation) → crmReports/getAllReportsByDate, filename Call_Type_Report.
  • Old payload ended the window at .999Z (unlike the distribution reports) — kept.

Distribution reports (cases 15–18, one config component)

  • REPORTS config maps each kind → {title, path, fileName, options, dimension}: age (getAllByAgeGroup, hardcoded buckets, All→nulls+"All"), gender (getAllByGender), language (getCountsByPreferredLanguage), sexual-orientation (getAllBySexualOrientation).
  • Day-boundary payload (dayBoundary(localDate(v.startDate), 'start'|'end')), state=stateName, undefined keys dropped, 500 → "No data found".

Date policy (byte-faithful to old maxStartDate / endDateChange)

  • Reports run up to yesterday; picking a start ≥31 days before yesterday caps the window to start+30 days (auto-fills the end date and tightens its [max]).

Review fixes included in this PR (from the high-effort code review)

  1. zValueChange fires before the CVA writes the FormControl — every cascading handler now reads the emitted $event value instead of form.controls.X.value (was reading the previous selection: first pick loaded nothing, second pick loaded the prior selection's children). Same root-cause fix landed on the allocation selects in feat(supervisor): phase 7d — outbound allocation and reallocation suite (generic, grievance, everwell) #11 and the call-flow selects in feat(outbound): phase 7c — outbound worklist hub, dial hand-offs and outbound call loop #10.
  2. 31-day cap off-by-one — old app capped at "≥31 days before yesterday"; corrected to spanDays > 30 so a start exactly 31 days before yesterday no longer produces a 32-day window.
  3. End-date [max] now tightened to start+30 after a cap (was left at yesterday, letting a manual re-pick exceed the window).
  4. Native date [max] doesn't feed reactive-form validity (unlike the old md2-datepicker) — added reportDatesValidator so a typed out-of-range date disables Download.
  5. Age buckets set unconditionally in ngOnInit (old caller-age-report hardcoded them) — the report is usable even if getRegistrationDataV1 fails.
  6. Old stale-sub-type quirk restored — switching call type no longer clears a chosen sub-type (old getCallSubType left it in the payload).
  7. getDistricts errors alerted with err.errorMessage (old GetDistricts), no longer silently swallowed.
  8. saveBlob defers revokeObjectURL (FileSaver parity, avoids aborting the download); duplicated date/clamp logic pulled into shared helpers; callTypeGroups is a signal + computed (zoneless guardrail).

Verification (live, 1097Supervisor)

  • Real server-produced XLSX downloaded end-to-end (getAllByAgeGroup 200 → valid PK-magic .xlsx); payloads byte-faithful across all five report pages with real master data.
  • Date rules verified in-browser (yesterday cap; 31-day boundary on both sides; typed future date disables Download).
  • Select cascades re-verified with real dropdown clicks (not programmatic patches): call-type → sub-types and state → districts both resolve on the first pick.
  • ng build clean, tsc clean, GPL header check passing.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ac5fe4c0-4d07-48ed-97fa-d36bc39095fe

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

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