Migración desde el sistema PHP legacy (MariaDB) al sistema nuevo (PostgreSQL + Shopify).
| Entidad legacy | Volumen aprox. | Destino |
|---|---|---|
Usuarios (app_usuarios) |
~140k | Shopify customers + users (PostgreSQL) |
| Direcciones | varias por usuario | Shopify customer addresses |
| Pedidos históricos | grandes | Decisión pendiente: ¿importar a Shopify o a tabla legacy_orders? |
| Diseños subidos | ~varios miles | designs (PostgreSQL) + S3 |
| Reseñas | ~muchas | reviews (PostgreSQL) |
| Diseñadores | ~cientos | users con role=designer |
| Concursos / votaciones | histórico | contests, votes |
| Puntos Pampling Up | por usuario | reward_balances, user_levels |
| Cupones | varios | coupons |
Tailor entregó scripts CLI en apps/sync-db/:
# Test conexiones
pnpm sync-db:test-connection # MariaDB legacy
pnpm sync-db:test-postgresql-connection # PostgreSQL nuevo
pnpm sync-db:test-syncdb-connection # BD intermedia de sync
# Migraciones
pnpm sync-db:import-customers # Usuarios → Shopify + PostgreSQL
pnpm sync-db:import-legacy-passwords # Hashes MD5 → users.legacy_password_hash
pnpm sync-db:import-designs # Diseños → PostgreSQL + S3
| Script | Estado | Problemas conocidos |
|---|---|---|
import-customers |
Implementado por Tailor | El INSERT no rellena password (NOT NULL) → falla. Hay que parchear |
import-legacy-passwords |
Implementado por Tailor | Correcto |
import-designs |
Implementado | Probable, no validado |
import-orders |
No existe | Decisión pendiente sobre estrategia |
Por dependencias de FK en PostgreSQL:
users (a través de import-customers)admins (creados con seed-super-admin, no importados)addresses (vienen junto con import-customers o separadas)user_designers (perfiles públicos de diseñadores)reward_balances, user_levelsrewards, reward_transactionscouponsreferralsdesignsfavouritesreviewsvotessubscriptionsmoderationEl sistema soporta autenticación dual transparente al usuario:
users PostgreSQL.users.legacy_password_hash con el MD5 de la BD vieja.Detalle técnico completo: ver Usuarios y autenticación NOT NULL. El script import-customers` actualmente no rellena ese campo → el INSERT falla con violación de constraint.
| Opción | Cómo | Pros | Contras |
|---|---|---|---|
| A. Hash argon2 de random | password = argon2.hash(crypto.randomUUID()) por user |
Seguro, consistente con el patrón ya en uso para users auto-registrados | ~100ms por hash × 140k users ≈ 4-40 h (mitigar con paralelismo) |
| B. Marcador literal | 'LEGACY_PENDING' para todos |
Migración instantánea | Si algún código intenta argon2.verify revienta. Frágil |
| C. Hacer columna nullable | ALTER TABLE + guard en sign-in-admin-user.service.ts |
Semánticamente correcto | Requiere tocar código de Tailor + tests |
Recomendación: opción A. Es la que ya usa el flujo auto-register del storefront (route.ts línea 412 password: crypto.randomUUID()). Aplicar en el script import-customers.command.ts.
Dos enfoques posibles:
orders históricos en Shopify vía Admin API.legacy_orders en PostgreSQLPendiente de decisión.
Imágenes de diseños y avatars del legacy están en almacenamiento local del servidor PHP. Hay que:
pampling-web-staging-bucket para staging).Antes de cualquier migración masiva:
sanity dataset export develop backup-pre-migracion.tar.gz).Rollback en caso de problemas:
Pasos para validar que la migración salió bien:
users PostgreSQL vs app_usuarios MariaDB (excluyendo borrados lógicos).users con shopify_id IS NOT NULL.legacy_password_hash se limpia tras primer login exitoso.+, con tildes, etc.).import-customers.command.ts para rellenar password