Files
fspm-web/docker-entrypoint.sh
Uriel JarethandClaude Opus 5 01b817d098 feat: sitio comercial FSPM con micro CRM interno
Sitio público orientado a venta consultiva e implementación de las
recomendaciones de la auditoría de marca y mercado:

- Inicio con tres rutas (industria, riesgo, cumplimiento) y clasificador
  de riesgo en el héroe, contra el hallazgo de que el visitante tenía que
  inferir qué solución le correspondía.
- Cinco páginas por segmento prioritario y catálogo comparable por clase
  de fuego, capacidad y agente.
- Los claims sin evidencia por modelo quedan aislados y se presentan como
  compromiso de documentación, nunca como característica del producto.
- SEO técnico completo: metadatos por página, sitemap derivado de los
  datos, JSON-LD, iconos y tarjeta social generadas.

Micro CRM:

- Captura por formulario embebido y por widget de WhatsApp que registra
  antes de abrir la conversación.
- Atribución de primer toque que sobrevive a la navegación.
- Deduplicación de contacto; un mismo contacto acumula oportunidades.
- Motor de asignación por reglas con reparto por turno de respaldo.
- Panel con dos roles de alcance distinto, tablero analítico, bitácora,
  pedidos y reglas. No enlazado desde el sitio público y con noindex.

Empaquetado en Docker multietapa con la base de demostración horneada en
la imagen y el volumen de datos separado, para que los leads capturados
sobrevivan a los redespliegues.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 00:07:20 -06:00

86 lines
3.3 KiB
Bash

#!/bin/sh
# =============================================================================
# Punto de entrada del contenedor de FSPM.
#
# Hace tres cosas antes de arrancar el servidor, en este orden:
#
# 1. Asegura que exista la base de datos en el volumen. Si el volumen viene
# vacío, copia la base de demostración que se horneó en la imagen durante
# la construcción.
# 2. Aplica el esquema con `prisma db push`.
# 3. Entrega el control al servidor de Next con `exec`, para que Next quede
# como PID 1 y reciba las señales de parada de Docker.
#
# CÓMO DETECTA QUE YA ESTÁ SEMBRADA
#
# Por la existencia del archivo de base de datos en el volumen ($BD).
# Si existe, no se toca su contenido: ni se copia la base de demostración
# encima, ni se ejecuta ningún seed.
#
# Y no puede duplicar el seed por una razón más fuerte que una comprobación:
# el seed no se ejecuta aquí. `prisma/seed.ts` es destructivo —borra todas las
# tablas antes de reconstruirlas— y `tsx`, que lo ejecuta, es dependencia de
# desarrollo y no está en esta imagen. La siembra ocurrió una única vez, en la
# etapa de construcción. Lo que hace este script es copiar un archivo.
#
# $MARCADOR es solo una traza legible con la fecha del primer arranque, para
# que quien opere el servidor pueda distinguir una base heredada de una nueva.
# No se usa como condición.
# =============================================================================
set -e
DIR_DATOS="/app/data"
BD="${DIR_DATOS}/fspm.db"
MARCADOR="${DIR_DATOS}/.sembrado"
SEMILLA="/app/semilla/fspm.db"
log() {
echo "[fspm] $1"
}
# --- 1. base de datos en el volumen ------------------------------------------
if [ ! -d "$DIR_DATOS" ]; then
log "el directorio de datos no existe, se crea: ${DIR_DATOS}"
mkdir -p "$DIR_DATOS"
fi
if [ ! -w "$DIR_DATOS" ]; then
log "ERROR: ${DIR_DATOS} no es escribible por el usuario $(id -un) (uid $(id -u))."
log " Si montaste una carpeta del anfitrión, dale permisos: chown -R 1001:1001 <carpeta>"
exit 1
fi
if [ -f "$BD" ]; then
log "ya existe ${BD}: su contenido no se toca."
if [ -f "$MARCADOR" ]; then
log "primer arranque de este volumen: $(cat "$MARCADOR")"
fi
elif [ -f "$SEMILLA" ]; then
log "volumen vacío: se copia la base de demostración horneada en la imagen."
cp "$SEMILLA" "$BD"
date -u '+%Y-%m-%dT%H:%M:%SZ' > "$MARCADOR" 2>/dev/null || true
log "listo. Los datos del panel son de demostración; los leads que capture el sitio se suman a esta base."
else
log "volumen vacío y la imagen no trae base de demostración: se creará vacía."
log "El panel no tendrá usuarios y no se podrá iniciar sesión en /admin/login."
fi
# --- 2. esquema ---------------------------------------------------------------
#
# Idempotente: si el esquema del código y el de la base ya coinciden, no hace
# nada. A propósito NO se pasa --accept-data-loss: si una versión nueva exigiera
# eliminar una columna o una tabla con filas, se prefiere que el arranque falle
# y quede en los registros antes que borrar leads capturados en silencio.
log "aplicando el esquema (prisma db push)"
node /app/prisma-cli/node_modules/prisma/build/index.js db push \
--schema=/app/prisma/schema.prisma \
--skip-generate
# --- 3. servidor --------------------------------------------------------------
log "arrancando Next en ${HOSTNAME}:${PORT}"
exec "$@"