Skip to content

Rework org status: remove program status, merged affiliated-since, 3-value status - #1993

Open
maebeale wants to merge 14 commits into
mainfrom
maebeale/remove-org-status-columns
Open

Rework org status: remove program status, merged affiliated-since, 3-value status#1993
maebeale wants to merge 14 commits into
mainfrom
maebeale/remove-org-status-columns

Conversation

@maebeale

@maebeale maebeale commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

🤖 suggested review level: 5 Inspect 🔬 substantive display logic (affiliation-period merging, mirrored in JS) plus a data migration that remaps + drops OrganizationStatus records

What is the goal of this PR and why is this important?

Three related cleanups to org data that only made sense together:

  • Program status (New/Reinstate/Ongoing) is event-relative, so it's removed from the org-wide index column and edit form (per-event version lives on the profile in Add Event abbreviation and surface it in compact/event contexts #1995).
  • "Affiliated since" now reflects the real shape of an org's affiliation history — merged periods with gaps — instead of one flat Mon YYYY – Mon YYYY range.
  • The org status vocabulary is trimmed from six event-flavored values to Active / Formerly active / Unknown.

How did you approach the change?

  • Removals: the index "Program" column, the orphaned Organization.program_statuses_by_id, and the edit-form "Program status" block.
  • AffiliationPeriods service merges affiliation intervals into periods: a lone ongoing period → "Mon YYYY" (this year) or its start year; multi-period lists are year-only → "2010-2012, 2026". Falls back to org.start_date, then blank. Applied on show / index / edit; the edit form's live JS preview mirrors the same formatting.
  • Status simplification: constant + a data migration remaps existing statuses (Reinstate→Active, Inactive/Suspended→Formerly active, Pending→Unknown) then deletes the retired records. The affiliation status-sync callback and seeds follow the new names.

Anything else to add?

  • The DB organization_status search filter is kept (real field).
  • Screenshots to follow.

Copilot AI review requested due to automatic review settings July 15, 2026 04:25

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

# already-loaded affiliations so a profile can classify many events without an
# N+1. No facilitator affiliation starting before the date => :new; an earlier
# one still active on the date => :ongoing; all earlier ones ended => :reinstated.
def facilitator_status_as_of(date)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Deliberately computed in-memory (over the already-loaded affiliations) rather than reusing the DB-backed Organization#facilitator_status_on, so classifying a paginated page of ~9 events doesn't fire 2 queries per event. Same classification rule, just no N+1.

title: event.title,
data: { turbo_frame: "_top" },
class: "inline-flex items-center rounded-full text-xs font-medium border px-2.5 py-0.5 #{OrganizationDecorator.program_status_classes(status)}" do %>
<%= status.to_s.titleize %> · <%= event.abbreviation.presence || event.title.truncate(24) %>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Falls back to a truncated title when abbreviation is blank so existing events still render a sensible chip. Chips are gated behind manage? to keep program status admin-only, matching how it was treated on the old index column.

@maebeale
maebeale force-pushed the maebeale/remove-org-status-columns branch from 06ca55a to 7fb2709 Compare July 15, 2026 04:51
Copilot AI review requested due to automatic review settings July 15, 2026 04:51

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale
maebeale marked this pull request as ready for review July 15, 2026 04:53
Copilot AI review requested due to automatic review settings July 15, 2026 05:06
@maebeale
maebeale force-pushed the maebeale/remove-org-status-columns branch from 7fb2709 to c1bb63c Compare July 15, 2026 05:06

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale maebeale changed the title Move org program status out of org-wide UI into event context Remove program status from org-wide UI Jul 15, 2026
Copilot AI review requested due to automatic review settings July 15, 2026 19:35

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale maebeale changed the title Remove program status from org-wide UI Rework org status: remove program status, merged affiliated-since, 3-value status Jul 15, 2026
class SimplifyOrganizationStatuses < ActiveRecord::Migration[8.1]
# Retiring the six-value status set down to Active / Formerly active / Unknown.
# Each retired status folds into one of the survivors; Reinstate counts as Active.
RETIRED_TO_REPLACEMENT = {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: The load-bearing decisions to eyeball: Reinstate folds into Active (per request), Inactive/Suspended into Formerly active, Pending into Unknown. down recreates the retired records but cannot restore per-org mappings — a merge is inherently lossy.


// Merge affiliation intervals into periods and format them as year-based ranges
// — the client-side mirror of app/services/affiliation_periods.rb.
affiliatedSinceLabel(affiliations, today) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: This is a hand-kept mirror of AffiliationPeriods (app/services/affiliation_periods.rb) so the edit-form live preview matches the server render. If the Ruby formatting rules change, change both.

Copilot AI review requested due to automatic review settings July 15, 2026 19:39

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

maebeale and others added 3 commits July 30, 2026 20:16
New/Reinstate/Ongoing can only be determined relative to a specific event, so
showing it as a global org attribute was misleading. Per-event program status is
surfaced on the org profile in a separate PR (event abbreviations, #1995).

- Drop the admin-only "Program" column from the org index.
- Drop the now-orphaned Organization.program_statuses_by_id bulk classifier.
- Drop the "Program status" block from the org edit form's Affiliations section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Affiliated-since was already affiliation-derived, but showed a single
Mon YYYY – Mon YYYY range. Admins need the real shape of an org's history —
including gaps — and a status vocabulary that isn't event-specific.

- AffiliationPeriods service merges affiliation intervals into periods and
  formats them as year-based ranges: a lone ongoing period shows "Mon YYYY"
  (this year) or its start year; multi-period lists are year-only, e.g.
  "2010-2012, 2026". Falls back to the org's start_date, then blank.
- Applied on the org show page, index column, and edit form; the edit form's
  live preview (affiliation_dates_controller.js) mirrors the same formatting.
- Simplify OrganizationStatus to Active / Formerly active / Unknown. Data
  migration remaps existing statuses (Reinstate->Active, Inactive/Suspended->
  Formerly active, Pending->Unknown) then drops the retired records; the
  affiliation status-sync callback and seeds follow the new names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rm's range

The affiliation-dates Stimulus controller is shared with the person edit form,
whose "Affiliated since" stays a single Mon YYYY range. Gate the merged-periods
formatting behind a `periods` value the org form sets, so only the org form's
live preview and server render use periods.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@maebeale
maebeale force-pushed the maebeale/remove-org-status-columns branch from f3e576d to 594d262 Compare July 31, 2026 00:20
Copilot AI review requested due to automatic review settings July 31, 2026 00:20

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Keeping the merge-and-format logic in both AffiliationPeriods and the Stimulus
controller was a duplication smell. The org form's "Affiliated since" doesn't
need a live preview now that it's coarse year-ranges, so render it server-side
via the decorator and leave that field untouched by JS (a `serverAffiliatedSince`
value gates it). The person form keeps its live single Mon YYYY range.

AffiliationPeriods is now the single source of truth. Replaces the org
affiliation-dates system spec with a request spec asserting the server render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 31, 2026 21:28

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Replaces the org index "Affiliated since" column with "Program since" — the
org's facilitator-affiliation history as merged year-based periods (e.g.
"2015-2018, 2024") via a new OrganizationDecorator#program_since_display. Adds a
"Program since" row to the org show page, and converts the edit form's
"Facilitations/program since" value to the same period format.

Both org-form "since" fields are now server-rendered, so the affiliation-dates
Stimulus controller is dropped from the org form (it still drives the person form).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

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

Suppressed comments (4)

app/views/organizations/_form.html.erb:344

  • 🤖 From Copilot: blocker: The org form no longer provides data-affiliation-dates-target="affiliationsContainer", but affiliation_dates_controller (and existing system specs) rely on this target to find .nested-fields and attach listeners / locate rows. Restoring the target keeps the existing behavior working without reintroducing the old UI fields.
        <div class="p-3" data-controller="paginated-fields" data-paginated-fields-per-page-value="10">

app/views/organizations/organizations_results.html.erb:13

  • 🤖 From Copilot: should-fix: The PR description says the index column is "Affiliated since" (now merged periods), but the results table header is now "Program since" and the affiliated-since display no longer appears in the index. If this change is intentional, the PR description (and any UX expectations) should be updated; otherwise consider restoring the affiliated-since column or renaming this header to match the intended display.
            <th class="px-4 py-2 text-left text-sm font-semibold text-gray-700">Program since</th>

app/decorators/organization_decorator.rb:94

  • 🤖 From Copilot: should-fix: program_since_display currently filters facilitator affiliations with Ruby select, which forces loading all affiliations when a relation is passed and can be wasteful compared to the existing .facilitators scope. Using the scope when available preserves the "pass a preloaded collection" API while avoiding unnecessary objects/IO.
  def program_since_display(affiliations = object.affiliations)
    AffiliationPeriods.label(affiliations.select(&:facilitator?)) || ""
  end

app/views/organizations/_form.html.erb:1

  • 🤖 From Copilot: blocker: Removing the affiliation-dates Stimulus controller from the org form leaves affiliation-dates#recalculate actions in app/views/affiliations/_fields.html.erb without a matching controller (console errors) and breaks system specs that wait for [data-affiliation-dates-ready]. Re-add the controller on this form (you can keep serverAffiliatedSince true to avoid touching the server-rendered "Affiliated since" field).

This issue also appears on line 344 of the same file.

<%= simple_form_for(@organization, html: { data: { controller: "affiliation-facilitator-warning" } }) do |f| %>

…o admins

- Per-event program-status chips now open the event dashboard (the canonical
  event admin home) in a new tab, instead of the background report — still a
  placeholder for the in-development attendance report.
- The org index "Program status" chip under the Program since date is now
  admin-only (manage?), matching how program status is treated elsewhere.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 2, 2026 01:28
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

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

Suppressed comments (2)

app/controllers/organizations_controller.rb:14

  • 🤖 From Copilot: should-fix: Eager-loading :affiliations for the org index results can pull a lot of data (all affiliation columns for every org in the page) just to compute the “Program since” label. You can avoid the heavier preload by fetching only facilitator affiliations for the current page and passing them into the decorator.
      base_scope = authorized_scope(Organization.includes(
        :windows_type, :organization_status, :sectors, :addresses, :affiliations,
        { categorizable_items: { category: :category_type } },
        logo_attachment: :blob
      ))

app/decorators/organization_decorator.rb:94

  • 🤖 From Copilot: should-fix: program_since_display always filters facilitator affiliations in Ruby, which forces loading all affiliations when the association isn’t already loaded (e.g., on org show). Consider using the SQL facilitators scope when possible to avoid unnecessary record loads.
  def program_since_display(affiliations = object.affiliations)
    AffiliationPeriods.label(affiliations.select(&:facilitator?)) || ""
  end

Copilot AI review requested due to automatic review settings August 2, 2026 01:33

Copilot AI 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.

Pull request overview

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

Suppressed comments (2)

app/views/organizations/_form.html.erb:344

  • 🤖 From Copilot: blocker: The affiliation editor container no longer has the affiliationsContainer target, so affiliation-dates can’t attach listeners / compute visible rows (and specs that locate rows via this target will fail).
        <div class="p-3" data-controller="paginated-fields" data-paginated-fields-per-page-value="10">

app/services/affiliation_periods.rb:62

  • 🤖 From Copilot: should-fix: AffiliationPeriods claims “touching intervals collapse into one period”, but the merge logic only merges when next_start <= finish (overlap), not when an interval starts the day after a prior one ends, so back-to-back affiliations will be shown as separate periods.
  # A nil end is ongoing and swallows every later interval.
  def overlaps?(period, next_start)
    period[1].nil? || next_start <= period[1]
  end

@@ -1,4 +1,4 @@
<%= simple_form_for(@organization, html: { data: { controller: "affiliation-dates affiliation-facilitator-warning" } }) do |f| %>
<%= simple_form_for(@organization, html: { data: { controller: "affiliation-facilitator-warning" } }) do |f| %>
…ctors

- Merge the separate year + status chips into one: admins see the facilitator
  years coloured by org status (green Active / orange Formerly active / gray
  Never active), falling back to the status label when there are no years;
  non-admins keep a neutral yellow year chip.
- Rename the index "Designations" column to "Sectors" and stop showing the
  windows-type pill there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 2, 2026 01:48

Copilot AI 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.

Pull request overview

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

Suppressed comments (2)

app/views/organizations/_form.html.erb:344

  • blocker: The org edit system spec locates affiliation rows via data-affiliation-dates-target="affiliationsContainer"; after removing it, the warning flow tests (and the affiliation-dates controller if re-enabled) can’t find the nested affiliation fields reliably.
        <div class="p-3" data-controller="paginated-fields" data-paginated-fields-per-page-value="10">

app/views/organizations/_form.html.erb:1

  • blocker: This form no longer mounts the affiliation-dates Stimulus controller, but existing system specs (and any JS that waits on data-affiliation-dates-ready) assume it runs on the org edit form. Either update those specs/UX expectations, or re-add the controller here (and set serverAffiliatedSince so it won’t overwrite the server-rendered merged periods).
<%= simple_form_for(@organization, html: { data: { controller: "affiliation-facilitator-warning" } }) do |f| %>

Replaces the "Windows audience" dropdown with a Sector dropdown (sector_names_all)
followed by an Age group dropdown (category_names_all over AgeRange categories) —
both wired to the existing search scopes. Options are loaded in set_index_variables.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 2, 2026 01:55

Copilot AI 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.

Pull request overview

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

Suppressed comments (3)

app/services/affiliation_periods.rb:62

  • 🤖 From Copilot: should-fix: overlaps? currently only merges when the next interval starts on/before the prior end date; adjacent intervals (end on 2020-01-31, next starts 2020-02-01) are treated as a gap even though the docstring says “touching intervals collapse”. This will split what looks like continuous affiliation history into multiple periods.
  # A nil end is ongoing and swallows every later interval.
  def overlaps?(period, next_start)
    period[1].nil? || next_start <= period[1]
  end

app/views/organizations/organizations_results.html.erb:26

  • 🤖 From Copilot: should-fix: This label uses the raw status name, so orgs with OrganizationStatus = "Unknown" will display "Unknown" instead of the intended user-facing "Never active" (per OrganizationDecorator#organization_status_label).
                <% status_label = organization.published? ? nil : organization.organization_status&.name %>

app/decorators/organization_decorator.rb:94

  • 🤖 From Copilot: should-fix: program_since_display filters facilitator affiliations in Ruby (select(&:facilitator?)), which forces loading all affiliations on pages that didn’t preload them (e.g., org show/edit) and can be unnecessarily expensive for orgs with many non-facilitator affiliations.
  def program_since_display(affiliations = object.affiliations)
    AffiliationPeriods.label(affiliations.select(&:facilitator?)) || ""
  end

Sector and age-group displays and filters now reflect tags on the org itself and
on any affiliated person (not just the org's own tags):

- Index sector column now uses all_sectors (aggregate), matching the age-group
  column and the org profile (which already aggregate).
- New Organization scopes sector_name_including_people / age_group_name_including_people
  back the index Sector / Age group dropdowns (params sector_name / age_group_name).
- affiliated_sectors now aggregates over all affiliated people (people through
  affiliations) rather than only those with user accounts, so all_sectors matches
  the age-group aggregation and the filters.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 2, 2026 02:02

Copilot AI 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.

Pull request overview

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

Suppressed comments (3)

app/services/affiliation_periods.rb:62

  • 🤖 From Copilot: should-fix: The docstring says “touching intervals collapse”, but overlaps? only merges when next_start <= end_date. Since Affiliation.active_on treats end_date as inclusive, back-to-back intervals (next starts the day after the previous end) will be split into separate periods unexpectedly.
  def overlaps?(period, next_start)
    period[1].nil? || next_start <= period[1]
  end

app/decorators/organization_decorator.rb:94

  • 🤖 From Copilot: should-fix: program_since_display filters facilitator affiliations in Ruby (select(&:facilitator?)), which forces loading all affiliations and duplicates the SQL rule already encoded in Affiliation.facilitators. Using the scope when available keeps behavior consistent and avoids unnecessary record loading.
  def program_since_display(affiliations = object.affiliations)
    AffiliationPeriods.label(affiliations.select(&:facilitator?)) || ""
  end

app/views/organizations/_form.html.erb:1

  • 🤖 From Copilot: nit: The PR description says the org edit form has a live JS preview that mirrors the server formatting, but this change removes the affiliation-dates Stimulus controller from the org form, so affiliation/program “since” values won’t update live while editing affiliations. Either update the PR description or reintroduce an equivalent live preview if that’s still a requirement.
<%= simple_form_for(@organization, html: { data: { controller: "affiliation-facilitator-warning" } }) do |f| %>

Sectors and age groups shown (and filtered) on the org index/profile are now:
tagged directly on the org (any), OR an affiliated person's PRIMARY tag —
affiliated people's non-primary sectors and additional age groups no longer
roll up.

- affiliated_sectors: only each person's primary sector (they have at most one).
- all_additional_age_groups: org's own additional only (people contribute their
  primary via all_primary_age_groups, not additional).
- sector/age-group filter scopes: org-direct OR affiliated person's primary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 2, 2026 02:26

Copilot AI 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.

Pull request overview

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

Suppressed comments (4)

app/views/organizations/_form.html.erb:1

  • 🤖 From Copilot: should-fix: The PR description says the org edit form’s live JS preview mirrors the new merged-period formatting, but the org form no longer attaches the affiliation-dates Stimulus controller, so the “Affiliated since” / “Program since” displays won’t update when editing nested affiliations.
<%= simple_form_for(@organization, html: { data: { controller: "affiliation-facilitator-warning" } }) do |f| %>

app/controllers/organizations_controller.rb:14

  • 🤖 From Copilot: should-fix: organizations_results now calls organization.all_sectors / age-group aggregations (which load through people.includes(...)), but the index query only eager-loads :affiliations/direct :sectors; this will add N+1 queries per org row for people + taggings.
      base_scope = authorized_scope(Organization.includes(
        :windows_type, :organization_status, :sectors, :addresses, :affiliations,
        { categorizable_items: { category: :category_type } },
        logo_attachment: :blob
      ))

app/views/organizations/organizations_results.html.erb:23

  • 🤖 From Copilot: should-fix: This fragment cache key doesn’t include inputs that drive the rendered sectors/age groups (notably affiliated people’s primary taggings), so the index row can stay stale after those associations change.
            <% cache [organization, @program_since_display[organization.id], organization.organization_status_id, @active_people_counts[organization.id], current_user.super_user?] do %>

app/frontend/javascript/controllers/affiliation_dates_controller.js:8

  • 🤖 From Copilot: nit: serverAffiliatedSince was added as a Stimulus value, but there are no views setting data-*-server-affiliated-since-value, and the org form no longer uses this controller; consider removing this value/branch or wiring it up so the intent is clear.
  static targets = ["affiliatedSince", "facilitatorSince", "affiliationsContainer"]
  // Orgs render "Affiliated since" server-side as merged periods (AffiliationPeriods),
  // so the controller leaves that field alone; the person form keeps the live single
  // Mon YYYY – Mon YYYY range.
  static values = { serverAffiliatedSince: Boolean }

Reverts the org-status simplification: restores the six-value constant, drops the
data migration (leaving the records/mappings as-is), and points the sync
callbacks and seeds back at "Inactive".

The program-status chip and index filter now collapse the stored six values into
three display buckets via OrganizationStatus::PROGRAM_STATUS_BUCKETS
(Active/Reinstate → Active, Inactive/Suspended → Formerly active,
Pending/Unknown/none → Never active), so the data is untouched while the UI still
reads as Active / Formerly active / Never active.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 2, 2026 03:06

Copilot AI 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.

Pull request overview

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

Suppressed comments (2)

app/controllers/organizations_controller.rb:14

  • should-fix: The organizations index now renders organization.all_sectors / all_primary_age_groups, which pulls affiliated people’s taggings; the index scope currently doesn’t eager-load people + their sectorable_items/categorizable_items, so the results frame will issue per-row queries. Preload the associations in the index includes(...) to avoid N+1s.
      base_scope = authorized_scope(Organization.includes(
        :windows_type, :organization_status, :sectors, :addresses, :affiliations,
        { categorizable_items: { category: :category_type } },
        logo_attachment: :blob
      ))

app/models/organization.rb:287

  • should-fix: affiliated_sectors always calls people.includes(...), which forces a fresh query even when people (and nested taggings) were already eager-loaded by the caller (e.g. the organizations index). Prefer using the already-loaded association when available to avoid redundant queries.
  # Only affiliated people's PRIMARY sector (a person has at most one) — their
  # non-primary sectors don't roll up to the org.
  def affiliated_sectors
    people.includes(sectorable_items: :sector)
          .flat_map { |person| person.sectorable_items.filter_map { |item| item.sector if item.is_primary? } }

Comment on lines 2 to +14
ORGANIZATION_STATUSES = [ "Active", "Inactive", "Pending", "Reinstate", "Suspended", "Unknown" ]

# The stored values are kept as-is (legacy data), but the UI collapses them into
# three "program status" buckets for display and filtering. Anything unmapped —
# including a missing status — reads as :never_active.
PROGRAM_STATUS_BUCKETS = {
"Active" => :active,
"Reinstate" => :active,
"Inactive" => :formerly_active,
"Suspended" => :formerly_active,
"Pending" => :never_active,
"Unknown" => :never_active
}.freeze
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.

2 participants