Lolita Pank

Tech Stack - Lolita Pank

Headless Architecture: Next.js + WordPress + Vercel

Overview

This solution implements a headless CMS architecture that separates the backend (WordPress) from the frontend (Next.js), offering significant advantages over the traditional WordPress approach:

  • Greater security: Frontend and backend are physically separated
  • Better performance: Next.js with SSG/ISR generates ultra-fast pages
  • Scalability: Vercel automatically handles high traffic
  • Better UX: Instant SPA-like navigation
  • Superior SEO: Static pre-rendering with optimized metadata
  • Atomic deploy: Instant rollback if something fails

Technology Stack

Frontend (Next.js 14 + App Router)

  • Framework: Next.js 14 con App Router
  • Lenguaje: TypeScript
  • Hosting: Vercel (deploy automático desde Git)
  • Data Fetching: GraphQL via WPGraphQL
  • Generación de tipos: GraphQL Code Generator
  • Caché: Next.js ISR (Incremental Static Regeneration)
  • Imágenes: Next.js Image Optimization
  • Estilos: Tailwind CSS (recomendado) o CSS Modules

Repositorio: GitHub/GitLab (control de versiones + CI/CD)

Backend (WordPress Headless)

  • CMS: WordPress.org (auto-hospedado)
  • API: WPGraphQL + WPGraphQL SEO
  • E-commerce: WooCommerce con WPGraphQL for WooCommerce
  • Autenticación: WPGraphQL JWT Authentication
  • Custom Fields: Advanced Custom Fields PRO + WPGraphQL for ACF
  • Pagos: MercadoPago (integración custom vía REST API)
  • Hosting WordPress: Hostinger Business WordPress o similar
  • Seguridad: Wordfence Security + SSL + 2FA

Infrastructure and DevOps

  • Frontend Hosting: Vercel (CDN global, edge functions)
  • Backend Hosting: Hostinger Business WordPress
  • Database: MySQL (incluido en hosting WordPress)
  • Control de versiones: Git (GitHub/GitLab)
  • CI/CD: Vercel Git Integration (auto-deploy on push)
  • DNS: Vercel DNS o Cloudflare
  • SSL: Automático en ambos (Let’s Encrypt)

System Architecture

┌─────────────────────────────────────────────────────────────┐
│                         USUARIO                             │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                   VERCEL CDN (Edge Network)                  │
│  • Next.js App (SSG/ISR)                                    │
│  • Static pages cached globally                             │
│  • Imágenes optimizadas                                     │
└───────────────────────────┬─────────────────────────────────┘
                            │
                ┌───────────┴───────────┐
                ▼                       ▼
┌───────────────────────────┐  ┌──────────────────────────┐
│  WordPress GraphQL API    │  │  MercadoPago REST API    │
│  (Hostinger)              │  │  (Pagos)                 │
│  • WPGraphQL              │  │  • Procesamiento pagos   │
│  • WooCommerce            │  │  • Webhooks              │
│  • ACF                    │  └──────────────────────────┘
│  • JWT Auth               │
│  • MySQL Database         │
└───────────────────────────┘
                │
                ▼
┌───────────────────────────────────────────────────────────┐
│              SISTEMA DE BACKUPS (Triple Capa)              │
│  1. Hostinger Auto Backup (semanal)                        │
│  2. UpdraftPlus → Google Drive (diario DB, semanal full)  │
│  3. Manual mensual (WordPress DB + Next.js repo Git tags) │
└───────────────────────────────────────────────────────────┘


Data Flow

Editorial Content (Posts, Events, Artists, Galleries)

  1. Edición en WordPress (CMS)
    • Editor agrega/edita contenido en WordPress admin
    • Custom Post Types: Posts, Eventos, Artistas, Galerías
    • ACF Flexible Content para bloques personalizados
  2. Webhook de Actualización
    • WordPress trigger webhook en save_post
    • Llama a /api/revalidate en Vercel
  3. Revalidación Incremental
    • Next.js revalida solo las rutas afectadas
    • Nuevo contenido disponible en ~2-5 segundos
    • No requiere rebuild completo
  4. Servir al Usuario
    • Usuario recibe página estática pre-renderizada
    • Tiempo de carga <500ms desde edge CDN
    • Navegación SPA instantánea

E-commerce (Courses/Workshops)

  1. Gestión en WooCommerce
    • Admin crea/edita productos (cursos) en WordPress
    • Precios, descripción, cupos, fechas en ACF
  2. Catálogo en Next.js
    • Next.js fetcha productos vía WPGraphQL
    • Genera páginas estáticas /cursos/[slug]
    • ISR revalida cada 60 segundos (configurable)
  3. Flujo de Compra
    • Usuario navega catálogo en Next.js (fast)
    • Click “Inscribirse” → Formulario Next.js
    • Next.js API route procesa orden:
      • Crea orden en WooCommerce vía REST API
      • Genera preference en MercadoPago
      • Redirige a checkout MercadoPago
  4. Post-Pago
    • MercadoPago webhook notifica a Next.js /api/webhooks/mercadopago
    • Next.js actualiza estado de orden en WooCommerce
    • Envía email confirmación vía SendGrid/Resend
    • Usuario recibe acceso al dashboard

Next.js Project Structure

lolita-pank-next/
├── src/
│   ├── app/                          # App Router (Next.js 14)
│   │   ├── layout.tsx                # Root layout
│   │   ├── page.tsx                  # Homepage
│   │   ├── [[...slug]]/              # Catch-all para páginas dinámicas
│   │   │   └── page.tsx              # Template resolver
│   │   ├── cursos/                   # Catálogo de cursos
│   │   │   ├── page.tsx              # Listado
│   │   │   └── [slug]/
│   │   │       └── page.tsx          # Detalle curso
│   │   ├── archivo/                  # Archivo histórico
│   │   │   ├── page.tsx              # Página principal archivo
│   │   │   ├── eventos/
│   │   │   │   ├── page.tsx
│   │   │   │   └── [slug]/page.tsx
│   │   │   ├── artistas/
│   │   │   │   ├── page.tsx
│   │   │   │   └── [slug]/page.tsx
│   │   │   └── galerias/
│   │   │       ├── page.tsx
│   │   │       └── [slug]/page.tsx
│   │   ├── blog/                     # Editorial
│   │   │   ├── page.tsx
│   │   │   └── [slug]/page.tsx
│   │   ├── dashboard/                # Usuario inscrito
│   │   │   └── page.tsx
│   │   ├── api/                      # API Routes
│   │   │   ├── preview/route.ts      # Draft preview
│   │   │   ├── revalidate/route.ts   # Webhook revalidation
│   │   │   ├── checkout/route.ts     # Crear orden WC + MP
│   │   │   └── webhooks/
│   │   │       └── mercadopago/route.ts
│   │   ├── robots.ts                 # robots.txt dinámico
│   │   ├── sitemap.ts                # sitemap.xml dinámico
│   │   ├── not-found.tsx             # 404 page
│   │   └── middleware.ts             # Redirects handling
│   │
│   ├── components/
│   │   ├── templates/                # Page templates
│   │   │   ├── PageTemplate.tsx
│   │   │   ├── PostTemplate.tsx
│   │   │   ├── EventoTemplate.tsx
│   │   │   ├── ArtistaTemplate.tsx
│   │   │   └── GaleriaTemplate.tsx
│   │   ├── blocks/                   # ACF Flexible Content blocks
│   │   │   ├── HeroBlock.tsx
│   │   │   ├── TextBlock.tsx
│   │   │   ├── ImageGalleryBlock.tsx
│   │   │   └── VideoBlock.tsx
│   │   ├── navigation/
│   │   │   ├── Header.tsx
│   │   │   └── Footer.tsx
│   │   ├── curso/
│   │   │   ├── CursoCard.tsx
│   │   │   └── CursoCheckoutForm.tsx
│   │   └── common/
│   │       ├── SEO.tsx
│   │       └── Image.tsx
│   │
│   ├── lib/
│   │   ├── wordpress.ts              # GraphQL client
│   │   ├── woocommerce.ts            # WC REST API client
│   │   ├── mercadopago.ts            # MercadoPago SDK
│   │   └── auth.ts                   # JWT auth helpers
│   │
│   ├── queries/                      # GraphQL queries
│   │   ├── pages.ts
│   │   ├── posts.ts
│   │   ├── eventos.ts
│   │   ├── artistas.ts
│   │   ├── galerias.ts
│   │   ├── cursos.ts
│   │   └── navigation.ts
│   │
│   ├── gql/                          # Auto-generated types
│   │   ├── schema.gql
│   │   └── graphql.ts                # Generated TypeScript types
│   │
│   └── utils/
│       ├── seo.ts
│       ├── date.ts
│       └── format.ts
│
├── public/
│   └── assets/
│
├── .env.local                         # Environment variables
├── .env.production
├── next.config.js
├── codegen.ts                         # GraphQL codegen config
├── apollo.config.js                   # VS Code GraphQL extension
├── tsconfig.json
├── tailwind.config.js
└── package.json


WordPress Headless Configuration

Required Plugins

✓ WPGraphQL (core)
✓ WPGraphQL for Advanced Custom Fields
✓ WPGraphQL for SEO (Yoast integration)
✓ WPGraphQL JWT Authentication
✓ WPGraphQL for WooCommerce
✓ WooCommerce
✓ Yoast SEO
✓ Advanced Custom Fields PRO
✓ Redirection (con API habilitada)
✓ Wordfence Security
✓ UpdraftPlus (backups)
✓ Classic Editor (opcional)

wp-config.php

// Headless configuration
define('HEADLESS_SECRET', 'INSERT_RANDOM_SECRET_KEY');
define('HEADLESS_URL', '<https://lolitapank.com>'); // URL Next.js production
define('HEADLESS_DEV_URL', '<http://localhost:3000>'); // Local dev
 
// JWT Authentication
define('GRAPHQL_JWT_AUTH_SECRET_KEY', 'INSERT_RANDOM_JWT_KEY');
define('GRAPHQL_JWT_AUTH_CORS_ENABLE', true);
 
// WPGraphQL settings
define('GRAPHQL_DEBUG', false); // true solo en dev
 

functions.php (Custom Theme)

Ver el código PHP proporcionado en la documentación del ejemplo cms-wordpress. Incluye:

  • ✓ Registro de menús
  • ✓ Reescritura de preview links al frontend
  • ✓ Webhook de revalidación a Vercel
  • ✓ REST endpoints para sitemap

Custom Post Types (Historical Archive)

Eventos (custom post type: ‘evento’)

Campos ACF:

  • fecha_evento (Date Picker)
  • ubicacion (Text)
  • descripcion (Wysiwyg)
  • galeria_fotos (Gallery)
  • videos_youtube (Repeater → URL)
  • instagram_embeds (Repeater → oEmbed)
  • artistas_participantes (Post Object → relación con Artistas)

GraphQL Query:

query GetEvento($slug: ID!) {
  evento(id: $slug, idType: SLUG) {
    title
    eventoFields {
      fechaEvento
      ubicacion
      descripcion
      galeriaFotos {
        sourceUrl
        altText
      }
      videosYoutube {
        url
      }
      instagramEmbeds {
        embed
      }
      artistasParticipantes {
        ... on Artista {
          title
          slug
        }
      }
    }
  }
}
 

Artistas (custom post type: ‘artista’)

Campos ACF:

  • biografia (Wysiwyg)
  • foto_perfil (Image)
  • portfolio (Gallery)
  • redes_sociales (Group → Instagram, Facebook, Twitter)
  • obra_destacada (Gallery)

Galerías (custom post type: ‘galeria’)

Campos ACF:

  • fecha_exposicion (Date Picker)
  • descripcion (Wysiwyg)
  • imagenes (Gallery)
  • curador (Text)

Headless E-commerce System

Complete Purchase Flow

1. Crear Producto en WooCommerce

Producto WooCommerce: "Taller de Serigrafía"
- Precio: $50 USD
- SKU: CURSO-SER-001
- Stock: 15 (cupos)
- ACF Custom Fields:
  - fecha_inicio: 2025-12-01
  - duracion: "8 semanas"
  - horario: "Sábados 10am-2pm"
  - instructor: "Ana García"
  - nivel: "Principiante"

2. Next.js Fetcha Cursos

// src/queries/cursos.ts
export const GET_CURSOS = gql`
  query GetCursos {
    products(first: 100, where: { status: "publish" }) {
      nodes {
        id
        databaseId
        name
        slug
        price
        regularPrice
        stockQuantity
        image {
          sourceUrl
        }
        cursoFields {
          fechaInicio
          duracion
          horario
          instructor
          nivel
        }
      }
    }
  }
`;
 

3. Página de Curso (/cursos/[slug])

// src/app/cursos/[slug]/page.tsx
import { getCursoBySlug } from '@/queries/cursos';
import CursoCheckoutForm from '@/components/curso/CursoCheckoutForm';
 
export async function generateStaticParams() {
  const cursos = await getAllCursos();
  return cursos.map((curso) => ({ slug: curso.slug }));
}
 
export default async function CursoPage({ params }) {
  const curso = await getCursoBySlug(params.slug);
 
  return (
    <>
      <h1>{curso.name}</h1>
      <p>Precio: ${curso.price}</p>
      <p>Cupos disponibles: {curso.stockQuantity}</p>
      {/* Detalles del curso... */}
 
      <CursoCheckoutForm cursoId={curso.databaseId} />
    </>
  );
}
 
// ISR: Revalidar cada 60 segundos
export const revalidate = 60;
 

4. Checkout Form (Next.js)

// src/components/curso/CursoCheckoutForm.tsx
'use client';
 
export default function CursoCheckoutForm({ cursoId }) {
  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
 
    // Crear orden en WooCommerce + Preference en MercadoPago
    const response = await fetch('/api/checkout', {
      method: 'POST',
      body: JSON.stringify({
        cursoId,
        nombre: formData.get('nombre'),
        email: formData.get('email'),
        telefono: formData.get('telefono'),
      }),
    });
 
    const { checkoutUrl } = await response.json();
 
    // Redirigir a MercadoPago
    window.location.href = checkoutUrl;
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <input name="nombre" required />
      <input name="email" type="email" required />
      <input name="telefono" required />
      <button type="submit">Inscribirse y Pagar</button>
    </form>
  );
}
 

5. API Route: Crear Orden + MercadoPago Preference

// src/app/api/checkout/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { createWooCommerceOrder } from '@/lib/woocommerce';
import { createMercadoPagoPreference } from '@/lib/mercadopago';
 
export async function POST(req: NextRequest) {
  const { cursoId, nombre, email, telefono } = await req.json();
 
  // 1. Crear orden en WooCommerce
  const wcOrder = await createWooCommerceOrder({
    product_id: cursoId,
    customer: {
      first_name: nombre,
      email,
      phone: telefono,
    },
    status: 'pending', // Pending payment
  });
 
  // 2. Crear preference en MercadoPago
  const mpPreference = await createMercadoPagoPreference({
    items: [
      {
        title: wcOrder.line_items[0].name,
        quantity: 1,
        unit_price: parseFloat(wcOrder.total),
      },
    ],
    back_urls: {
      success: `${process.env.NEXT_PUBLIC_BASE_URL}/checkout/success?order=${wcOrder.id}`,
      failure: `${process.env.NEXT_PUBLIC_BASE_URL}/checkout/failure`,
      pending: `${process.env.NEXT_PUBLIC_BASE_URL}/checkout/pending`,
    },
    notification_url: `${process.env.NEXT_PUBLIC_BASE_URL}/api/webhooks/mercadopago`,
    external_reference: wcOrder.id.toString(), // Link WC order to MP payment
  });
 
  return NextResponse.json({
    checkoutUrl: mpPreference.init_point,
    orderId: wcOrder.id,
  });
}
 

6. Webhook MercadoPago → Actualizar Orden

// src/app/api/webhooks/mercadopago/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { getMercadoPagoPayment } from '@/lib/mercadopago';
import { updateWooCommerceOrder } from '@/lib/woocommerce';
import { sendConfirmationEmail } from '@/lib/email';
 
export async function POST(req: NextRequest) {
  const body = await req.json();
 
  if (body.type === 'payment') {
    const paymentId = body.data.id;
    const payment = await getMercadoPagoPayment(paymentId);
 
    if (payment.status === 'approved') {
      const wcOrderId = payment.external_reference;
 
      // Actualizar orden en WooCommerce
      await updateWooCommerceOrder(wcOrderId, {
        status: 'completed',
        payment_method: 'mercadopago',
        transaction_id: paymentId,
      });
 
      // Enviar email de confirmación
      await sendConfirmationEmail({
        orderId: wcOrderId,
        email: payment.payer.email,
      });
    }
  }
 
  return NextResponse.json({ received: true });
}
 

Backup System (Headless Architecture)

Specific Challenge of the Headless Approach

In a headless architecture, we have TWO systems that need backup:

  1. WordPress Backend (CMS + Database)
  2. Next.js Frontend (Source code)

The advantage is that if one fails, the other keeps working. But we need a backup strategy for both.


Capa 1: WordPress Backend Backups (Triple Sistema)

A. Hosting Automático (Hostinger)

  • Frecuencia: Semanal
  • Retención: 30 días
  • Contenido: Files + Database completos
  • Pros: Automático, incluido
  • Cons: Solo 4 snapshots, restauración lenta

B. UpdraftPlus → Google Drive

  • Frecuencia:

    • Database: Diaria (00:00 AM)
    • Files completos: Semanal (Domingo 02:00 AM)
  • Retención: 30 copias

  • Contenido:

    • /wp-content/uploads/ (imágenes, media)
    • Database completa (posts, users, products, orders)
    • /wp-content/themes/ (theme custom)
    • /wp-content/plugins/ (configs)
  • Configuración:

    UpdraftPlus Settings:
    ✓ Files backup schedule: Weekly (Sunday 2am)
    ✓ Database backup schedule: Daily (12am)
    ✓ Remote Storage: Google Drive
    ✓ Retain: 30 backups
    ✓ Email notifications: admin@lolitapank.com
    
    

C. Manual Mensual (Control Total)

  • Frecuencia: Primer lunes de cada mes
  • Método:
    1. Login a WordPress admin
    2. UpdraftPlus → “Backup Now”
    3. Descargar todos los archivos localmente
    4. Almacenar en disco duro externo + Google Drive personal
    5. Etiquetado: lolitapank-backup-2025-01-01.zip
  • Checklist:
    • Database (.sql.gz)
    • Uploads folder (.zip)
    • Plugins (.zip)
    • Themes (.zip)
    • WordPress core files

Script de verificación (ejecutar mensual):

# Verificar que backups existen en Google Drive
curl -X GET "<https://www.googleapis.com/drive/v3/files?q=name> contains 'backup'" \\
  -H "Authorization: Bearer YOUR_TOKEN"
 

Capa 2: Next.js Frontend Backups (Git + Vercel)

A. Control de Versiones Git (GitHub/GitLab)

Ventaja principal: El código Next.js vive en Git, por lo que NUNCA se puede perder.

# Repositorio
<https://github.com/lolitapank/website>
 
# Branching strategy
main Producción (Vercel auto-deploy)
staging Testing (Vercel preview)
dev Desarrollo activo
 
# Tags para releases importantes
v1.0.0-launch       (Lanzamiento inicial)
v1.1.0-archivo      (Sistema archivo implementado)
v1.2.0-ecommerce    (Integración MercadoPago)
 

Backup process:

  1. Todo cambio se commitea a Git
  2. Git está hosteado en GitHub (servers redundantes)
  3. Developer mantiene clone local
  4. Cliente puede clonar repo en cualquier momento

Recuperación: Si Vercel desaparece, clone repo + deploy a Netlify/Cloudflare Pages en 10 minutos.

B. Vercel Deployment History

  • Retención: Todos los deploys históricos (ilimitado en plan Pro)
  • Rollback: 1-click rollback a cualquier deploy anterior
  • Snapshots: Cada deploy es un snapshot inmutable
  • Preview URLs: Cada commit genera preview URL permanente
Ejemplo:
Commit abc123 → Deploy exitoso → URL: lolitapank-abc123.vercel.app
Commit def456 → Deploy con bug → Rollback a abc123 en 5 segundos

C. Manual Mensual (Paranoia Extra)

Frecuencia: Primer lunes del mes (junto con WordPress backup)

#!/bin/bash
# backup-frontend.sh
 
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="$HOME/lolitapank-backups/$DATE"
 
# 1. Clone fresh del repo
git clone <https://github.com/lolitapank/website> $BACKUP_DIR/repo
 
# 2. Export de variables de entorno (desde Vercel dashboard)
# Manual: Vercel Dashboard → Settings → Environment Variables → Export
 
# 3. Backup de .env.local (encrypted)
gpg -c $BACKUP_DIR/.env.local
 
# 4. Crear tarball
tar -czf lolitapank-frontend-$DATE.tar.gz $BACKUP_DIR
 
# 5. Upload a Google Drive (via rclone)
rclone copy lolitapank-frontend-$DATE.tar.gz gdrive:/backups/
 
echo "✓ Frontend backup completed: $DATE"
 

Capa 3: Assets y Media (WordPress uploads)

Challenge: Las imágenes del archivo histórico están en WordPress /wp-content/uploads/.

Solución: Next.js usa next/image con remotePatterns apuntando a WordPress.

// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'cms.lolitapank.com', // WordPress backend
        pathname: '/wp-content/uploads/**',
      },
    ],
  },
};
 

Backup de imágenes:

  • Incluidas en UpdraftPlus backups (Capa 1B)
  • Manual mensual descarga /wp-content/uploads/ completo
  • Opcional: Sync automático a AWS S3/Cloudinary para redundancia extra

Migración futura a CDN (opcional, Fase 2):

WordPress Uploads → Cloudinary/ImageKit
- Auto-upload on WordPress media upload
- Next.js Image apunta a CDN
- Ventaja: Imágenes sobreviven incluso si WordPress muere


Monitoring and Alert System

A. Uptime Monitoring (UptimeRobot)

Monitores configurados:

  1. Frontend Next.js (https://lolitapank.com)
    • Check cada 5 minutos
    • Alerta si down >2 minutos
    • Notificar: Email + SMS
  2. WordPress GraphQL API (https://cms.lolitapank.com/graphql)
    • Check cada 10 minutos
    • Alerta si response time >5s o down
    • Notificar: Email
  3. Keyword monitoring:
    • Homepage debe contener “Lolita Pank”
    • GraphQL debe responder {"data":...}

B. Backup Health Monitoring

Script automático (cron diario):

#!/bin/bash
# check-backups.sh (ejecutar diario vía cron)
 
# 1. Check que UpdraftPlus corrió hoy
LAST_BACKUP=$(wp updraftplus last-backup-time)
HOURS_AGO=$(( ($(date +%s) - $LAST_BACKUP) / 3600 ))
 
if [ $HOURS_AGO -gt 26 ]; then
  # Backup tiene más de 26 horas, alertar
  curl -X POST <https://api.sendgrid.com/v3/mail/send> \\
    -H "Authorization: Bearer $SENDGRID_KEY" \\
    -d '{
      "to": "admin@lolitapank.com",
      "subject": "⚠️ ALERTA: Backup de WordPress no corrió",
      "text": "El backup diario de UpdraftPlus no se ejecutó. Verificar."
    }'
fi
 
# 2. Check que archivos existen en Google Drive
# (requiere rclone configurado)
BACKUP_COUNT=$(rclone ls gdrive:/backups/ | wc -l)
 
if [ $BACKUP_COUNT -lt 5 ]; then
  # Menos de 5 backups en Drive, alertar
  echo "⚠️ Solo $BACKUP_COUNT backups en Google Drive"
fi
 

Ejecutar vía cron:

# crontab -e
0 8 * * * /home/lolitapank/scripts/check-backups.sh
 

C. Vercel Deployment Monitoring

Vercel notifica automáticamente vía email/Slack cuando:

  • ✓ Deploy exitoso
  • ✗ Deploy falló (build error)
  • ⚠️ Deploy con warnings

Integración Slack (opcional):

Vercel → Slack integration
Canal: #website-deploys

Mensaje ejemplo:
✅ Deployed lolitapank.com
   Commit: abc123 "Fix: corregir galería eventos"
   Time: 45s
   URL: <https://lolitapank.com>


Disaster Recovery Procedure

Escenario 1: WordPress Muerto (hosting caído, hacked, corrupto)

Impacto: ⚠️ Medio

  • Frontend Next.js sigue funcionando (Vercel independiente)
  • Contenido existente sigue visible (páginas cacheadas)
  • NO se puede editar contenido nuevo
  • NO se pueden procesar compras nuevas

Recuperación:

Tiempo: 2-4 horas

1. Contratar nuevo hosting WordPress (30 min)
   → Hostinger, SiteGround, o similar

2. Instalar WordPress limpio (10 min)
   → Versión misma que backup

3. Restaurar desde UpdraftPlus (45-90 min)
   → Plugins instalados
   → Restore database
   → Restore files

4. Actualizar DNS de GraphQL API (15 min)
   → cms.lolitapank.com → nuevo IP
   → TTL de 5 min para propagación rápida

5. Test de funcionalidad (30 min)
   → GraphQL queries funcionan
   → Login WordPress OK
   → WooCommerce operativo

6. Revalidar cache Next.js (5 min)
   → Trigger /api/revalidate?tag=wordpress
   → Todo el contenido refresca desde nuevo WordPress

✅ Sitio 100% operativo

Prevención de pérdida de datos:

  • Último backup diario (máximo 24 horas de contenido perdido)
  • Si hay contenido crítico del día, recuperar desde backup manual

Escenario 2: Vercel Muerto (empresa cerró, cuenta cancelada, bug catastrófico)

Impacto: 🔴 Alto

  • Frontend Next.js down
  • WordPress backend sigue funcionando
  • Contenido existe pero no se puede ver

Recuperación:

Tiempo: 15-30 minutos

1. Clone repositorio Git (2 min)
   git clone <https://github.com/lolitapank/website>
   cd website

2. Install dependencies (3 min)
   npm install

3. Deploy a alternativa (10-15 min)
   Opciones:
   a) Netlify: netlify deploy --prod
   b) Cloudflare Pages: pages:deploy
   c) AWS Amplify: amplify push
   d) Hosting propio: npm run build && npm start

4. Actualizar DNS (5 min)
   lolitapank.com A record → nuevo proveedor

5. Configurar variables de entorno (5 min)
   - NEXT_PUBLIC_WORDPRESS_API_URL
   - HEADLESS_SECRET
   - Etc. (copiar desde backup .env)

✅ Sitio 100% operativo en nuevo host

Ventaja del enfoque Next.js: El código está en Git, portabilidad total entre proveedores.

Escenario 3: AMBOS Muertos (Catástrofe Total)

Impacto: 🔴🔴 Crítico

  • Todo el sitio down
  • Requiere reconstrucción completa

Recuperación:

Tiempo: 3-5 horas

1. Recuperar WordPress (Escenario 1)
   → 2-4 horas

2. Recuperar Next.js (Escenario 2)
   → 15-30 minutos

3. Reconectar ambos sistemas
   → Update environment variables
   → Test GraphQL connectivity

4. Verificación completa
   → Test e-commerce flow
   → Test preview/draft
   → Test revalidation webhooks

✅ Sitio 100% restaurado

Probabilidad: <0.001% Requiere que fallen simultáneamente:

  • Vercel (CDN global, 99.99% uptime)
  • Git remote (GitHub, servers redundantes)
  • WordPress hosting
  • Google Drive (99.9% uptime)
  • Backup local en disco duro

Escenario 4: Pérdida de Acceso a Credenciales

Impacto: 🟡 Medio

  • No se puede acceder a servicios pero todo funciona

Recuperación:

1. WordPress admin password:
   → Reset via email
   → O via phpMyAdmin (hosting panel)

2. Vercel account:
   → Reset password via email
   → 2FA recovery codes (guardados en backup)

3. GitHub access:
   → Reset password
   → SSH keys en backup

4. Hosting panel:
   → Contact support
   → ID verification

5. MercadoPago API keys:
   → Regenerar en dashboard MP
   → Update en Vercel env vars

Prevención:

  • Documento “Credenciales Master” (encrypted) en Google Drive
  • 2FA recovery codes impresos y guardados físicamente
  • Email de recuperación secundario configurado

Monthly Maintenance Checklist

Cliente ejecuta (15 minutos/mes):

□ Verificar que sitio está online (lolitapank.com)
□ Verificar que WordPress admin accesible (cms.lolitapank.com/wp-admin)
□ UpdraftPlus: Verificar último backup (debe ser <24 horas)
□ UpdraftPlus: "Backup Now" + Descargar local
□ Guardar backup en disco duro externo
□ Ejecutar script check-backups.sh
□ Review UptimeRobot status (verificar sin alertas)
□ Update WordPress core si disponible
□ Update plugins si disponible (test en staging primero)
□ Git: Create tag para release mensual (v1.X.0)
□ Revisar Google Drive: Confirmar >10 backups existen
□ Test compra de prueba en MercadoPago (sandbox)
□ Verificar emails de confirmación funcionan
□ Revisar Vercel dashboard (sin deploys fallidos)
 

Developer ejecuta (opcional, 30 min/mes):

□ Review Vercel analytics (performance)
□ Review WordPress slow queries
□ Optimizar imágenes si necesario
□ Update dependencies Next.js (npm outdated)
□ Security scan (npm audit)
□ Check lighthouse score (>90)
□ Review error logs (Vercel + WordPress)
□ Test preview/draft mode
□ Review backup storage costs (Google Drive)
 

Comparison: Traditional WordPress vs Headless Next.js

AspectoWordPress TradicionalHeadless Next.js
Seguridad⚠️ WordPress expuesto a internet, vulnerable a ataques✅ WordPress oculto, solo GraphQL API expuesta
Performance🐢 ~2-4s carga inicial, cada página genera server-side🚀 <500ms desde CDN, páginas pre-renderizadas
Escalabilidad⚠️ Requiere upgrade hosting para tráfico alto✅ Vercel escala automáticamente, sin límite
Backups✅ Backups incluidos en el ejemplo tradicional✅ Doble sistema: WordPress + Git
Costo hosting~$60-80/año (hosting único)~$80-100/año (WordPress host + Vercel free/Pro)
Developer Experience⚠️ PHP, limited type safety✅ TypeScript, modern React, hot reload
SEO✅ Yoast SEO integrado✅ Next.js metadata API, igual o mejor
Mobile Performance🐢 Lighthouse score ~60-70🚀 Lighthouse score ~95-100
Vendor Lock-in⚠️ Difícil migrar desde WordPress✅ Frontend portable (Git), backend portable (WordPress standard)
Time to Interactive~4-6s~0.5-1s
Admin UX✅ WordPress admin familiar✅ Mismo WordPress admin (no cambia)
E-commerce✅ WooCommerce nativo con themes⚠️ Requiere integración custom (más trabajo dev)
Learning Curve✅ Fácil para no-developers⚠️ Requiere developer con conocimiento React

Veredicto:

  • Traditional WordPress: Mejor para equipos sin developer, presupuesto mínimo, setup rápido
  • Headless Next.js: Mejor para performance extremo, escalabilidad, modern UX, SEO competitivo

Para Lolita Pank:

  • Si tienen developer en equipo o presupuesto para contratar → Headless Next.js (mejor long-term)
  • Si zero budget y auto-gestión total → Traditional WordPress (más simple)

Comparative Costs

Traditional WordPress Stack

Hostinger Business WordPress: $60-80/año
Dominio: $12/año
Plugins premium: $0 (todos gratuitos en propuesta)
TOTAL: ~$72-92/año

Headless Next.js Stack

WordPress Hosting (Hostinger Business): $60-80/año
Vercel Hobby (para proyectos pequeños): $0/año
Vercel Pro (para producción, recomendado): $240/año ($20/mes)
Dominio: $12/año
GitHub (repos privados): $0/año
Google Drive (15GB free): $0/año
TOTAL Hobby: ~$72-92/año (igual que tradicional)
TOTAL Pro: ~$312-332/año

Desarrollo inicial:

  • Traditional WordPress: ~75-95 horas (según propuesta)
  • Headless Next.js: ~95-120 horas (+20-25 horas por complejidad integración)
    • Diferencia: ~5,200-6,500 MXN extra

Recomendación:

  • Fase 1 (lanzamiento): Traditional WordPress (menor costo, más rápido)
  • Fase 2 (6-12 meses después): Migrar a Headless si escalan y necesitan performance

O empezar Headless si:

  • Esperan >1000 visitas/día en primer año
  • Presupuesto permite $300-350 USD/año hosting
  • Tienen developer React en equipo
  • Performance y SEO son prioridad #1

Environment Variables (.env.local)

# WordPress GraphQL API
NEXT_PUBLIC_WORDPRESS_API_URL=https://cms.lolitapank.com/graphql
NEXT_PUBLIC_WORDPRESS_API_HOSTNAME=cms.lolitapank.com
 
# Frontend URL
NEXT_PUBLIC_BASE_URL=https://lolitapank.com
 
# Headless authentication
HEADLESS_SECRET=insert_random_secret_key_min_32_chars
 
# WordPress credentials (para preview/draft)
WP_USER=preview_user
WP_APP_PASS=abcd 1234 efgh 5678
 
# WooCommerce REST API
WC_CONSUMER_KEY=ck_abc123...
WC_CONSUMER_SECRET=cs_xyz789...
 
# MercadoPago
MERCADOPAGO_ACCESS_TOKEN=APP_USR-1234567...
MERCADOPAGO_PUBLIC_KEY=APP_USR-abc123...
 
# Email (SendGrid/Resend)
SENDGRID_API_KEY=SG.abc123...
EMAIL_FROM=noreply@lolitapank.com
 
# Analytics (opcional)
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
 

Next Implementation Steps

Fase 0: Planning & Setup (Semana 0-1)

□ Decisión final: Traditional vs Headless
□ Si Headless → Contratar Vercel Pro plan
□ Setup repositorio Git (GitHub)
□ Configurar WordPress en Hostinger
□ Instalar plugins requeridos
□ Configurar wp-config.php
□ Crear custom theme con functions.php
□ Setup Custom Post Types (Eventos, Artistas, Galerías)
□ Test GraphQL API funcionando

Fase 1: Next.js Base Setup (Semana 1-2)

□ Create Next.js 14 project con App Router
□ Configurar TypeScript + ESLint + Prettier
□ Install dependencias: graphql, @apollo/client, etc.
□ Setup GraphQL Code Generator (codegen.ts)
□ Configurar next.config.js (images, redirects)
□ Implementar WordPress GraphQL client
□ Setup Layout + Navigation (Header/Footer)
□ Implementar catch-all route [[...slug]]
□ Test: Homepage rendering desde WordPress

Fase 2: Core Functionality (Semana 3-5)

□ Implementar templates: Page, Post, Evento, Artista, Galería
□ Implementar /api/preview (Draft mode)
□ Implementar /api/revalidate (ISR webhook)
□ Setup middleware.ts (redirects handling)
□ Implementar robots.ts + sitemap.ts
□ Deploy a Vercel staging
□ Test preview mode end-to-end
□ Test revalidation funcionando

Fase 3: E-commerce Integration (Semana 6-7)

□ Install WooCommerce + WPGraphQL for WooCommerce
□ Crear productos test (3-5 cursos)
□ Implementar /cursos/[slug] pages
□ Implementar CursoCheckoutForm component
□ Setup MercadoPago SDK + credentials
□ Implementar /api/checkout (crear orden WC + MP preference)
□ Implementar /api/webhooks/mercadopago
□ Test compra completa sandbox
□ Test emails confirmación
□ Switch to MercadoPago producción
□ Test compra real

Fase 4: Archivo Histórico (Semana 8-9)

□ Importar contenido CSV (eventos, artistas, galerías)
□ Implementar templates específicos (EventoTemplate, etc.)
□ Implementar página /archivo con filtros
□ Implementar búsqueda (Algolia o built-in)
□ Optimizar galerías (lazy load, lightbox)
□ Test responsive mobile

Fase 5: Testing & Launch (Semana 10-11)

□ Testing exhaustivo (ver propuesta original)
□ Setup UptimeRobot monitors
□ Setup sistema triple de backups
□ Test recuperación de backup
□ Capacitación cliente (2 sesiones)
□ Preparar documentación
□ Pre-launch checklist
□ DNS cutover
□ Launch 🚀
□ Monitoreo 72 horas


Client Documentation Deliverables

1. Manual de Operación Diaria

- Cómo publicar blog posts
- Cómo crear/editar cursos
- Cómo agregar eventos al archivo
- Cómo agregar artistas nuevos
- Cómo gestionar inscripciones
- Cómo responder consultas

2. Manual de Sistema de Backups

- Verificar backups automáticos
- Descargar backup manual mensual
- Verificar alertas UptimeRobot
- Checklist mensual mantenimiento

3. Manual de Recuperación ante Desastres

- Escenario 1: WordPress muerto → Procedimiento paso a paso
- Escenario 2: Vercel muerto → Procedimiento paso a paso
- Escenario 3: Ambos muertos → Procedimiento completo
- Contactos de emergencia

4. Manual Técnico para Developers (Futuro)

- Arquitectura del sistema
- Setup local development
- Deploy process
- Agregar nuevos Custom Post Types
- Agregar nuevos templates
- Troubleshooting común


Conclusion

This Headless Next.js + WordPress architecture offers:

Performance superior: <500ms load time vs 2-4s tradicional ✅ Seguridad mejorada: WordPress no expuesto directamente ✅ Escalabilidad automática: Vercel CDN global ✅ Backup robusto: Sistema doble (WordPress + Git) ✅ Modern DX: TypeScript, React, hot reload ✅ Portabilidad total: Frontend portable, backend WordPress standard ✅ SEO excelente: Pre-rendering estático + metadata API

Trade-offs: ⚠️ Mayor complejidad inicial (requiere developer React) ⚠️ Costo ligeramente superior (~$240/año extra si Vercel Pro) ⚠️ E-commerce requiere integración custom (vs WooCommerce nativo)

Ideal para Lolita Pank si:

  • Tienen presupuesto para Vercel Pro (~$300-350/año total)
  • Tienen o pueden contratar developer familiarizado con Next.js/React
  • Priorizan performance, escalabilidad y modern UX
  • Planean escalar significativamente en próximos 2 años

Alternativa: Empezar con Traditional WordPress (propuesta original) y migrar a Headless en 6-12 meses si el proyecto tiene éxito y requiere mayor performance/escala.