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": "Sistema",
"settings_sync_conflicts": "Conflictos de sincronización",
"settings_sync_conflicts_empty": "Sin conflictos registrados.",
"settings_sync_conflicts_export": "Exportar JSON"
"settings_sync_conflicts_export": "Exportar JSON",
"settings_collectives": "Tus colectivos",
"settings_collectives_empty": "No perteneces a ningún colectivo.",
"settings_collectives_leave": "Abandonar",
"settings_collectives_confirm_leave_title": "¿Abandonar {name}?",
"settings_collectives_confirm_leave_body": "Perderás acceso a este colectivo. El contenido se queda para los demás miembros.",
"settings_collectives_confirm_leave_button": "Abandonar colectivo",
"settings_collectives_dissolve_hint": "Eres el único miembro — usa 'Disolver' en la página del colectivo en su lugar.",
"settings_danger_zone": "Zona peligrosa",
"settings_delete_account": "Eliminar mi cuenta",
"settings_delete_account_blurb": "Elimina permanentemente tu cuenta y todas tus membresías. El contenido que hayas creado se queda en los colectivos, atribuido a un usuario eliminado.",
"settings_delete_account_modal_title": "¿Eliminar tu cuenta?",
"settings_delete_account_modal_body": "Esto es permanente. Lo que se borra: tu cuenta, tus membresías, tu idioma y tema guardados. Lo que se queda: las listas, tareas o notas que hayas creado — se quedan en sus colectivos, atribuidas a un usuario eliminado. Si eres el único admin de algún colectivo, el miembro más antiguo será promovido automáticamente. Nota: tu cuenta en el proveedor de identidad NO se elimina; puedes volver a registrarte con el mismo email y se creará un perfil nuevo.",
"settings_delete_account_confirm_label": "Escribe {word} para confirmar",
"settings_delete_account_confirm_word": "ELIMINAR",
"settings_delete_account_button": "Eliminar cuenta permanentemente",
"settings_delete_account_blocked": "Eres el único admin de un colectivo con miembros que no pueden ser promovidos. Promueve a alguien primero o elimina a los demás miembros.",
"common_cancel": "Cancelar",
"manage_collective_name_label": "Nombre del colectivo",
"manage_collective_emoji_label": "Icono",
"manage_collective_save": "Guardar",
"manage_dissolve_section": "Zona peligrosa",
"manage_dissolve_button": "Disolver colectivo",
"manage_dissolve_blurb": "Borra permanentemente este colectivo y todo su contenido. No se puede deshacer.",
"manage_dissolve_title": "¿Disolver {name}?",
"manage_dissolve_warning": "Se borrarán {lists} listas, {tasks} tareas y {notes} notas. Esta acción es irreversible.",
"manage_dissolve_confirm_label": "Escribe {name} para confirmar",
"manage_dissolve_confirm_button": "Disolver permanentemente",
"sidebar_create_collective": "+ Nuevo colectivo",
"create_collective_modal_title": "Nuevo colectivo",
"create_collective_modal_button": "Crear"
}