Changelog

Release notes and runtime details.

System info
app name
ImagingOverreads
rails version
7.2.2.2
ruby version
3.3.9
ruby platform
x86_64-linux
environment
production
rad env
production
site url
imaging-overreads.radiology.wisc.edu
current time
2026-04-19 14:31:05 -0500
Release notes
## [v2.4.6] — 2026-04-16
### Fix
- **MSK Prior Exam** - Fix bug caused from sorting prior exams

## [v2.4.5] — 2026-04-15

### Added
- **MSK Visit Enhancements** — expanded visit-level data capture to include additional anatomy context, improved protocol/procedure tracking, and richer attachment handling for each visit.
- **Abnormal Follow-up Workflow Improvements** — enhanced follow-up resolution flow with clearer separation of abnormal findings, required follow-up actions, and resolution tracking.

### Changed
- **MSK Exam & Visit UI Redesign** — significantly refactored exam show page, visit accordion, and supporting panels (summary, pain, protocol, artifacts, attachments) for improved readability, consistency, and workflow clarity.
- **Visit Status & Badge System** — standardized status indicators (Open, On Hold, Follow-up Needed, Resolved, Overdue) across visit headers and detail views for more intuitive at-a-glance understanding.
- **Prior Exam Matching & Display** — improved prior exam lookup and presentation, including more reliable sorting by scan date and enhanced contextual display of prior exam metadata.

### Fixed
- **Prior Exam Sorting Error** — resolved database error caused by ordering on `last_scan_date` without proper query aliasing, ensuring stable prior exam queries and display.

## [v2.4.4] — 2026-04-13

### Added
- **Abdominal Program Scaffold** — introduced initial Abdominal program section with routing, landing page, and placeholder workspace structure to support future workflow expansion.
- **Homepage Program Expansion** — added Abdominal as a third program option on the Imaging Overreads homepage alongside Neuro and MSK.

### Changed
- **Homepage Redesign** — refactored the program selection homepage with updated layout, styling, and clearer separation of program workspaces.
- **Program Status Messaging** — improved user guidance by explicitly labeling Abdominal as “Under Construction” and not yet available for use.

### Notes
- Abdominal workflows, intake, and reporting features are still in progress and not yet active in production.

## [v2.4.3] — 2026-03-04
### Changed
- **Role Request Flow Refactor** — simplified `UsersController#request_role` by normalizing incoming role parameters, making `program` optional (admin excluded), and centralizing program-required logic.
- **Role Request Email Simplification** — refactored `UserMailer#request_role_email` to infer `requested_role` directly from the user and accept an optional `program:` keyword argument. Updated HTML and text templates to inline role-label formatting.
- **Enum Modernization (Rails 8 Ready)** — converted all enum definitions to positional syntax (`enum :field, {...}`) and replaced deprecated `_prefix` / `_suffix` options with `prefix:` / `suffix:` to remove Rails 7.2 deprecation warnings and ensure forward compatibility.

### Fixed
- **Pending Role Removal (Admin)** — corrected checkbox handling (`"1"` vs `"true"`) so admins can properly clear a user’s `requested_role`, including associated `coordinator_request` cleanup.
- **User Form Checkbox Error** — resolved `wrong number of arguments (given 5, expected 1..4)` by correcting `form.check_box` argument ordering.
- **Enum Option Error** — resolved `invalid option(s): :_prefix` by aligning enum options with Rails 7.2+ API.

### Notes
- No database migrations were required.

## [v2.4.2] — 2026-02-27
- update documentation

## [v2.4.1] — 2026-02-25

### Added
- **MSK Bi-Weekly Reader Report (Mon/Thu 6am)** — introduced an automated email report for the MSK program, delivered every Monday and Thursday at 6:00am to all active MSK readers.
- **Unread Exam Definition Standardization** — defined an “Unread MSK Exam” as `resolved_at: nil` with at least one associated visit where `resolved_at: nil`, ensuring alignment with current resolution semantics.

### Notes
- No database migrations were required.

### Deployment / Cron Setup

After deploying to staging or production, ensure the following host-level cron entry exists:
- ```docker exec dockerradweb_imaging-overreads_1 bundle exec rake msk_reports:send_monday_thursday_reader_report RAILS_ENV=production```
- ```crontab -e```
- ```0 6 * * 1,4 docker exec dockerradweb_imaging-overreads_1 bundle exec rake msk_reports:send_monday_thursday_reader_report RAILS_ENV=production >> /var/log/msk_reader_report.log 2>&1```

## [v2.4.0] — 2026-02-18

### Added
- **MSK Visit Read Window Selection** — added 30-day, 60-day, and Custom Date options for `msk_exam_visits.due_date`, including nested support when creating the first visit directly from the MSK exam form.
- **Server-Side Due Date Enforcement** — implemented model-level handling of `due_date_option` to ensure consistent behavior whether visits are created via nested exam creation or through the standalone visit controller.

### Changed
- **Resolution Model Simplification** — completed transition away from legacy `closed_by_rule` semantics and standardized resolution state on `resolved_at`, aligning exam and visit state logic.
- **Status Badge Accuracy** — updated exam status evaluation to rely strictly on unresolved visits and abnormal findings, preventing premature “Resolved” labeling.
- **Nested Visit Parameter Handling** — hardened `visits_attributes` permitting to ensure due date and resolution-related fields behave consistently across create and update flows.

### Notes
- This release strengthens the MSK workflow by consolidating resolution logic and ensuring due date rules behave predictably in both nested and standalone contexts.
- No database migrations were required; updates are limited to model callbacks, controllers, and form/UI behavior.

## [v2.3.11] — 2026-02-09
### Added
- **MSK Exam Search: Pain Subject Filter** — added support for filtering exams where `pain_subject` is true, including full visibility in the search summary and removable filter chips.
- **MSK Exam Search: Procedure Type Filter** — added enum-based filtering for procedure type (`joint_replacement`, `joint_arthroscopy`, `other`), with human-readable labels in the search UI and summary.

### Fixed
- **Search Summary Status Mismatch** — corrected the search summary helper to align with the current `resolved_at_null` / `resolved_at_not_null` filters, restoring accurate “Open only” and “Resolved only” indicators.
- **Legacy Filter Compatibility** — preserved backward compatibility for older `open_by_rule` / `closed_by_rule` parameters to avoid breaking existing links or bookmarks.

### Changed
- **Search Helper Hardening** — centralized and standardized MSK exam search criteria generation to ensure all active filters (status, abnormal flags, pain subject, procedure type, and sort order) are consistently reflected in the UI.
- **Improved Filter Transparency** — enhanced the “Search summary” panel so newly added and recently refactored filters are clearly visible and individually removable.

### Notes
- This update keeps the MSK search experience in sync with recent model and workflow changes, reducing confusion when combining multiple filters.
- No database migrations were required; changes are limited to search behavior, helpers, and UI.

## [v2.3.10] — 2026-02-06
### Fixed
- **MSK Exam Close Override Routing** — corrected the exam-level resolve endpoint to no longer require a visit ID, preventing `RecordNotFound` errors when manually closing an exam.
- **Controller Responsibility Separation** — clarified the boundary between exam-level resolution (`Msk::ExamsController`) and visit-level resolution (`Msk::ExamVisitsController`), eliminating accidental cross-dependencies.

### Changed
- **Explicit Exam Close Semantics** — aligned the “Close Exam (Override)” action with true exam-level state changes, independent of visit resolution logic.
- **Improved Resolution Consistency** — ensured visit resolution continues to drive automatic exam closure where appropriate, while allowing safe manual overrides when visits cannot be completed.

### Notes
- This change hardens the MSK resolution workflow by enforcing clear ownership of state transitions at the exam vs visit level.
- No data migrations were required; existing exams and visits continue to behave correctly under the updated logic.

## [v2.3.9] — 2026-02-05

### Added
- **Rule-Based MSK Exam Resolution** — exams now automatically resolve when the number of resolved visits meets the expected visit count, with support for manual override when visits cannot be completed.
- **Resolved Exam Status Banner** — added a prominent banner on the MSK exam page showing resolution status, closure reason (by rule vs override), timestamps, and visit counts.
- **MSK Abnormal Finding Notifications** — implemented email notifications for abnormal findings requiring follow-up to ensure timely visibility.

### Changed
- **MSK Visit Resolution Workflow** — split visit resolution into clear, explicit paths for normal findings, abnormal findings without follow-up, and abnormal findings requiring follow-up.
- **MSK Exam Show Page Refinements** — reorganized exam and visit UI for clarity, including consolidated visit metrics, cleaner accordions, and better placement of secondary actions.
- **Automatic Exam Reopen Logic** — reopening a resolved visit now automatically reopens the associated exam to maintain state consistency.

### Notes
- Exam state is now driven by visit state and expected visit rules rather than derived flags, simplifying resolution logic.
- These changes improve auditability, reduce ambiguity in MSK workflows, and lay groundwork for future reporting enhancements.

## [v2.3.8] — 2026-01-27
### Changed
- **MSK Joint & Laterality Data Relocation** — moved joint-related fields (joint, laterality, and related context) from the MSK study level down to the MSK exam level, aligning the data model with real-world exam-specific anatomy.
- **MSK Exam Form Updates** — updated MSK exam create/edit forms to capture joint and laterality information directly on the exam, ensuring clearer data entry and reducing ambiguity across visits.
- **View Refactors for Exam Context** — adjusted MSK exam and visit views to reference joint data from the exam instead of the study, maintaining consistent display across dashboards, show pages, and visit accordions.

### Notes
- This change improves data accuracy by scoping joint and laterality to the exam where they belong, rather than sharing them across an entire study.
- No historical data was altered; existing exams continue to render correctly using the updated associations.
- This refactor lays groundwork for more flexible MSK exam workflows where joint context may vary between exams within the same study.

## [v2.3.7] — 2026-01-27
### UI / UX
- **MSK Exam Visit Accordion Redesign** — refactored the MSK exam visit accordion layout to use a consistent, card-based presentation across all sections, improving visual hierarchy and readability.
- **Patient Feedback Card Alignment** — updated patient feedback to follow the same card header/body pattern as other visit sections for visual consistency.
- **Attachment Display Improvements** — aligned exam visit attachment presentation with the unified card design, improving scanability and action placement (view/download).

### Notes
- These changes are visual and structural only; no data model or workflow behavior was altered.
- The refactor improves long-term maintainability by applying a consistent UI pattern across MSK visit components.

## [v2.3.6] — 2026-01-14
### Infrastructure
- **Rails Framework Upgrade** — upgraded the application from **Rails 7.1.3.4 to Rails 7.2.2.2**, bringing in the latest framework fixes, performance improvements, and security updates.
- **Ruby Runtime Upgrade** — updated the application runtime to **Ruby 3.3.9**, ensuring compatibility with Rails 7.2 and aligning with current Ruby support recommendations.
- **Docker Build Hardening** — improved the Docker build process by pinning the Bundler version, validating the Ruby runtime at build time, and leveraging layer caching for faster and more reliable image builds.
- **Bundler & Dependency Alignment** — refreshed the `Gemfile.lock` to resolve legacy 7.1.x pins, aligning all Rails components (`activesupport`, `actionpack`, etc.) with Rails 7.2.
- **Production Asset Pipeline Stability** — verified successful asset precompilation and runtime behavior under the updated Rails/Ruby stack using the existing subpath deployment (`/a/imaging-overreads`).

### Notes
- No functional user-facing changes were introduced as part of this upgrade.
- Existing workflows and deployment commands (`docker-compose down` / `up`) continue to operate as before.

## [v2.3.5] — 2026-01-11
### Fixes
- **Program-Aware User Creation & Role Assignment** — fixed errors when creating Coordinators or Principal Investigators from study pages or program home pages by unifying program detection through the `ProgramScoped` concern.
- **Namespaced Study Redirects** — resolved invalid `edit_study_path` usage by routing correctly to MSK (`edit_msk_study_path`) or Neuro (`edit_program_study_path`) study edit pages based on context.
- **MSK PI Selection Logic** — updated MSK study forms to list all active users with the **MSK Principal Investigator** role, rather than only users already assigned as PIs on existing studies.

## [v2.3.4] — 2025-12-30
### Fixes
- **Improve** - homepage improvements to queue for neuro 

## [v2.3.3] — 2025-12-30
### Added
- **Neuro Dashboard Queue Panels** — replaced the legacy Neuro “Stats” section with MSK-style queue panels on the Neuro Control Center for improved operational visibility.
- **On Hold Exams Queue (Neuro)** — added a dashboard queue highlighting exams that currently have an active hold, including hold reason and quick navigation to exam details.
- **Dedicated “On Hold Exams” Listing** — added a new Neuro exams collection route and controller action to display all exams currently on hold (all-time), reusing the shared exams table with full sorting support.

## [v2.3.2] — 2025-12-30
### Added
- **MSK “Due Soon” Dashboard Panel** — added a new table on the MSK welcome page that highlights visits with due dates approaching the overdue window (showing items due within the next 15 days).
- **Rule-Based Due Date Logic (30/60 Days)** — implemented MSK follow-up due dates based on scan date using the program rule: **30 days for pain subjects with a joint replacement; otherwise 60 days**.
- **Days Remaining Indicator** — added a “Days Left” column to clearly show time remaining until a visit becomes overdue.

## [v2.3.1] — 2025-12-23
### Added
- **Exam Number Field for MSK Visits** — introduced a new `exam_number` attribute on `msk_exam_visits`, including form support so users can record site- or PACS-specific exam identifiers.
- **Expanded MSK Study Information on Exam Pages** — enhanced the MSK exam show page to display additional study metadata, including IRB number, PI, default reader, active status, and date added.
- **Joint & Laterality Context** — added clear display of joint, laterality, and “other joint” details in the exam information section for improved clinical context.
- **Polymorphic Coordinator Associations** — refactored the `coordinators` join model to use polymorphic associations, allowing a single coordinator implementation to be shared across Neuro and MSK studies while preventing ID collisions and reducing duplicate models.

## [v2.3.0] — 2025-12-16
### Added
- **Neuro Reads by Reader Report** — added a new report showing monthly read counts per reader, organized by year with monthly breakdowns for easier workload review.

### Improved
- **Neuro Reporting Organization** — consolidated reporting logic within `Neuro::ReportsController` for improved maintainability and consistency across reports.

## [v2.2.9] — 2025-12-03
- Fixes to the neuro scanner logic

## [v2.2.8] — 2025-12-03
- Revert changes

## [v2.2.7] — 2025-12-03
### Added
- **Authorization & Role Scoping** — consolidated Neuro and MSK role logic using proper namespace-aware patterns. Reader, PI, Coordinator, and Lab Support roles now respect program context more reliably across controllers, helpers, and queries.
- **Namespacing Consistency** — continued reorganization of the Exam and Study models into the `Neuro::` and `Msk::` namespaces. Updated controllers, associations, and Ransack configuration to ensure smoother resolution of class paths and cleaner program separation.
- **Role Request Workflow** — improved the “Request a Role” form to correctly show program selection for Lab Support roles. Updated dynamic visibility logic, fixed JS refresh behavior, and ensured PI lists properly filter by selected program for Coordinator requests.

### Fixed
- **Ransack Sorting Errors** — resolved several `PG::UndefinedTable` issues caused by ordering on related tables without appropriate joins. Added nested joins for `scanner`, `study`, and `lab` to prevent missing FROM-clause errors.
- **Coordinator PI Dropdown** — fixed an issue where PI options would not refresh when switching programs or roles.
- **Role Selection Reset** — resolved a bug where switching between roles caused program radio buttons to persist incorrectly.

## [v2.2.6] — 2025-12-03
### Added
- **MSK Study Management (Full CRUD)** — introduced a dedicated `Msk::StudiesController` with full create, read, update, and delete functionality. MSK program administrators can now manage study names, IRB numbers, joint protocol, laterality, PIs, and default readers directly from the UI.
- **“Other Joint” Field** — added a `joint_other` field plus form/UI support for describing non-enumerated joints when `joint: :other` is selected.

## [v2.2.5] — 2025-11-27
### Added
- **MSK Abnormal Finding Resolution Email Notifications** — when a follow-up-required abnormal finding is resolved, the system now automatically notifies the responsible reader with a detailed summary of the exam, visit, abnormal finding notes, resolution details, and links back to the exam in Imaging Overreads.
- **Created-By Tracking for Abnormal Findings** — added a new `created_by` association to MSK abnormal findings, enabling emails and audit trails to display who originally documented the abnormality.

### Fixed
- **Search Page Sorting Errors** — resolved PostgreSQL `SELECT DISTINCT` sorting issues when ordering by associated lab fields by removing legacy `distinct` usage from on-hold scopes and standardizing Ransack result handling.

## [v2.2.4] — 2025-11-26
### Added
- **Neuro Hold Email Notifications** — updated hold creation to trigger program-specific notifications, including direct links back to the held exam and clear indication of the reader placing the hold.

### Improved
- **Controller Logic for Hold Creation** — refactored `Neuro::OnHoldsController#create` to properly build holds through the `holdable` association, preventing mass-assignment issues and ensuring consistent behavior across programs.
- **Release Hold Routing** — updated release actions to redirect dynamically to the associated exam via the polymorphic `holdable` relation rather than relying on legacy IDs.

## [v2.2.3] — 2025-11-24
### Added
- **Password Reset Workflow Overhaul** — implemented a clear distinction between local (email + password) accounts and UWHIS/LDAP accounts. Users with a UWHIS username are now directed to the UW Health Password Self-Service website or Help Desk instead of receiving a reset email.
- **Navigator Support Integration** — added a new global footer with a direct link to the Imaging Overreads support portal in Navigator for streamlined assistance.

### Improved
- **Reset Password UX** — updated reset forms, email copy, and controller logic to better communicate authentication modes and guide users through the correct reset path.
- **Security & Token Handling** — centralized token validation logic, improved handling of expired/invalid tokens, and clarified messages shown to users during the reset process.
- **Admin Edit User Page** — reorganized the authentication section to clearly separate UWHIS vs local authentication fields and emphasize how login modes are determined.

### Fixed
- **Ambiguous Reset Responses** — resolved issues where users saw confusing “not eligible” messages by providing explicit guidance for UWHIS accounts and unknown emails.

## [v2.2.2] — 2025-11-20
### Added
- **Program-Scoped Labs (Neuro + MSK)** — introduced `program_scoped` support for labs, allowing Neuro and MSK to maintain fully separate lab lists while still permitting shared/global labs when appropriate.
- **MSK “Add Lab” Workflow** — MSK users can now create labs directly from the MSK workspace. The MSK program is auto-selected in the form, and successful creation redirects back to the MSK home page.
- **Neuro “Add / View Labs” Quick Actions** — added new links in the Neuro Control Center to view all Neuro-scoped labs or add a new lab within the Neuro program context.

### Improved
- **Program-Aware Routing & Redirects** — updated controllers to use `program_slug` from `ProgramScoped`, ensuring correct behavior when labs are created or edited from either Neuro, MSK, or Admin paths.
- **Lab Index Filtering** — the labs index now shows only labs belonging to the active program (plus global labs), while the Admin index continues to list all labs.
- **Lab Form Enhancements** — the lab form now includes program selection via radio buttons, with defaults set based on the current namespace. Improved strong params, normalization, and

## [v2.2.1] — 2025-11-19
### Added
- **Sex Field for MSK Exams** — added a dedicated `sex` attribute to MSK exams, captured during exam creation/editing and stored in the database for downstream reporting and communication.
- **Sex Display in MSK Exam Detail & Emails** — MSK exam detail pages now display patient sex alongside other demographic identifiers, and MSK email notifications (e.g., abnormal findings / on-hold messages) now include the sex field when available.

### Improved
- **MSK Demographics Consistency** — aligned MSK demographic capture with Neuro by standardizing where subject ID, DOB, and sex are entered and displayed, reducing ambiguity for readers and coordinators reviewing cases.

## [v2.2.0] — 2025-11-19
### Added
- **MSK Visit On-Hold Workflow** — readers can now place individual MSK visits “on hold” with a structured reason and optional comments. Hold metadata is stored directly on the visit and displayed alongside the exam so the MSK team, PIs, and coordinators understand why a case was paused.
- **On-Hold Email Notifications (MSK)** — when a visit is placed on hold, the system now sends a notification email to the PI, study coordinators (if any), the visit reader (or required reader), Jan Yakey, and Paul Ramirez. The message includes exam/visit details and a direct link back into Imaging Overreads for quick review.

### Improved
- **Environment-Safe Mail Delivery & Debugging** — extended the MSK notification mailer so that in non-production environments emails are routed only to the logged-in user, while still showing who *would* receive the message in production. This ensures safe testing without spamming actual study teams.

## [v2.1.11] — 2025-11-16
### Added
- **Automated MSK Abnormal Finding Email Notifications** — when a visit is marked as *Abnormal (follow-up required)*, the system now sends a notification email to the PI, study coordinators (if any), the interpreting reader, Jan Yakey, and Paul Ramirez.  
  Includes environment-safe delivery logic to prevent accidental notifications in development.
- **Abnormal Status Filters (MSK Exam Search)** — added new Ransack-powered filters for quickly locating:

### Improved
- **Search Results Stability** — refactored visit statistics query to use correlated subqueries instead of `GROUP BY`, resolving Postgres grouping and ordering errors when combining filters and sorting by `last_scan_date`.
- **Filter Layout & Consistency** — removed duplicated resolution filters and aligned new abnormal-status checkboxes within the search form for improved readability.

## [v2.1.10] — 2025-11-14
### Added
- **MSK Abnormal Findings Index** — centralized table for reviewing all abnormal findings across MSK visits, including status, visit links, follow-up indicators, and resolving provider information.
- **Delete workflow for abnormal findings** — allows removal of incorrectly entered findings, automatically clearing any associated visit-level resolution metadata.
- **Follow-Up Required badge logic** — unified display of follow-up status across visit pages and the new index, ensuring consistent visual cues (Needs Follow-Up vs No Follow-Up).

## [v2.1.9] — 2025-11-13
### Added
- **Abnormal Findings Workflow (MSK)** — introduces a static interface for documenting whether a visit’s findings are *Normal*, *Abnormal (no follow-up)*, or *Abnormal (follow-up recommended)*.  
  This section will later trigger automated email alerts to study coordinators and Principal Investigators when follow-up is required.
- **Allows users to add new PIs and Coordinators

## [v2.1.8] — 2025-11-10
### Added
- **MSK Exam Search page** — a dedicated interface for browsing, filtering, and sorting all MSK exams (resolved and unresolved).  
  Includes Ransack-based search by subject, study, reader, and date range, plus status filters for Unresolved and Resolved exams.
- **Dashboard statistics** in the *Find Exams* section — displays Total, Unresolved, Resolved, and Last 30 Days exam counts for quick at-a-glance insights.

### Changed
- **MSK Control Center layout:** standardized column widths so *Find Exams* and *Recent Exams* cards align visually.
- **Reading Pools and Studies** sections restructured into a unified left-side stack for balanced presentation and improved readability.

## [v2.1.7] — 2025-11-09
### Added
- **Joint Information fields** on MSK Visits — enables structured recording of joint-specific data (joint name, laterality, region, and “Other” text when applicable).
- **Auto-population logic** for joint data during Visit creation, ensuring smoother entry for returning participants.

### Changed
- **Removed `energy_or_duration_text`** column and all associated form fields to streamline the MSK Visit form.
- **Updated Visit accordion display** to include joint summary information alongside medications and pain details.

### Fixed
- Minor UI spacing and alignment adjustments in the Visit accordion headers for consistent readability.

## [v2.1.6] — 2025-11-07
### Added
- Current Medications field on MSK Visits — records patients’ current meds and auto-prefills from the previous visit for continuity.
- Medications section added to the Visit accordion view, showing a concise summary and optional full list reveal.

### Improved
- Updated MSK Visit controller logic to seed visit numbers and copy forward prior visit data automatically. 
- UI refinements in accordion badges for clarity and consistent layout spacing.

## [v2.1.5] — 2025-11-07
### Fixed 
- Fixes to calculate_age method

## [v2.1.4] — 2025-11-06
### Fixed
- Age at Time of Scan now calculates from the exam’s Scan Date (not today) and also shows Current Age in parentheses. Handles nil dates and respects app timezone.
- Move away from radweb email group

### Technical
- Added age_years_on(dob, as_of_date) (and optional age_ym_on) helper; replaced previous calculate_age usage in the Subject card.

## [v2.1.3] — 2025-11-06
### Added
- **MSK Visit Resolution Panel:** users can now mark a visit as *resolved* with optional **resolution notes**.
    - A new card appears within each visit accordion.
    - Once resolved, the visit displays a green badge with the resolution date and notes; a **Reopen** button restores it to open status.
- **Body Diagram modal:** added a top-right **“Body Diagram”** button on the MSK Exam page that opens a full-size reference image in a Bootstrap modal.
- **Unresolved-only Reading Pool:** implemented logic to display only exams with at least one unresolved visit, ensuring accurate exam lists and reader counts.

### Fixed
- **Reader pool counts:** dashboard tallies now accurately reflect unresolved exams per reader — exams with *all visits resolved* are no longer counted.

### Changed
- **MSK Exam Visit schema:** renamed `reader_id` → `resolver_id` and added `resolution_notes` column to support the new resolution workflow.

## [v2.1.2] — 2025-10-31
### Fixed
- Reading pool lists now load **chronologically by Scan Date (newest first)** by default, eliminating the need to manually click the column header.
- Prior scan matching is now **case-insensitive** — entries such as `RMR123`, `rmr123`, and `Rmr123` are treated as equivalent, ensuring no priors are missed due to letter casing.

### Added
- **MSK Visit attachments:** users can now upload files (PDF, images, and `.docx`). Each attachment shows action buttons for **Open in new tab** or **Download**; non-previewable types (e.g., `.docx`) are clearly labeled **Download only**.
- **Downloads menu in top nav (MSK):** quick links to **FDG PET MR Pain Questionnaire** and **CRF Biswal Pain Survey & Body Diagram** (subpath-safe; Turbo disabled for file links).

### Changed
- **Form submission flow:** disabled Turbo on Visit edit forms and now redirect back to the Exam show (anchored to the updated visit) to prevent show/edit content blending.

## [v2.1.2] — 2025-10-31
### Fixed
- Reading pool lists now load **chronologically by Scan Date (newest first)** by default, eliminating the need to manually click the column header.
- Prior scan matching is now **case-insensitive** — entries such as `RMR123`, `rmr123`, and `Rmr123` are treated as equivalent, ensuring no priors are missed due to letter casing.

## [v2.1.1] — 2025-10-21
### Added
- Pool now only lists unresolved exams (exams with any open visits).
- Added clear visit metrics (open / resolved / total) per exam row
- Improved table alignment and readability
- Preloaded study and reader data for faster load times.

## [v2.1.0] — 2025-10-20
### Added
- **Prior Exam Matching (MSK):**
  - Implemented logic to match prior exams by `subject_id` and display them on the MSK Exam detail view.
  - Added new two-column layout for exam pages with a summary sidebar and improved readability.
  - Links to prior exams now open in a new browser tab.

- **Coordinator / PI Entry Form:**
  - Support for creating multiple visits per exam.
  - Improved handling of missing fields when creating new MSK exams.
  - Added ability to edit existing MSK exams directly from the exam page.

- **Visits Entry Form:**
  - Added visit edit functionality.
  - Implemented shorter and clearer visit form layout.
  - Added *Joint* and *Spine* form fields.
  - Added *Pain Tracking* fields (pain range, peak pain, cause of significant pain).
  - Enabled *Medication Tracking* per visit.
  - Added *IRB approval logic* and *patient feedback tracking*.
  - Enabled automatic removal of exams from reader queue once all visits are resolved.

### Changed
- Redesigned **MSK Exam Show Page** to a cleaner two-column layout:
  - Left: visit accordion and management tools.
  - Right: sticky summary sidebar with prior exams, exam metadata, and quick actions.
- Improved page responsiveness and consistency with the Neuro Overreads layout.

## [v2.0.8] — 2025-10-15 - Fixed
- Neuro: prevent `[]=` on `nil` in `Neuro::ExamsController#create` by routing “new diagnosis” inputs through `exam_params` and setting `diagnosis_id` safely.
- Reading Pools: Ransack sort by **Scanner** now works (`left_joins(:scanner)` + permitted association).
- Reading Pools: Ransack sort by **Lab** now works (`left_joins(study: :lab)` + nested association allowances).

## [v2.0.7] — 2025-10-02 — Fix syntax error
- Fix syntax error 

## [v2.0.6] — 2025-10-02 — Fix ransack sorting
- Users can sort on study, lab, and scanner

## [v2.0.5] — 2025-10-02 — Fix bug with redirect
- Fix routing issue after login

## [v2.0.4] — 2025-10-01 — Fix to prior exams
- Fix bug with reading pool not showing the correct name

## [v2.0.3] — 2025-10-01 — Fix to prior exams
- Fix pathing to display prior exam

## [v2.0.2] — 2025-09-29 — Fix to banner
- remove banner from msk section

## [v2.0.1] — 2025-09-29 — Hot fixes to 
- Fix daily report
- update the Banner messages to be less annoying

## [v2.0.0] — 2025-09-29 — MSK demo workflow & program-scoped foundation
### Added
- **MSK demo workflow (preview):** Introduced `Msk::` namespace with initial exam flow and UI. Labeled as preview to set expectations while features are still evolving.
- **MSK preview note in-card:** Moved the “MSK workflow is in preview.” notice into the MSK card/footer to reduce global noise while keeping visibility where it matters.
- **Program-scoped UI groundwork:** Added/extended layout selection so program areas (MSK/Neuro) render the correct layout when browsing program-specific pages (e.g., profile pages under `/msk/...`).

### Changed
- **Top navigation clarity:** Improved the brand/left link’s role as a clear “App Home” to choose MSK vs Neuro; added iconography and labeling to make the landing choice more obvious.
- **Admin area under namespace:** Consolidated admin screens (e.g., Logs) under `Admin::` with correct path helpers (e.g., `admin_logs_path`, `logs_modal_admin_logs_path`). Updated pagination and modal links to match namespaced routing.
- **Reader report plumbing (non-breaking):** Kept the rake entry point stable (`reports:send_daily_report`) while tightening instrumentation and environment handling (see DevOps). Mailer remains program-aware for Neuroradiology readers in production.

## [v1.4.9] - 2025-09-9 - General reading pool fix
- Exclude exams that do not need overread

## [v1.4.8] - 2025-09-9 - Namespacing & Program Slugs
- Added **program-scoped routes** (`/:program/studies`) with helpers like `program_studies_path(program_slug)`.
- Introduced **ProgramScoped** concern to set `current_program`/`program_slug` and switch layouts per program.
- Centralized allowed slugs via **`PROGRAM_SLUGS`** initializer; added **`Program.resolve!(slug)`** and kept `Program.msk/neuro` finders.

## [v1.4.7] - 2025-09-5 - Hotfix
- Edit studies form fix

## [v1.4.6] - 2025-09-4 - Hotfix
- Fix link route

## [v1.4.5] - 2025-09-4 - Hotfix
- Added example Reading Pool table 
- Added example resolution page for readers

## [v1.4.4] - 2025-09-3 - Hotfix
- Fix error in search page

## [v1.4.3] - 2025-09-3 - Added MSK Workflow Support
- Introduced new Musculoskeletal (MSK) workflow for overread requests.
- Coordinators and PIs can now create MSK exams using a dedicated intake form and study selection.
- MSK studies and submissions are tracked alongside existing Neuro overreads.
- Added support for MSK-specific exam details (joints, laterality, procedure context, etc.).

## [v1.4.2] - 2025-08-14
- Fix rspec error

## [v1.4.1] - 2025-08-14
- Added optional `month`/`months` parameter to Panda Data export for filtering by `created_at` (scan entry date) within the last N months.
- Updated Panda Data project instructions to document the new filter.

## [v1.4.0] - 2025-08-01
- Alphabetize dropdown menu

## [v1.3.9] - 2025-08-01
- Display diagonses that are active

## [v1.3.8] - 2025-08-01
- Fix tag/commit issue

## [v1.3.7] - 2025-08-01
- Change entry form from Gender to sex
  - added additional option for "intersex"
- Fix unit testing using docker-compose.test.yml file

## [v1.3.6] - 2025-07-30
### Added
- Added ability for users to add a new dialog
- Added a search field for studies list

## [v1.3.5] - 2025-07-25
### Fix
- Fix hardcoded email

## [v1.3.4] - 2025-07-23
### Fix
- Daily status report bug

## [v1.3.3] - 2025-07-23
### Added
- Created MVC scaffold for `Program` model, including model, controller, views, and associated request specs.
- Added Bootstrap-styled layout to `programs/index.html.erb` for a cleaner UI.
- Implemented model spec (`program_spec.rb`) with validations and attribute tests.
- Included uniqueness validation test for `Role` model scoped to `resource_type` and `resource_id`.

### Fix
- Fix the "Select Principal Investigator" dropdown option in the choose role page

## [v1.3.2] - 2025-07-21
### Added
- Scoped the following roles to a `Program` resource:
  - `reader`
  - `principal_investigator`
- Hidden form field support for `program` in both AD and manual user creation forms.

### Changed
- `UsersController#create_user`:
  - Assigns roles like `reader` and `principal_investigator` with associated `Program` resource.
  - Global roles like `admin` and `lab_support` remain unscoped.
  - Flash messages now include program context where applicable.
- Role assignment logic now prevents assigning duplicate scoped roles.

### Fixed
- Bug where scoped roles were being assigned without program resource in manual form.
- Fixed incorrect passing of `program` to global roles (`admin`, `lab_support`).

### UI
- Added `short_name` column to `programs` table for abbreviated display names (e.g., `"Neuro"` for `"Neuroradiology"`).
- Added `Program#display_name` method to return `short_name` if present.
- Added `Role#display_name` method to map long role names to short labels (e.g., `"principal_investigator"` → `"PI"`).

### Developer Notes
- To scope the Reader and Principal Investigator role, run these commands in rails console
```
neuro = Program.find_by(name: "Neuroradiology")

# Find all global (non-scoped) reader roles
global_reader_role = Role.find_by(
  name: "principal_investigator",
  resource_type: nil,
  resource_id: nil
)

# Fetch all users who currently have the global reader role
users = User.joins(:roles).where(roles: { id: global_reader_role.id })

# Update each user: remove global role, add program-scoped role
users.find_each do |user|
  user.remove_role(:principal_investigator)
  user.add_role(:principal_investigator, neuro)
  puts "Updated user #{user.id} - #{user.email}"
end

neuro = Program.find_by(name: "Neuroradiology")

# Find all global (non-scoped) reader roles
global_reader_role = Role.find_by(
  name: "reader",
  resource_type: nil,
  resource_id: nil
)

# Fetch all users who currently have the global reader role
users = User.joins(:roles).where(roles: { id: global_reader_role.id })

# Update each user: remove global role, add program-scoped role
users.find_each do |user|
  user.remove_role(:reader)
  user.add_role(:reader, neuro)
  puts "Updated user #{user.id} - #{user.email}"
end
```

## [v1.3.1] - 2025-07-17
### Added
- Added `program_id` foreign key to `coordinator_requests` table, linking each request to a `Program`.
- Created model associations: `CoordinatorRequest belongs_to :program`, `Program has_many :coordinator_requests`.

### Changed
- Updated `request_role` method in `WelcomeController` to temporarily assign the "Neuroradiology" program to new coordinator requests.
- Refactored `confirm_reader` method to assign the `:coordinator` role scoped to the associated `program`.

### Notes
- run `rails db:migration` to add the foreign key reference in the programs table

## [v1.3.0] - 2025-07-17
✅ Role Management Enhancements
- Refactored coordinator role to require a Program association (e.g., Neuroradiology, Nuclear Medicine).
- Removed support for global coordinator roles; all role assignments are now resource-scoped.
- Added support for assigning program-specific coordinator roles during user creation and editing

### Refactor coordinator role migration
- Run this in rails console
``` 
neuro = Program.find_by(name: "Neuroradiology")
global_coordinator_role = Role.find_by(
  name: "coordinator",
  resource_type: nil,
  resource_id: nil
)

users = User.joins(:roles).where(roles: { id: global_coordinator_role.id })

users.find_each do |user|
  user.remove_role(:coordinator)
  user.add_role(:coordinator, neuro)
  puts "Updated user #{user.id} - #{user.email}"
end
  
```

## [v1.2.7] - 2025-07-14
### Added
- Reader column to the exam table

## [v1.2.6] - 2025-07-02
### Added
- Added **Edit Exam** button next to the Delete button on the exam details page for easier navigation.

### Changed
- Updated Exam `update` action logic:
  - Redirect now goes to the Reading Pool **only if a summary is present** (indicating the exam was read).
  - Otherwise, after a successful update, users are redirected back to the exam’s show page.
- Improved study dropdown in the exam form:
  - The study select box now displays both Lab and Study names (e.g. “UWNI - Study A”) as the selected text.
  - Maintains optgroup grouping of studies by Lab for better organization.
  
## [v1.2.5] - 2025-07-01
### Fixed
- Fixed an error in `ExamsController#create` where the `@studies` instance variable was not set when rendering the form after a failed save.

## [v1.2.4] - 2025-06-25
### Added
- Implemented `ApplicationSetting.instance` as a true singleton accessor to ensure only one configuration record exists.
- Created comprehensive RSpec tests for `ApplicationSetting` model covering:
- Added tests to ensure `User.display_banner` is toggled when banner message is updated.

### Fixed
- Replaced outdated validation-based singleton enforcement (`validates :id`) with exception-based enforcement using `before_create`.

### Improved
- Added logging when `admin_email` is missing in non-production environments to assist with debugging.

## [v1.2.3] - 2025-06-25
### Added
- **Monthly Usage Report**: Summarizes total exams submitted each month, grouped by year, with a single table layout. Available to admins and readers.
- **Per-Study Usage Breakdown**: Displays exams submitted per study over the last 5 years, with a column for each year, plus total submissions and active status.
- **User Activity Report**: Tracks user roles, last sign-in, active status, and exam submission totals over the past 5 years, with breakdown by year.

### UI Enhancements
- Added "Reports" dropdown to the top navigation bar with links to:
  - Monthly Usage Report
  - Per-Study Usage
  - User Activity Report
- Used contextual Bootstrap styling (e.g., `table-success`, `badge`) for improved visual clarity.

### Security & Access Control
- All reports require user to be either an `admin` or a `reader` (`authorized_as_reader_or_admin!`).

## v1.2.2 - 2025-06-24
### Fixed
- Fixed `ActionView::Template::Error` caused by `@studies` being `nil` when rendering the exam form after validation failure. Added a `before_action :set_studies` to ensure `@studies` is always set in `ExamsController#create`.
- Fixed issue where `comparison_date_cannot_be_before_scan_date` validation caused form rendering to fail by ensuring controller sets necessary data.

### Added
- RSpec model validations for `Exam`, `Study`, `Lab`, `Diagnosis`, and `Log` models.
- Scope tests for `Exam.unread`.
- Tests for file presence validation in `ExamAttachment` using `FactoryBot` with attached test files.

## v1.2.1 - 2025-06-23
- RSpec test coverage for the `Study` model, including:
  - Validations and associations
  - `after_initialize` behavior to assign default program ("Neuroradiology")
  - Ransack configuration via `.ransackable_attributes` and `.ransackable_associations`
  - Edge cases for blank coordinator IDs, invalid billing arrangements, and default values
  
## v1.2.0 - 2025-06-19
- Renamed `users.role` to `users.requested_role` to reduce confusion with actual assigned roles via Rolify.
- Changed `on_holds.reader_id` column type from text to integer for data integrity.
- Removed unused `lab_id` column from `labs` table
- Removed migrations logic

## v1.1.21 - 2025-06-18
- Fix bug causing error when creating a new PI 

## v1.1.20 - 2025-06-17
- Fixes to abnormal email attachment for missing field and incorrect name

## v1.1.19 - 2025-06-16
- Improved coordinator request approval flow:
  - Added friendly feedback for users who re-click confirmation links after approval.
  - Clarified flash messages for already-approved coordinator requests.
- Improvements to Manual user sign-up flow
- Flash notifications on successful account creation.
- Resolved issue where manual passwords weren’t being saved due to strong-params guard.

## v1.1.18 - 2025-06-05
- Preserve original URL during authentication:
  - Users are now redirected back to their originally requested page (e.g., `/panda`) after logging in
  - Improves support for automation tools and redirect-following scripts
  
## v1.1.17 - 2025-06-04
- Remove auth token from panda page

## v1.1.16 - 2025-06-04
- Allow users to post to the panda page

## v1.1.15 - 2025-06-02
- CC the reader on email notification sent to PI's and Coordinators
- Improved formatting of abnormal report `.doc` attachments:
    - Added bordered tables for clearer layout
    - Centered and italicized header to match legacy style
    - Included all missing metadata fields (scan date, PI, coordinators, contact info)
    - Replaced placeholder date in filename with actual date (e.g., `2025-06-02`)
    - Enhanced disclaimer styling for readability
    
## v1.1.14 - 2025-05-30
- Fix email bug for abnormal report attachment

## v1.1.13 - 2025-05-29
- Added delete functionality for exams

## v1.1.12 - 2025-05-27
- Send admin email notification upon role request
- Fix role removal in admin form
- Improve PI confirm coordinator confirmation message

## v1.1.11 - 2025-05-19
- Fix diagonsis form fields
- Improvements to formatting on studies list

## v1.1.10 - 2025-05-19
- Allow On-hold to be released by anyone

## v1.1.4 - v1.1.9 - 2025-05-15
- Fix coordinator insert
- Fix bug that would not allow users to select multiple coordinators
- Fixed an issue that sometimes prevented a Study from being saved when Coordinators were selected.
- Resolved a problem that caused an error message to appear when creating a new Study.
- Fix study dropdown menu for principal investigators

## v1.1.3 - 2025-05-14
### Improvements
- Refactored the Users index page to improve performance by eager-loading roles and removing in-place role editing.
- Added role management fields to the User edit page (admin-only).
- Coordinator role assignment now clears any pending Coordinator request and resets the user's `role` field.
- Daily Reader Report emails now include a direct link to access the application homepage.

## v1.1.2 - 2025-05-13
### Improvements
- Added funding to the billing reports page
- Role requested information and notification

## v1.1.1 - 2025-05-08
### Fixed
- Fix authorization issue that blocked Readers from submitting an exam as "On Hold"

## v1.1.0 - 2025-05-08
### Fixed
- Corrected an issue where unchecking a user role did not properly remove the role from the database.
- Improved handling of New User creation during Study#new when no Study record exists yet.
- Updated user authentication flow with clearer flash alert messages.
- Fixed inconsistencies in redirects to fallback paths when study context was missing.

## v1.0.9 (2025-04-25)
- Fixed search filter for exams that are "on hold"
- Fixed redirect error upon authentication

## v1.0.8 (2025-04-28)
- Implemented placeholder email generation (missing-email-<username>@placeholder.local) when LDAP mail attribute is missing
- Incomplete users are redirected to edit their profile after login
- Successful profile completion redirects users to root dashboard
- Added Admin-only editable fields (username and password) on the users#edit page

## v1.0.7 (2025-04-21)
- Add safe handling for missing LDAP mail attribute when creating new users

## v1.0.6 (2025-04-17)
- Fixed crash caused by missing `mail` attribute in LDAP user login
- Added defensive handling for missing email values during AD authentication
- Simulated missing LDAP `mail` attribute in development for testing edge cases

## v1.0.5 (2025-04-16)
- Hot fix to search page

## v1.0.4 (2025-04-16)
- Fixed Ransack-related table sorting bugs across multiple views
- Added dynamic modal system to logs#index for viewing detailed log information
- AJAX-powered modals allow users to inspect individual log entries without leaving the page
- Improved log table layout and viewer link styling
- Minor controller and view cleanups for consistency

## v1.0.3 (2025-04-15)
- Fix migrations error for adding studies

## v1.0.2 (2025-04-14)
- Added global banner alert system for application-wide announcements
- Admins can edit banner content via Application Settings
- Users can dismiss banner; dismissal is tracked per user
- Added buttons to force-show or hide the banner for all users
- Improved styling and layout of the Application Settings page
- 
## v1.0.1 (2025-04-02)
- Fixes to search filters

## v1.0.0 (2025-03-27)
- MVP release

## v0.0.2 (02-27-2025) - Fix authorization
- coordinator requests fixed
- improvements to table data
- format email notification

## v0.0.1 (02-21-2025) - Base app MVP 
- Enter Scans
- Reading pools
- Billing Page
- Search page
- Coordinator Request workflow
- Email notifications