Move the member overview query into the Membership domain #590

Closed
opened 2026-10-14 18:24:16 +02:00 by simon · 0 comments
Owner

Follow-up from #536 (Import/Export consolidation). There, the CSV and PDF exports were switched to load members through the same query as the member overview (MvWeb.MemberLive.Index.OverviewQuery), so an export now contains exactly the members, in exactly the order, that the overview shows. To keep #536 focused, the query stayed in the web layer and the export controllers call it from there (option A of #536's solution options). This issue is the deliberately deferred option C.

Problem

The query that decides which members match the overview's filters and in which order is domain logic, but it lives under MvWeb.MemberLive.Index:

  • MvWeb.MemberLive.Index.OverviewQuery builds the :overview read with search, group, fee-type, boolean, date, as-of-date, custom-date and payment filters plus the sort and its tie-breakers.
  • It depends on MvWeb.MemberLive.Index.DateFilter, which in turn uses CustomFieldValueLookup and FilterParams. Those modules mix query building with URL/param parsing.
  • Since #536, the export controllers depend on these LiveView-namespaced modules. Any future non-LiveView caller (an API, a scheduled report, a mail merge) would have to do the same.

This conflicts with the guideline that domains encapsulate business logic and the web layer only calls into them (CODE_GUIDELINES.md §1.3).

Proposal

  • Move the query building into the Membership domain, for example Mv.Membership.MemberOverviewQuery (exact name to be decided), taking a plain, validated options map.
  • Split DateFilter / FilterParams into the domain-side filter expressions (move) and the web-side param parsing (stays in MvWeb).
  • Point the overview LiveView and both export controllers at the domain module.
  • Move or rename the roughly ten test files that exercise OverviewQuery (test/mv_web/live/member_live/index/overview_query_test.exs, index_*_query_test.exs, index_*_property_test.exs, …) to the new location.

Out of scope

  • Any change to filter or sort behavior; this is a pure move. The export/overview parity property from #536 and the existing overview tests are the guard.
  • Replacing the structured export payload with the overview's URL parameters (option B of #536). That fits the separate "slim down index.ex" follow-up better.

Acceptance criteria

  • No module under Mv.* references MvWeb.*, and no export controller references MvWeb.MemberLive.*.
  • The overview and the exports produce identical results before and after the move. The #536 parity property and the overview test suite stay green unchanged, apart from module names.
  • just ci-dev is green.

Dependencies

After #536 is merged.

Follow-up from #536 (Import/Export consolidation). There, the CSV and PDF exports were switched to load members through the same query as the member overview (`MvWeb.MemberLive.Index.OverviewQuery`), so an export now contains exactly the members, in exactly the order, that the overview shows. To keep #536 focused, the query stayed in the web layer and the export controllers call it from there (option A of #536's solution options). This issue is the deliberately deferred option C. ## Problem The query that decides *which members match the overview's filters and in which order* is domain logic, but it lives under `MvWeb.MemberLive.Index`: - `MvWeb.MemberLive.Index.OverviewQuery` builds the `:overview` read with search, group, fee-type, boolean, date, as-of-date, custom-date and payment filters plus the sort and its tie-breakers. - It depends on `MvWeb.MemberLive.Index.DateFilter`, which in turn uses `CustomFieldValueLookup` and `FilterParams`. Those modules mix query building with URL/param parsing. - Since #536, the export controllers depend on these LiveView-namespaced modules. Any future non-LiveView caller (an API, a scheduled report, a mail merge) would have to do the same. This conflicts with the guideline that domains encapsulate business logic and the web layer only calls into them (CODE_GUIDELINES.md §1.3). ## Proposal - Move the query building into the Membership domain, for example `Mv.Membership.MemberOverviewQuery` (exact name to be decided), taking a plain, validated options map. - Split `DateFilter` / `FilterParams` into the domain-side filter expressions (move) and the web-side param parsing (stays in `MvWeb`). - Point the overview LiveView and both export controllers at the domain module. - Move or rename the roughly ten test files that exercise `OverviewQuery` (`test/mv_web/live/member_live/index/overview_query_test.exs`, `index_*_query_test.exs`, `index_*_property_test.exs`, …) to the new location. ## Out of scope - Any change to filter or sort behavior; this is a pure move. The export/overview parity property from #536 and the existing overview tests are the guard. - Replacing the structured export payload with the overview's URL parameters (option B of #536). That fits the separate "slim down index.ex" follow-up better. ## Acceptance criteria - No module under `Mv.*` references `MvWeb.*`, and no export controller references `MvWeb.MemberLive.*`. - The overview and the exports produce identical results before and after the move. The #536 parity property and the overview test suite stay green unchanged, apart from module names. - `just ci-dev` is green. ## Dependencies After #536 is merged.
simon closed this issue 2026-10-16 17:04:39 +02:00
Sign in to join this conversation.
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
local-it/mitgliederverwaltung#590
No description provided.