Skip to content

feat(scheduler): Clinical Scheduler audit trail + inline per-week history#236

Open
rlorenzo wants to merge 9 commits into
mainfrom
feature/clinical-scheduler-audit-log
Open

feat(scheduler): Clinical Scheduler audit trail + inline per-week history#236
rlorenzo wants to merge 9 commits into
mainfrom
feature/clinical-scheduler-audit-log

Conversation

@rlorenzo

@rlorenzo rlorenzo commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Surfaces the clinical schedule-change audit data VIPER already records, replacing the legacy ColdFusion "Schedule Changes Audit log". Everything is gated on SVMSecure.ClnSched.Manage, the same permission the legacy page used, so no new permission is introduced.

  • Audit Trail page: filterable read of the ScheduleAudit table (grad year, term, rotation, area, modified-by, person, date range) with colored action badges.
  • Inline per-week audit trail: a clock icon on each week in Schedule-by-Rotation / Schedule-by-Clinician opens that week's audit trail (anchored popover on desktop, centered dialog on mobile).
  • Legend entry (managers): the schedule legend gains a manager-only history-icon row so managers know the per-week icon opens that week's audit trail.
  • Term column and grad-year-scoped Term filter; "Year" relabeled to "Grad Year"; every filter defaults to an explicit "All ...".
  • Responsive audit table: full table (desktop), stacked table (tablet/iPad), cards (phone), matching the Effort audit trail.
  • Effort audit parity: same "All ..." filter defaults, the free-text search moved on top of the table, and a shared AuditChangeDetail component (removes duplicated diff markup).

Activates previously-dead code (flagged by fallow)

This branch is mostly surfacing audit code that already existed but was dead, not new plumbing:

  • The ScheduleAudit table has been written on every add/remove/primary-evaluator change, but had no reader. At this branch's base the read methods (GetInstructorScheduleAuditHistoryAsync, GetRotationWeekAuditHistoryAsync) had zero callers, i.e. dead code.
  • The project's dead-code detection (the fallow tool) is exactly what flags unreferenced code like this. Rather than delete the audit read paths, this PR gives them real consumers (the audit page and inline per-week audit trail), so the recorded data is finally exercised.

@codecov-commenter

codecov-commenter commented Jun 27, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 22.53kB (1.06%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
viper-frontend-esm 2.15MB 22.53kB (1.06%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: viper-frontend-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/GenericError-*.js 17 bytes 538.55kB 0.0%
assets/TermManagement-*.js -5 bytes 52.38kB -0.01%
assets/schedule-*.js 2.34kB 52.06kB 4.71%
assets/PhotoGallery-*.js 2 bytes 36.08kB 0.01%
assets/InstructorEdit-*.js -1 bytes 28.55kB -0.0%
assets/InstructorList-*.js -2 bytes 25.92kB -0.01%
assets/effort-*.js -2 bytes 23.17kB -0.01%
assets/MultiYearReport-*.js 1 bytes 18.75kB 0.01%
assets/ClinicianScheduleView-*.js -277 bytes 18.63kB -1.46%
assets/AuditList-*.js 277 bytes 17.59kB 1.6%
assets/RotationScheduleView-*.js 225 bytes 17.2kB 1.33%
assets/AuditLogPage-*.js (New) 11.11kB 11.11kB 100.0% 🚀
assets/permission-*.js 193 bytes 9.75kB 2.02%
assets/schedule-*.css 1.76kB 8.6kB 25.82% ⚠️
assets/WebReports-*.js 5 bytes 6.37kB 0.08%
assets/UnitList-*.js 1 bytes 6.35kB 0.02%
assets/use-*.js -4.65kB 739 bytes -86.29%
assets/use-*.js (New) 5.39kB 5.39kB 100.0% 🚀
assets/use-*.js (New) 5.88kB 5.88kB 100.0% 🚀
assets/clinicalscheduler-*.js 141 bytes 1.71kB 8.99% ⚠️
assets/use-*.css (New) 115 bytes 115 bytes 100.0% 🚀

Files in assets/schedule-*.js:

  • ./src/ClinicalScheduler/components/WeekHistoryContent.vue → Total Size: 261 bytes

  • ./src/ClinicalScheduler/components/WeekCell.vue → Total Size: 231 bytes

  • ./src/ClinicalScheduler/components/WeekHistoryButton.vue → Total Size: 258 bytes

  • ./src/ClinicalScheduler/components/ScheduleLegend.vue → Total Size: 249 bytes

  • ./src/ClinicalScheduler/components/ScheduleView.vue → Total Size: 243 bytes

Files in assets/ClinicianScheduleView-*.js:

  • ./src/ClinicalScheduler/pages/ClinicianScheduleView.vue → Total Size: 265 bytes

Files in assets/AuditList-*.js:

  • ./src/Effort/components/AuditChangeDetail.vue → Total Size: 162 bytes

  • ./src/Effort/pages/AuditList.vue → Total Size: 218 bytes

Files in assets/RotationScheduleView-*.js:

  • ./src/ClinicalScheduler/pages/RotationScheduleView.vue → Total Size: 262 bytes

Files in assets/AuditLogPage-*.js:

  • ./src/ClinicalScheduler/pages/AuditLogPage.vue → Total Size: 153 bytes

  • ./src/ClinicalScheduler/components/AuditLogResultsTable.vue → Total Size: 182 bytes

Files in assets/permission-*.js:

  • ./src/ClinicalScheduler/constants/permission-messages.ts → Total Size: 1.62kB

Files in assets/use-*.js:

  • ./src/ClinicalScheduler/composables/use-audit-entries.ts → Total Size: 962 bytes

  • ./src/ClinicalScheduler/components/SchedulerNavigation.vue → Total Size: 264 bytes

  • ./src/ClinicalScheduler/services/audit-log-service.ts → Total Size: 2.6kB

  • ./src/ClinicalScheduler/utils/audit-actions.ts → Total Size: 332 bytes

Files in assets/clinicalscheduler-*.js:

  • ./src/ClinicalScheduler/router/routes.ts → Total Size: 1.59kB

@codecov-commenter

codecov-commenter commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.07182% with 396 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.45%. Comparing base (3eaecff) to head (026e8f9).

Files with missing lines Patch % Lines
...ClinicalScheduler/Services/ScheduleAuditService.cs 0.00% 190 Missing ⚠️
...alScheduler/Controllers/ScheduleAuditController.cs 0.00% 73 Missing ⚠️
...ueApp/src/ClinicalScheduler/pages/AuditLogPage.vue 62.29% 39 Missing and 7 partials ⚠️
...rc/ClinicalScheduler/services/audit-log-service.ts 19.04% 34 Missing ⚠️
...nicalScheduler/components/AuditLogResultsTable.vue 54.54% 17 Missing and 3 partials ⚠️
...cheduler/Models/DTOs/Responses/AuditLogEntryDto.cs 0.00% 15 Missing ⚠️
...ClinicalScheduler/composables/use-audit-entries.ts 68.00% 5 Missing and 3 partials ⚠️
...icalScheduler/Services/ClinicalSchedulerNavMenu.cs 0.00% 5 Missing ⚠️
...cheduler/Models/DTOs/Responses/AuditModifierDto.cs 0.00% 2 Missing ⚠️
...calScheduler/Models/DTOs/Responses/AuditTermDto.cs 0.00% 2 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #236      +/-   ##
==========================================
- Coverage   44.67%   44.45%   -0.23%     
==========================================
  Files         897      914      +17     
  Lines       51894    52580     +686     
  Branches     4869     4964      +95     
==========================================
+ Hits        23184    23372     +188     
- Misses      28130    28607     +477     
- Partials      580      601      +21     
Flag Coverage Δ
backend 44.48% <0.00%> (-0.26%) ⬇️
frontend 43.93% <57.42%> (+0.51%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Comment thread web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs Fixed
Comment thread web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs Fixed
Comment thread web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs Fixed
Comment thread web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs Fixed
@rlorenzo rlorenzo force-pushed the feature/clinical-scheduler-audit-log branch 3 times, most recently from d936116 to 3bc2ddf Compare June 29, 2026 22:49
@rlorenzo

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an end-to-end audit trail feature to the Clinical Scheduler: new C# DTOs, IScheduleAuditService methods, and ScheduleAuditController endpoints; a new AuditLogPage.vue with multi-filter UI; inline WeekHistoryButton/WeekHistoryContent components for per-week history popovers; and history prop wiring through ScheduleView/WeekCell. Also extracts AuditChangeDetail in the Effort module.

Changes

Clinical Scheduler Audit Trail

Layer / File(s) Summary
Shared audit types and DTOs
VueApp/src/ClinicalScheduler/types/audit-types.ts, VueApp/src/ClinicalScheduler/utils/audit-actions.ts, VueApp/src/ClinicalScheduler/constants/permission-messages.ts, web/Areas/ClinicalScheduler/Models/DTOs/Responses/Audit*.cs
Defines AuditLogEntry, AuditModifier, AuditTerm TS interfaces; getAuditActionColor utility; AUDIT_LOG permission message keys; and three C# DTOs (AuditLogEntryDto, AuditModifierDto, AuditTermDto).
Backend service interface and implementation
web/Areas/ClinicalScheduler/Services/IScheduleAuditService.cs, web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs
Extends IScheduleAuditService with six new methods; implements them in ScheduleAuditService using EF left-joins to Weeks, Rotations, and Persons, optional filter application, 2500-row cap, TermCodeService post-enrichment, and shared BuildEnrichedAuditQuery projection.
Backend controller and nav
web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs, web/Areas/ClinicalScheduler/Services/ClinicalSchedulerNavMenu.cs
Adds ScheduleAuditController with six GET endpoints gated by Manage permission, input validation, and 500/400 error handling; appends "Audit Trail" to the server-side nav menu when hasManage is true.
Frontend AuditLogService
VueApp/src/ClinicalScheduler/services/audit-log-service.ts
Static service with buildUrl helper and six methods matching backend endpoints, each using useFetch().get and converting errors to a standardized ApiResult failure shape.
AuditLogPage, route, and nav tab
VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue, VueApp/src/ClinicalScheduler/router/routes.ts, VueApp/src/ClinicalScheduler/components/SchedulerNavigation.vue, VueApp/src/ClinicalScheduler/__tests__/audit-log-page-access.test.ts
Full audit trail page with expandable filter panel, three responsive table layouts (desktop/tablet/mobile), debounced watchers, permission-gated initialization; new /ClinicalScheduler/audit route; conditionally rendered "Audit Trail" nav tab; access-control tests.
WeekHistoryButton and WeekHistoryContent
VueApp/src/ClinicalScheduler/components/WeekHistoryButton.vue, VueApp/src/ClinicalScheduler/components/WeekHistoryContent.vue
WeekHistoryButton lazy-loads history via AuditLogService and renders desktop popover or mobile dialog. WeekHistoryContent displays loading skeleton, error/retry, empty state, or scrollable entry list with StatusBadge and formatted timestamps.
WeekCell, ScheduleView, ScheduleLegend, and schedule view pages wiring
VueApp/src/ClinicalScheduler/components/WeekCell.vue, VueApp/src/ClinicalScheduler/components/ScheduleView.vue, VueApp/src/ClinicalScheduler/components/ScheduleLegend.vue, VueApp/src/ClinicalScheduler/pages/ClinicianScheduleView.vue, VueApp/src/ClinicalScheduler/pages/RotationScheduleView.vue
Adds canViewHistory/historyContextId/historyContextLabel props through the component chain; WeekCell conditionally renders WeekHistoryButton and adds originatesOnControl click guard; ScheduleLegend gains optional showHistory entry; mobile style overrides added.

Effort AuditChangeDetail Refactor

Layer / File(s) Summary
AuditChangeDetail component and AuditList updates
VueApp/src/Effort/components/AuditChangeDetail.vue, VueApp/src/Effort/pages/AuditList.vue
Extracts old→new value diff rendering into AuditChangeDetail; tablet/mobile views in AuditList delegate to this component; search input moved above the results table; filter dropdowns gain "All …" display text for null values.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant AuditLogPage
    participant AuditLogService
    participant ScheduleAuditController
    participant ScheduleAuditService

    Browser->>AuditLogPage: mount
    AuditLogPage->>ScheduleAuditController: GET /audit (year, filters)
    ScheduleAuditController->>ScheduleAuditService: GetAuditLogAsync(gradYear, filters)
    ScheduleAuditService-->>ScheduleAuditController: List<AuditLogEntryDto>
    ScheduleAuditController-->>AuditLogPage: 200 OK entries
    AuditLogPage-->>Browser: render responsive table

    Browser->>AuditLogPage: click WeekHistoryButton in WeekCell
    AuditLogPage->>AuditLogService: getRotationWeekHistory(rotationId, weekId)
    AuditLogService->>ScheduleAuditController: GET /audit/rotation-week
    ScheduleAuditController->>ScheduleAuditService: GetRotationWeekAuditAsync
    ScheduleAuditService-->>ScheduleAuditController: List<AuditLogEntryDto>
    ScheduleAuditController-->>AuditLogService: 200 OK entries
    AuditLogService-->>AuditLogPage: ApiResult
    AuditLogPage-->>Browser: render WeekHistoryContent popover/dialog
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ucdavis/VIPER#177: Modifies permission-messages.ts exported surface; this PR adds AUDIT_LOG keys to that same file.

Suggested reviewers

  • bsedwards
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: a clinical scheduler audit trail with inline per-week history.
Description check ✅ Passed The description is directly related to the audit trail and inline history changes in the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/clinical-scheduler-audit-log

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@VueApp/src/ClinicalScheduler/components/WeekHistoryButton.vue`:
- Around line 97-114: Refactor loadHistory in WeekHistoryButton.vue to satisfy
the quality gate by breaking the logic into small helpers instead of keeping the
fetch selection and result/error handling inline. Extract one helper to choose
the correct AuditLogService call based on props.viewMode and another to
normalize successful and failed responses/errors into entries.value and
error.value. Keep loadHistory focused on toggling isLoading and orchestrating
these helpers so the method stays simple and readable.

In `@VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue`:
- Around line 54-60: The AuditLogPage.vue filters expansion item is using an
inline desktop visibility style, which violates the Vue styling rules in this
repo. Update the q-expansion-item in AuditLogPage to remove the :header-style
binding and use Quasar utility classes or separate mobile/desktop filter header
containers instead, keeping the same behavior while avoiding inline styles.
- Around line 570-578: The clearFilters function in AuditLogPage.vue does not
fully reset the page because currentYear is left unchanged, so the year-scoped
data and term list remain filtered. Update clearFilters to also reset
currentYear and reuse the same refresh path as onYearChange() so the
year-specific term list and audit log state are restored consistently when
clearing filters.
- Around line 484-510: loadAuditTrail() in AuditLogPage.vue is too complex and
needs to be split up to pass the Fallow gate. Extract the
AuditLogService.getAuditLog filter construction into a helper and move the
success/error response handling into a separate helper so loadAuditTrail() stays
a simple linear fetch flow. Keep the existing behavior intact while reducing the
branching inside loadAuditTrail(), and use the current symbols like currentYear,
selectedTermCode, selectedRotationId, selectedArea, selectedModifier,
selectedPerson, fromDate, toDate, and AuditLogService.getAuditLog to organize
the refactor.
- Around line 484-515: `loadAuditTrail()` can resolve out of order and overwrite
newer filter results in `AuditLogPage.vue`. Add a request guard in
`loadAuditTrail` (for example, a monotonically increasing request id or
cancellation token) so only the latest invocation is allowed to set
`entries.value`, `error.value`, and `isLoading.value`. Make sure the debounced
loader and any other callers still invoke `loadAuditTrail`, but stale responses
are ignored before committing state.

In `@VueApp/src/Effort/components/AuditChangeDetail.vue`:
- Line 3: Remove the narration comments from AuditChangeDetail’s template
branches; they just restate the conditional rendering and add noise. Update the
Vue template around the inline reference-value and changed-value sections by
deleting the explanatory comments, while keeping the existing branch logic and
structure in place.

In `@VueApp/src/Effort/pages/AuditList.vue`:
- Around line 152-167: The search input in AuditList.vue currently relies only
on placeholder text, so it loses its visible name after typing. Update the
q-input used for filter.searchText to include a persistent label while keeping
the existing placeholder as hint text, using the existing search field markup
and v-model binding to locate it.

In `@web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs`:
- Around line 141-187: The week-history endpoints in ScheduleAuditController
return List<AuditLogEntryDto> even though
ScheduleAuditService.BuildEnrichedAuditQuery(...) does not populate required
fields such as WeekNum and Term. Update the projection used by
GetRotationWeekHistory and GetClinicianWeekHistory to fully populate
AuditLogEntryDto, or switch those actions to a narrower DTO that only includes
the fields actually returned. Ensure the response contract matches the frontend
AuditLogEntry expectations.
- Around line 15-18: The ScheduleAuditController route is using a hardcoded
nonstandard path, so update the route attribute on ScheduleAuditController to
follow the repo’s controller-based API convention. Replace the current fixed
audit route with the standard absolute /api/{area}/{controller} pattern so the
controller resolves through its name instead of a custom endpoint.
- Around line 31-41: The XML documentation for ScheduleAuditController’s
GetAuditLogAsync contract is misleading about the person filter. Update the
<param name="person"> comment so it clearly states this parameter is a MothraID
exact match, not a substring search on display name. Keep the docs aligned with
the behavior in IScheduleAuditService.GetAuditLogAsync and
ScheduleAuditService.GetAuditLogAsync, and adjust any related wording in the
controller summary if needed.

In `@web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs`:
- Around line 388-401: The week-history projection in ScheduleAuditService’s
audit query is returning AuditLogEntryDto without setting WeekNum, TermCode, or
Term, which leaves those members at default values and makes the shared DTO
inconsistent across endpoints. Update the select new AuditLogEntryDto in the
GetRotationWeekAuditAsync/GetClinicianWeekAuditAsync query to populate those
fields from the available week-related data, or introduce a separate DTO for
week history and use it there instead of reusing AuditLogEntryDto.
- Around line 237-240: Replace the filtered catch in ScheduleAuditService with
explicit typed handlers so each failure type is handled separately. Update the
exception handling around the audit retrieval logic in the relevant service
method to use distinct catch blocks for DbUpdateException, SqlException, and
InvalidOperationException instead of a single `catch (Exception) when (...)`,
and keep the existing logging/throw behavior in each branch using the same
logger message pattern and the method context around `gradYear`.
🪄 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: a18a5a59-93d9-4808-80e7-38949f8f10db

📥 Commits

Reviewing files that changed from the base of the PR and between 4564dae and 3bc2ddf.

📒 Files selected for processing (24)
  • VueApp/src/ClinicalScheduler/__tests__/audit-log-page-access.test.ts
  • VueApp/src/ClinicalScheduler/components/ScheduleLegend.vue
  • VueApp/src/ClinicalScheduler/components/ScheduleView.vue
  • VueApp/src/ClinicalScheduler/components/SchedulerNavigation.vue
  • VueApp/src/ClinicalScheduler/components/WeekCell.vue
  • VueApp/src/ClinicalScheduler/components/WeekHistoryButton.vue
  • VueApp/src/ClinicalScheduler/components/WeekHistoryContent.vue
  • VueApp/src/ClinicalScheduler/constants/permission-messages.ts
  • VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue
  • VueApp/src/ClinicalScheduler/pages/ClinicianScheduleView.vue
  • VueApp/src/ClinicalScheduler/pages/RotationScheduleView.vue
  • VueApp/src/ClinicalScheduler/router/routes.ts
  • VueApp/src/ClinicalScheduler/services/audit-log-service.ts
  • VueApp/src/ClinicalScheduler/types/audit-types.ts
  • VueApp/src/ClinicalScheduler/utils/audit-actions.ts
  • VueApp/src/Effort/components/AuditChangeDetail.vue
  • VueApp/src/Effort/pages/AuditList.vue
  • web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs
  • web/Areas/ClinicalScheduler/Models/DTOs/Responses/AuditLogEntryDto.cs
  • web/Areas/ClinicalScheduler/Models/DTOs/Responses/AuditModifierDto.cs
  • web/Areas/ClinicalScheduler/Models/DTOs/Responses/AuditTermDto.cs
  • web/Areas/ClinicalScheduler/Services/ClinicalSchedulerNavMenu.cs
  • web/Areas/ClinicalScheduler/Services/IScheduleAuditService.cs
  • web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs

Comment thread VueApp/src/ClinicalScheduler/components/WeekHistoryButton.vue Outdated
Comment thread VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue
Comment thread VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue Outdated
Comment thread VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue
Comment thread VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue
Comment thread web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs
Comment thread web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs
Comment thread web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs
Comment thread web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs
Comment thread web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs
@rlorenzo rlorenzo force-pushed the feature/clinical-scheduler-audit-log branch from 3bc2ddf to b8e1cd4 Compare June 30, 2026 05:39
@rlorenzo rlorenzo requested a review from Copilot July 3, 2026 02:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Surfaces and productizes existing Clinical Scheduler audit data by adding a manager-gated audit-log API + UI (full page and inline per-week history), replacing the legacy ColdFusion “Schedule Changes Audit log”.

Changes:

  • Added new Clinical Scheduler audit endpoints (/api/clinicalscheduler/audit/*) and service methods returning enriched, filterable audit DTOs.
  • Added new Vue Audit Trail page + routing/navigation, plus inline per-week history popover/dialog for managers.
  • Refactored Effort audit list change-detail rendering into a shared AuditChangeDetail component and adjusted filter UX defaults.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
web/Areas/ClinicalScheduler/Services/ScheduleAuditService.cs Adds enriched audit-log query methods (filters, term mapping, per-week history projections).
web/Areas/ClinicalScheduler/Services/IScheduleAuditService.cs Extends the service contract to include audit-log, term, modifier/person, and per-week history methods.
web/Areas/ClinicalScheduler/Services/ClinicalSchedulerNavMenu.cs Adds “Audit Trail” nav item for users with Manage permission.
web/Areas/ClinicalScheduler/Models/DTOs/Responses/AuditTermDto.cs New DTO for term filter options scoped to grad year.
web/Areas/ClinicalScheduler/Models/DTOs/Responses/AuditModifierDto.cs New DTO for “Modified By” / “Person” filter options.
web/Areas/ClinicalScheduler/Models/DTOs/Responses/AuditLogEntryDto.cs New enriched audit row DTO used by page + inline week history.
web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs New API controller exposing audit-log/filter endpoints and per-week history endpoints (Manage-gated).
VueApp/src/Effort/pages/AuditList.vue Improves filter defaults/UX and uses shared change-detail component.
VueApp/src/Effort/components/AuditChangeDetail.vue New shared renderer for change-detail old/new values.
VueApp/src/ClinicalScheduler/utils/audit-actions.ts Shared mapping from schedule-audit action → Quasar color.
VueApp/src/ClinicalScheduler/types/audit-types.ts New TS types for schedule audit rows and filter option DTOs.
VueApp/src/ClinicalScheduler/services/audit-log-service.ts New frontend service for Clinical Scheduler audit endpoints.
VueApp/src/ClinicalScheduler/router/routes.ts Adds route for the new Audit Trail page.
VueApp/src/ClinicalScheduler/pages/RotationScheduleView.vue Plumbs “can view history” + context info into the schedule grid.
VueApp/src/ClinicalScheduler/pages/ClinicianScheduleView.vue Plumbs “can view history” + context info into the schedule grid.
VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue New Audit Trail page with responsive results display and filter controls.
VueApp/src/ClinicalScheduler/constants/permission-messages.ts Adds access-denied messaging for the new audit trail feature.
VueApp/src/ClinicalScheduler/composables/use-audit-entries.ts Shared loader/state composable for audit entries (page + inline history).
VueApp/src/ClinicalScheduler/components/WeekHistoryContent.vue New reusable content component for per-week audit history UI.
VueApp/src/ClinicalScheduler/components/WeekHistoryButton.vue New trigger button that shows per-week history (popover on desktop, dialog on mobile).
VueApp/src/ClinicalScheduler/components/WeekCell.vue Adds per-week history icon and prevents cell actions when tapping embedded controls.
VueApp/src/ClinicalScheduler/components/ScheduleView.vue Plumbs history props through to week cells and legend; minor export cleanup + mobile layout tweak.
VueApp/src/ClinicalScheduler/components/SchedulerNavigation.vue Adds “Audit Trail” tab for managers.
VueApp/src/ClinicalScheduler/components/ScheduleLegend.vue Adds manager-only legend row describing the history icon.
VueApp/src/ClinicalScheduler/tests/audit-log-page-access.test.ts Adds access-control tests for the audit-log page behavior.

Comment thread web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs Outdated
@rlorenzo rlorenzo force-pushed the feature/clinical-scheduler-audit-log branch from b8e1cd4 to 4f6cd6d Compare July 3, 2026 02:41
rlorenzo added 6 commits July 2, 2026 19:58
Replace the legacy ColdFusion "Schedule Changes Audit log" with a filterable audit trail (year, rotation, area, modified-by, person, date range) and colored action badges, matching the Effort audit trail UI. Reachable from a left-nav link and in-page tab gated on SVMSecure.ClnSched.Manage.

The ScheduleAudit table was already written on every add/remove/primary-evaluator change but had no reader; this surfaces that data, so the audit read paths are no longer dead code.
Surfaces the schedule-change audit data in more places and rounds out
the audit trail page:

- Inline per-week change-history popover (centered dialog on mobile) on
  each week in Schedule-by-Rotation / Schedule-by-Clinician, gated on
  SVMSecure.ClnSched.Manage, backed by new per-week audit endpoints.
- Audit trail: Term column and grad-year-scoped Term filter, "Year"
  relabeled to "Grad Year", and an explicit "All ..." default on every
  filter.
- Responsive audit table: full table on desktop, a stacked table on
  tablet/iPad, and cards on phones, matching the Effort audit trail.
- Fix a mobile bug where tapping an in-cell control (history, remove,
  primary toggle) also fired the cell's tap-to-schedule, and validate
  the per-week endpoint parameters.
- Default every filter to an explicit "All ..." state and move the
  free-text search to a bar on top of the results table.
- Extract a shared AuditChangeDetail component, removing the duplicated
  old-to-new diff markup in the desktop and mobile views.
Replace .HasValue/.Value with "is T x" pattern matching on the audit-log
filter params (rotation, term, from/to dates) so the code-quality
analyzer stops flagging the guarded .Value access as a possible null
dereference. No behavior change.
The per-week change-history clock icon now has a key in the schedule
"Quick Guide" legend, shown only when the user can view history
(SVMSecure.ClnSched.Manage), so the icon is explained for the people
who can use it.
@rlorenzo rlorenzo force-pushed the feature/clinical-scheduler-audit-log branch from 4f6cd6d to 15d53b4 Compare July 3, 2026 03:00
- main's fallow 2.101 bump tightened the template complexity gate,
  failing CI on the audit page and two uncovered new components
- extract the responsive results tables into AuditLogResultsTable and
  compute responsive classes once so templates stay branch-free
- cover WeekHistoryContent, AuditChangeDetail, and the new table with
  component tests

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 3 comments.

Comment thread web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs
Comment thread web/Areas/ClinicalScheduler/Controllers/ScheduleAuditController.cs
Comment thread VueApp/src/ClinicalScheduler/pages/AuditLogPage.vue Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

@rlorenzo rlorenzo requested a review from bsedwards July 3, 2026 05:04
@rlorenzo

rlorenzo commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@bsedwards Should be on TEST now. Adds audit trail inline on the weeks display as well as a dedicated page

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.

3 participants