feat(fase-10): CU-H06 leave collective — RPC + settings UI

Migration 017 adds public.leave_collective(uuid) with three branches:
- normal member: remove membership row
- sole admin with other members: promote oldest-joined remaining member
  to admin (inline; the existing user-delete trigger does not cover the
  membership-delete path), then remove the row
- sole member: reject with errcode P0001 so the UI can direct the user
  to the dissolve flow (CU-H08)

Settings page gains a "Your collectives" section listing the user's
memberships with a per-row Leave button; the confirmation modal calls
the RPC, drops the collective from local stores, and either switches
to the next collective or sends the user to /onboarding when none
remain. Also seeds the Danger zone scaffolding for Fase 10.5 and adds
all message keys consumed by 10.1, 10.3, 10.5 and 10.6.

pgTAP 010 (7 assertions): member-leave, sole-admin-leave + auto-promote,
sole-member rejected with P0001. Playwright L-01 walks Borja through
the UI flow + checks the seed collective survives (content stays).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 02:04:43 +02:00
parent 6cb13146f5
commit 2f0847a5a3
6 changed files with 529 additions and 2 deletions

View File

@@ -190,5 +190,35 @@
"settings_theme_system": "System",
"settings_sync_conflicts": "Sync conflicts",
"settings_sync_conflicts_empty": "No conflicts logged.",
"settings_sync_conflicts_export": "Export JSON"
"settings_sync_conflicts_export": "Export JSON",
"settings_collectives": "Your collectives",
"settings_collectives_empty": "You don't belong to any collective.",
"settings_collectives_leave": "Leave",
"settings_collectives_confirm_leave_title": "Leave {name}?",
"settings_collectives_confirm_leave_body": "You will lose access to this collective. The content stays for the other members.",
"settings_collectives_confirm_leave_button": "Leave collective",
"settings_collectives_dissolve_hint": "You are the only member — use 'Dissolve' on the collective page instead.",
"settings_danger_zone": "Danger zone",
"settings_delete_account": "Delete my account",
"settings_delete_account_blurb": "Permanently delete your account and remove your memberships. Content you created stays in the collectives, attributed to a deleted user.",
"settings_delete_account_modal_title": "Delete your account?",
"settings_delete_account_modal_body": "This is permanent. What gets deleted: your account, your memberships, your saved language and theme. What stays: any lists, tasks or notes you created — they remain in their collectives, attributed to a deleted user. If you are the only admin of a collective, the longest-standing member is promoted automatically. Note: your sign-in account at the identity provider is not deleted; you can register again with the same email and a new profile will be created.",
"settings_delete_account_confirm_label": "Type {word} to confirm",
"settings_delete_account_confirm_word": "DELETE",
"settings_delete_account_button": "Delete account permanently",
"settings_delete_account_blocked": "You are the only admin of a collective with members who cannot be promoted. Promote someone first, or remove the other members.",
"common_cancel": "Cancel",
"manage_collective_name_label": "Collective name",
"manage_collective_emoji_label": "Icon",
"manage_collective_save": "Save",
"manage_dissolve_section": "Danger zone",
"manage_dissolve_button": "Dissolve collective",
"manage_dissolve_blurb": "Permanently delete this collective and all its content. This cannot be undone.",
"manage_dissolve_title": "Dissolve {name}?",
"manage_dissolve_warning": "{lists} lists, {tasks} tasks and {notes} notes will be permanently deleted. This is irreversible.",
"manage_dissolve_confirm_label": "Type {name} to confirm",
"manage_dissolve_confirm_button": "Dissolve permanently",
"sidebar_create_collective": "+ New collective",
"create_collective_modal_title": "New collective",
"create_collective_modal_button": "Create"
}