Untangle compile cycles: split Mv.Config + extract the join-request workflow #538

Open
opened 2026-06-15 22:21:09 +02:00 by moritz · 0 comments
Owner

Motivation

The codebase has 36 dependency cycles (several via compile-time edges → recompilation cascades). Two hubs drive
most of them: Mv.Config (a 720-LOC accessor present in the majority of cycles) and the Mv.Membership domain
module (which embeds a 500+ LOC join-request workflow and pulls Emails/Router into compile cycles).

Scope — two ordered sub-tracks (CI green each step)

Track A — split Mv.Config (720 LOC). Extract per-domain config modules (Config.Smtp, Config.Oidc,
Config.Vereinfacht, Config.Import), one per step, keeping a thin facade if needed so call sites compile each
step. Each context then depends only on its config slice.

Track B — extract the join-request workflow.

  • R-013: move the 500+ LOC join-request orchestration (submit/resend/confirm/approve/reject, notification
    dispatch, token generation, member promotion) out of lib/.../membership.ex:392-900 into its own module; the
    domain module becomes a thin facade.
  • R-019 (after R-013): break the domain→Emails→Router compile cycles (~20 of 36). Keep the runtime JoinNotifier
    indirection as the only link between the domain and the web layer.

Acceptance criteria

  • Mv.Config and Mv.Membership materially thinner.
  • mix xref graph --format stats shows the cycle count materially reduced (record before/after); the
    domain→Emails→Router compile cycles are gone.
  • mix compile and just ci-dev green after each step.

Note

Track A pairs with the "Split global_settings + fees_component" issue (global_settings consumes the config).

## Motivation The codebase has 36 dependency cycles (several via compile-time edges → recompilation cascades). Two hubs drive most of them: `Mv.Config` (a 720-LOC accessor present in the majority of cycles) and the `Mv.Membership` domain module (which embeds a 500+ LOC join-request workflow and pulls Emails/Router into compile cycles). ## Scope — two ordered sub-tracks (CI green each step) **Track A — split `Mv.Config` (720 LOC).** Extract per-domain config modules (`Config.Smtp`, `Config.Oidc`, `Config.Vereinfacht`, `Config.Import`), one per step, keeping a thin facade if needed so call sites compile each step. Each context then depends only on its config slice. **Track B — extract the join-request workflow.** - R-013: move the 500+ LOC join-request orchestration (submit/resend/confirm/approve/reject, notification dispatch, token generation, member promotion) out of `lib/.../membership.ex:392-900` into its own module; the domain module becomes a thin facade. - R-019 (after R-013): break the domain→Emails→Router compile cycles (~20 of 36). Keep the runtime `JoinNotifier` indirection as the only link between the domain and the web layer. ## Acceptance criteria - `Mv.Config` and `Mv.Membership` materially thinner. - `mix xref graph --format stats` shows the cycle count materially reduced (record before/after); the domain→Emails→Router compile cycles are gone. - `mix compile` and `just ci-dev` green after each step. ## Note Track A pairs with the "Split global_settings + fees_component" issue (global_settings consumes the config).
moritz added this to the Code and Test Refactoring | TI I milestone 2026-06-15 22:21:09 +02:00
moritz added this to the Sprint 18: Juli 2026 project 2026-06-15 22:21:09 +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#538
No description provided.