Saltar al contenido
WebViewGold Del vibe coding a la App Store
Español
Consigue WebViewGold

Claude Code + privacidad

Eliminación de cuenta y exportación de datos con Claude Code: cumple la 5.1.1(v) de Apple y Google Play

Si los usuarios pueden crear una cuenta en tu app, Apple y Google exigen que también puedan eliminarla desde dentro de la app, y Google además quiere una página web para las solicitudes de eliminación. Claude Code puede construir la función en una tarde, pero solo cuando sabe dónde vive cada dato del usuario. Esta guía empieza por ese mapa de datos y luego construye la eliminación, una exportación para descargar mis datos y la limpieza dentro de la app WebViewGold.

Desde $109 de pago único por plataforma, o deja que nuestro equipo lo haga todo desde $698.

  • Garantía de aprobación – o te devolvemos el dinero en 14 días
  • Sin programar
  • Pago único, actualizaciones gratuitas
  • Soporte humano 24/7
  • Hecho en Alemania desde 2014 · ISO 27001

Qué exigen realmente las tiendas

Apple, directriz 5.1.1(v): si tu app permite crear cuentas, los usuarios deben poder iniciar la eliminación de su cuenta dentro de la app. Las indicaciones de Apple piden eliminar el registro de la cuenta y los datos personales asociados, no un interruptor de desactivación; puedes conservar los datos que la ley te obligue a guardar, y deberías decir a los usuarios cuánto tarda la eliminación. Si ofreces Sign in with Apple, revoca los tokens del usuario mediante la REST API de Apple cuando se elimine la cuenta. Las suscripciones compradas a través de Apple no se cancelan al eliminar la cuenta, así que explica a los usuarios cómo cancelarlas.

Google Play: las apps que permiten crear cuentas deben ofrecer la eliminación dentro de la app y un enlace web donde los usuarios puedan solicitarla sin reinstalar la app. Ese enlace se introduce en el formulario de Data safety, y la eliminación debe abarcar los datos asociados a la cuenta, salvo lo que declares que conservas. La guía de eliminación de cuenta en Google Play cubre la parte de la consola.

Exportación de datos: ninguna tienda la exige, pero leyes de privacidad como el RGPD dan a los usuarios derecho de acceso y de portabilidad, y un botón "Descargar mis datos" responde a esas solicitudes sin pasar por soporte. También es una buena prueba de tu mapa de datos: si el agente no puede exportarlo, probablemente tampoco pueda eliminarlo.

Qué hace Claude Code y qué haces tú

ÁreaClaude CodeTú
Mapa de datosBusca en modo plan en el código, las migraciones, las importaciones de SDK y los webhooks, y redacta DATA_MAP.mdAñadir lo que el código no puede mostrar (hojas de cálculo, bandeja de soporte, exportaciones manuales) y confirmar los plazos de conservación
CódigoInterfaz de ajustes, rutas de exportación y eliminación, helpers de limpieza, migraciones, tests, página /delete-accountRevisar, definir las variables de entorno en el hosting, desplegar
Consolas de las tiendasRedacta los cambios de la política de privacidad y las respuestas de Data safetyIntroducir la URL de eliminación en la Play Console, actualizar App Privacy en App Store Connect
WebViewGoldNada obligatorio; puede definir las opciones del descargador si los proyectos están en el repositorioUna nueva compilación si cambias los ajustes del descargador

Prompt 1: el mapa de datos, en modo plan

El modo plan permite a Claude Code leer y buscar en el repositorio sin editar nada. Guarda el resultado como DATA_MAP.md y corrígelo antes de continuar; este archivo es lo que hace que la eliminación sea completa.

Pégalo en Claude Code en modo plan (Shift+Tab)
Solo modo plan, no cambies ningún archivo. Necesitamos la eliminación de cuenta dentro de la app (directriz 5.1.1(v) de Apple y la política de eliminación de cuentas de Google Play) y una exportación para descargar mis datos. Primero construye un mapa de datos completo.

Busca en el código, las migraciones, los nombres de las variables de entorno, las importaciones de SDK, los cron jobs y los handlers de webhooks, y enumera cada lugar donde viven datos sobre un usuario: registros de autenticación, cada tabla con una columna user_id, owner_id o email y cómo referencia al usuario, buckets de almacenamiento y rutas de archivos, clientes y suscripciones de Stripe, clientes de RevenueCat, IDs de suscripción de OneSignal, tokens de Sign in with Apple, analítica y seguimiento de errores, herramientas de correo y newsletter, logs y copias de seguridad.

Para cada entrada indica: dónde vive, qué identificador la vincula al usuario, cómo eliminarla (cascada de clave foránea, llamada a una API o conservación con un motivo) y si debe ir en la exportación. Marca todo aquello de lo que no estés seguro. Presenta el resultado como una tabla en markdown que pueda guardar como DATA_MAP.md.

¡Estoy muy feliz de haber comprado esta aplicación! Documentación extremadamente fácil y excelente. Estaba en contacto con el servicio al cliente, respondieron muy rápido y de forma muy amigable. Resolvieron mi pregunta en un día. 10/10 lo recomendaría".

Nelis Geiger · CodeCanyon

Un mapa de datos típico para una app con Supabase

DatosCómo se eliminan¿En la exportación?
Usuario de autenticaciónauth.admin.deleteUser, último pasoID, correo, fecha de creación
Tablas de perfil y de contenidoClaves foráneas al usuario con ON DELETE CASCADESí
Archivos subidosAPI de Storage, por carpeta de usuario (el listado no es recursivo)Enlaces o los archivos
Cliente y suscripciones de StripeCancelar las suscripciones; conservar las facturas según exija la ley e indicarlo en /privacyPlan y lista de facturas
Suscripción de App Store / Google PlayNo puedes cancelarla tú; muestra cancelinapppurchase:// dentro de la appNombre del plan
Cliente de RevenueCatEliminación del cliente mediante la REST API de RevenueCatNo
IDs de suscripción de OneSignalEliminar tus filas guardadas; opcionalmente, el usuario de OneSignal mediante su APINo
Sign in with AppleRevocar el token en el endpoint de revocación de AppleNo
Analítica, seguimiento de errores, herramientas de correoAPI de eliminación del proveedor o conservación documentadaNormalmente no

Prompt 2: construir la eliminación y la exportación

Vuelve al modo de permisos predeterminado para revisar cada edición, o al modo accept-edits si prefieres revisar el diff completo al final.

Pégalo en Claude Code cuando DATA_MAP.md sea correcto
Implementa la eliminación de cuenta y la exportación de datos basándote en DATA_MAP.md. Nuestra app también se ejecuta dentro de apps nativas de iOS y Android creadas con WebViewGold (el user agent contiene WebViewGoldApp).

1. Ajustes > Cuenta: un botón "Descargar mis datos" y un botón "Eliminar cuenta".
2. Exportación: GET /api/account/export devuelve un único archivo JSON para el usuario con sesión iniciada con todas las entradas exportables del mapa, enviado con Content-Type application/json y Content-Disposition attachment; filename=my-data.json. Lánzala con un enlace normal a esa URL, no con una descarga mediante Blob o createObjectURL: dentro de la app, el descargador de WebViewGold reacciona a las extensiones de archivo y a las cabeceras Content-Disposition. Si una exportación puede ser grande, genérala en un job en segundo plano y envía por correo un enlace firmado que caduque a las 24 horas.
3. Eliminación: una pantalla de confirmación que explique qué se elimina, qué conservamos por motivos legales (facturas) y que las suscripciones de App Store o Google Play no se cancelan automáticamente. Dentro de la app, muestra un enlace "Gestionar suscripción" que navegue a cancelinapppurchase:// cuando el usuario tenga una suscripción de la tienda. Exige escribir DELETE.
4. POST /api/account/delete: autentica y después, en este orden, cancela las suscripciones de Stripe, elimina el cliente de RevenueCat, revoca los tokens de Sign in with Apple si los tenemos (REST API de Apple, /auth/revoke), elimina los archivos del almacenamiento, elimina las filas (da preferencia a ON DELETE CASCADE; añade una migración donde falte) y elimina el usuario de autenticación al final con el cliente admin. Solo en el servidor; la clave service-role nunca debe llegar al bundle del cliente. Haz que la ruta sea idempotente para que un reintento tras un fallo parcial termine el trabajo.
5. Tras el éxito: cierra la sesión y muestra /account-deleted. Dentro de la app, su botón "Listo" navega a reset:// para borrar las cookies y la caché que guarda el envoltorio.
6. Una página pública /delete-account para quien ya no tenga la app: explica el camino dentro de la app y ofrece un formulario de solicitud o una dirección de correo, funciona sin iniciar sesión y en una pantalla de 320 px.
7. Actualiza /privacy con los plazos de conservación y la URL /delete-account.
8. Tests para la ruta de eliminación: un usuario con datos en todas las tablas termina con cero filas, y llamar a la ruta por segunda vez sigue teniendo éxito.

Informa de los archivos cambiados, las migraciones y cada paso manual que tenga que hacer yo.

La ruta de eliminación, en el orden que no pierde IDs

Primero los terceros, mientras aún conoces los IDs de cliente; el usuario de autenticación al final, porque de él cuelgan la mayoría de las claves foráneas. Los helpers de account-cleanup envuelven las llamadas a Stripe, RevenueCat y Apple de tu mapa de datos.

typescript
// app/api/account/delete/route.ts  (solo servidor)
import { NextResponse } from "next/server";
import { createClient as createAdmin } from "@supabase/supabase-js";
import { createClient } from "@/lib/supabase/server";
import { cancelStripeSubscriptions, deleteRevenueCatCustomer, revokeAppleTokens } from "@/lib/account-cleanup";

export async function POST(req: Request) {
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "unauthorized" }, { status: 401 });

  const { confirm } = await req.json();
  if (confirm !== "DELETE") return NextResponse.json({ error: "confirmation missing" }, { status: 400 });

  const admin = createAdmin(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY!);

  // 1. Terceros, mientras los IDs aún existen (cada helper no hace nada si no hay nada que hacer)
  await cancelStripeSubscriptions(user.id);
  await deleteRevenueCatCustomer(user.id);
  await revokeAppleTokens(user.id);

  // 2. Archivos: list() no es recursivo, las carpetas anidadas necesitan su propia pasada
  const { data: files } = await admin.storage.from("uploads").list(user.id);
  if (files && files.length > 0) {
    await admin.storage.from("uploads").remove(files.map((f) => user.id + "/" + f.name));
  }

  // 3. Las filas se van con el usuario mediante ON DELETE CASCADE (ver DATA_MAP.md)
  // 4. El usuario de autenticación, al final
  const { error } = await admin.auth.admin.deleteUser(user.id);
  if (error) return NextResponse.json({ error: "delete failed, safe to retry" }, { status: 500 });

  return NextResponse.json({ ok: true });
}

Haz que la exportación se descargue dentro de la app

Dos pequeños ajustes deciden si el archivo llega al teléfono.

  1. Sirve una URL de archivo real

    La ruta de arriba devuelve JSON con una cabecera Content-Disposition attachment. Enlázala con un anchor normal; las descargas de Blob generadas con JavaScript no están cubiertas por la documentación del descargador de WebViewGold.

  2. iOS

    Activa autodownloader en Config.swift (descarga según las cabeceras Content-Disposition) o sirve el archivo en una URL que termine en .json y añade ".json" a extentionARY. Consulta la documentación del descargador de archivos para iOS.

  3. Android

    Activa AUTO_DOWNLOAD_FILES en Config.java o añade la extensión a downloadableExtension; requireStorage debe seguir en true si usas descargas. Consulta la documentación del descargador de archivos para Android.

  4. Compila una vez

    Son ajustes nativos, así que necesitan una compilación nueva. Todo lo demás de esta guía llega con tu próximo despliegue web. El Cloud Builder puede generar esa compilación sin tener Xcode ni Android Studio instalados en local.

Checklist de verificación

  • En las compilaciones de TestFlight y de pruebas internas, crea una cuenta nueva, añade contenido, sube un archivo y, si vendes suscripciones, compra una en el sandbox.
  • Toca "Descargar mis datos": el archivo llega al teléfono y contiene tu contenido, no un objeto vacío.
  • Toca "Eliminar cuenta": la confirmación explica las consecuencias e incluye la nota sobre la suscripción, el enlace "Gestionar suscripción" abre la pantalla de la tienda, escribir DELETE completa el flujo y la app muestra la confirmación.
  • Toca "Listo" en la confirmación: reset:// borra las cookies y la caché del envoltorio. Fíjate en lo que muestra después tu compilación y asegúrate de que sea un inicio limpio, no un error.
  • Intenta iniciar sesión de nuevo: la cuenta ya no existe. Una consulta por el ID de usuario devuelve cero filas en todas las tablas de DATA_MAP.md, y la carpeta de almacenamiento está vacía.
  • Con un usuario de prueba de Sign in with Apple, la app desaparece tras la eliminación de la lista de Sign in with Apple en los ajustes de esa Apple Account, lo que demuestra que el token se revocó.
  • Abre /delete-account en una ventana privada del navegador en un teléfono: funciona sin sesión iniciada, y la misma URL figura en el formulario de Data safety de la Play Console.

Errores frecuentes

  • Solo un borrado lógico. Un campo deleted_at es una desactivación. Los revisores y Google esperan que los datos desaparezcan, salvo la conservación que hayas declarado.
  • Eliminar primero el usuario de autenticación. Sin cascadas, quedan filas; con cascadas, pierdes los IDs que necesitabas para Stripe y RevenueCat. Primero los terceros, la autenticación al final.
  • Almacenamiento olvidado. Los avatares y los archivos subidos sobreviven a la eliminación de las filas. El mapa de datos existe precisamente para detectar esto.
  • Eliminar la cuenta demo del revisor. Los revisores pueden probar la eliminación con la cuenta que les diste. Indica en las notas para la revisión que pueden registrarse desde cero, y vuelve a crear la cuenta demo después de cada revisión.
  • Escondida tras el soporte. "Escríbenos para eliminar tu cuenta" como único camino incumple la 5.1.1(v) en la mayoría de las apps. El botón dentro de la app debe iniciar la eliminación.

Preguntas frecuentes

¿Basta con desactivar la cuenta?

No. Apple pide eliminar la cuenta y sus datos personales asociados, y Google Play exige que los datos se eliminen, no que solo se oculten. La desactivación puede ser una opción adicional, no la única.

¿Puedo conservar algunos datos tras la eliminación?

Sí, cuando tengas una obligación legal o un motivo legítimo, como las facturas por la normativa fiscal. Decláralo en tu política de privacidad y en el formulario de Data safety.

¿Puede la eliminación tardar unos días?

Un breve periodo de gracia es habitual. Inicia la eliminación en la app, dile al usuario exactamente cuándo desaparecerán los datos y consulta las indicaciones actuales de Apple sobre la eliminación de cuentas para usar la redacción que esperan los revisores.

¿Qué pasa con las suscripciones compradas en la app?

No puedes cancelar suscripciones de App Store o Google Play en nombre del usuario. Muestra un enlace "Gestionar suscripción" (cancelinapppurchase:// dentro de la app) y deja claro que el cobro continúa hasta que la cancele.

¿Qué formato debe usar la exportación?

Un formato estructurado y legible por máquina, como JSON o CSV. Un archivo JSON por cuenta es lo más fácil de generar, probar y explicar.

Tres formas de llevar tu app a las tiendas

El mismo resultado, con distinta cantidad de trabajo por tu parte. Las tres incluyen la garantía de aprobación y soporte humano 24/7.

Hazlo tú mismo

$109 por plataforma, pago único

La licencia de WebViewGold: un proyecto de Xcode o Android Studio listo para usar. Pega tu URL, define nombre e icono, activa funciones, compila y envía. Actualizaciones gratuitas para siempre.

Ver planes en la página principal

Full Service

$698 por plataforma $798

Envíanos tu URL y tu icono. Nuestro equipo configura, compila y entrega tu app en 72 horas, en marca blanca y con los proyectos fuente. Ambas plataformas por $1,158.

Detalles del Full Service Con tecnología de WeSetupYourWebViewApp

Precios de la Oferta de invierno válidos hasta el 31 de diciembre de 2026.

¿Listo para lanzar tu app?

Garantía de aprobación en App Store & Google Play – o te devolvemos el dinero en 14 días

¿Prefieres delegarlo? Full Service: configuramos, compilamos y entregamos en 72 horas, desde $698 por plataforma. ¿Preguntas? Chatea con nosotros 24/7.

Los reembolsos se conceden bajo las condiciones indicadas en nuestras FAQ: un rechazo por motivos ajenos al contenido por parte de Apple y/o Google, reclamado dentro de los 14 días posteriores a la compra.