Skip to content

[FEATURE] Transfer Ownership screen #545

Description

@CRamsan

Status

Built, but the implemented flow doesn't match what the mockup specifies — a real functional gap, not just polish.

What's there

TransferOwnershipScreen.kt + TransferOwnershipViewModel.kt + TransferOwnershipUIState.kt +
TransferOwnershipEvent.kt + preview + test at
edifikana/front-end/app/src/commonMain/.../features/settings/organizations/transferownership/, registered as
SettingsDestination.TransferOwnershipDestination(orgId), reached from Organization Detail's "Transfer Ownership" row
(Owner-only).

Current flow: list eligible ADMIN-role members → tap a card → confirmation dialog ("Transfer ownership to X? You will
become an Admin. This cannot be undone.") → single "Transfer" action → MembershipManager.transferOwnership(orgId, newOwnerId) → navigate back on success.

Gap vs. mockup (edifikana/mockups/transfer-ownership.html)

The mockup's interaction model is select-then-choose: tap a member to select them (checkmark, no dialog), then pick
one of two bottom actions:

  • "Transfer & Stay as Admin"
  • "Transfer & Leave Organization"

The built screen only implements the first behavior (transfer, caller becomes Admin) via a tap-triggered dialog — there
is no "transfer and leave" option anywhere in the stack:

  • MembershipApi.transferOwnership / MembershipController.transferOwnership / MembershipService.transferOwnership
    / SupabaseMembershipDatastore.transferOwnership only atomically swap Owner↔Admin roles between caller and target —
    there's no combined "leave after transferring" backend capability, and the front-end MembershipManager /
    MembershipService interfaces don't expose one either.

Decision needed before implementing

This is a product/scope call, not a pure engineering one — pick one:

  1. Simplify the mockup to match what's built (single "Transfer" action, caller stays Admin) — cheapest, ships now.
  2. Extend to match the mockup — add a "leave after transfer" path. Likely needs either a new backend
    endpoint/flag (e.g. transferOwnership(..., leaveAfter: Boolean)) or the front-end chaining
    transferOwnership() then leaveOrganization() as two calls (note: the target becomes Owner and the caller is no
    longer sole-owner by then, so the second call should pass the sole-owner check cleanly) — plus rework the
    selection UI from tap-to-confirm into select-then-two-buttons.

Acceptance criteria

  • Decision made and recorded here on option 1 vs. 2
  • Selection UI and action(s) match the agreed mockup/behavior
  • TransferOwnershipViewModelTest updated to cover the agreed behavior(s)
  • If option 2: backend scope split out into its own issue if it can't land in the same PR as the frontend change

Files

  • edifikana/front-end/app/src/commonMain/.../features/settings/organizations/transferownership/{TransferOwnershipScreen,TransferOwnershipViewModel,TransferOwnershipUIState}.kt
  • edifikana/front-end/app/src/commonMain/.../managers/MembershipManager.kt
  • edifikana/front-end/app/src/commonMain/.../service/MembershipService.kt
  • Backend (if option 2): edifikana/back-end/src/main/kotlin/com/cramsan/edifikana/server/{controller/MembershipController,service/MembershipService,datastore/supabase/SupabaseMembershipDatastore}.kt, edifikana/api/.../MembershipApi.kt

Related

Parent: #392.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions