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:
- Simplify the mockup to match what's built (single "Transfer" action, caller stays Admin) — cheapest, ships now.
- 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
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.
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 atedifikana/front-end/app/src/commonMain/.../features/settings/organizations/transferownership/, registered asSettingsDestination.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:
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.transferOwnershiponly atomically swap Owner↔Admin roles between caller and target —there's no combined "leave after transferring" backend capability, and the front-end
MembershipManager/MembershipServiceinterfaces don't expose one either.Decision needed before implementing
This is a product/scope call, not a pure engineering one — pick one:
endpoint/flag (e.g.
transferOwnership(..., leaveAfter: Boolean)) or the front-end chainingtransferOwnership()thenleaveOrganization()as two calls (note: the target becomes Owner and the caller is nolonger 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
TransferOwnershipViewModelTestupdated to cover the agreed behavior(s)Files
edifikana/front-end/app/src/commonMain/.../features/settings/organizations/transferownership/{TransferOwnershipScreen,TransferOwnershipViewModel,TransferOwnershipUIState}.ktedifikana/front-end/app/src/commonMain/.../managers/MembershipManager.ktedifikana/front-end/app/src/commonMain/.../service/MembershipService.ktedifikana/back-end/src/main/kotlin/com/cramsan/edifikana/server/{controller/MembershipController,service/MembershipService,datastore/supabase/SupabaseMembershipDatastore}.kt,edifikana/api/.../MembershipApi.ktRelated
Parent: #392.