Skip to content

feat(publishers): make adding a ministry-school student a first-class flow #212

Description

@mindsers

Problem

There is no logical, easy way for an admin to add a ministry-school student (a current Member of the congregation who attends but isn't yet a declared publisher). Today:

  1. /publishers/new is the only entry point on the Publishers screen, and the create service hardcodes isPublisher: true (app/features/publishers/server/create-member.server.ts:52). No toggle on the form.
  2. The only way to end up with a non-publisher Member is to create them as a publisher, then demote them via a POST /publishers/:memberId/make-student action. But that action has no visible button on the publisher detail page — the lifecycle icon cluster only shows mark-as-left when the member is a publisher. The route exists and is reachable from the Settings → Users list and from e2e tests, but a normal user can't find it from the publisher view.
  3. The one place that exposes a clear isPublisher checkbox in the UI is app/features/settings/routes/users/add-to-congregation.tsx, which only fires when a UserAccount exists but isn't yet linked to a Member — a niche admin flow (e.g. a circuit overseer login becoming a local member), not the common case.

Underlying mismatch: the domain has two independent axes — Type (publisher / student) and Lifecycle (present / inactive / left / anonymized) — but the UI presents one axis. The list is also labelled "Publishers" even though it already contains both publishers and ministry-school students (see docs/product/publishers.md).

Idea (not decided — needs more design work)

The shape of the redesign we've been kicking around:

  • Rename the section "Membres" / "Members" to match what the list already contains. Keep the /publishers URL for now to avoid link/test churn.
  • Single "Ajouter un membre" CTA, with a segmented control inside the form (Publisher / Ministry-school student, defaulting to Publisher). The choice would hide baptism date, anointed, the elder/servant nomination card, and the publisher type select for students; the group selector would stay visible.
  • Move publisher ↔ student switching out of the lifecycle icon cluster into a dedicated "Status" card on the publisher view, with a single labelled action ("Convertir en étudiant" / "Déclarer proclamateur"). The lifecycle cluster would keep only inactive / mark-as-left / mark-as-returned — cleaner separation between "type of member" and "lifecycle state".
  • createMember would accept isPublisher: boolean and force-zero baptism-gated flags when the kind is student, so DB CHECK constraints (servant/elder/anointed → baptism + male) can't be violated by construction.

Out of scope (current thinking)

  • Renaming the /publishers URL — link rot, e2e tests, deep-links from territories. Sidebar/in-page copy rename only.
  • Per-kind limits (students vs publishers). The existing members limit already covers both.
  • Renaming audit actions (PublisherCreated, PublisherStatusChanged). Historical analytics rely on them.
  • A list-row "convert" shortcut. Forcing the admin into the profile first is the right friction.

Status

Not decided. The above is one direction, not a committed design. Open questions before this is ready to implement:

  • Is "segmented control inside the form" the right entry-point shape, or is a split button / two CTAs / a separate route preferable?
  • Should the section actually be renamed, or should the label stay "Publishers" and the IA be fixed elsewhere?
  • Where exactly does the publisher↔student action live on the profile (dedicated card vs. a settings-style menu vs. somewhere else)?
  • Confirm-dialog copy (FR + EN) needs review before it ships.
  • Are there flows we're forgetting — e.g. bulk import, archive restore — that would also need a "kind" field?

More design work needed before opening a PR. Feedback welcome.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Wishlist

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions