17 KiB
🎯 MEMORIA COMPLETA DEL PROYECTO - SaaS PageBuilder
Fecha: 13 Enero 2025
Hash: gkachele-login-customizer-20250114-v3
Última actualización: 14 Enero 2025 - 11:35
🇦🇷 OBJETIVO ARGENTINA
Meta: Lanzar GKACHELE™ SaaS en Argentina con funcionalidad completa y profesional.
Criterio de Éxito: Si funciona 1 rubro bien en Raspberry Pi → PAGAR VPS
Dominio: Ya tienes dominio configurado
Ver: OBJETIVOS_ARGENTINA.md y GITEA_WORKFLOWS.md para detalles completos
🎯 OBJETIVOS ACTUALES (Memorizado)
🚀 PRIORIDAD: ARGENTINA 🇦🇷
Objetivo: Lanzar GKACHELE™ SaaS en Argentina con funcionalidad completa.
Criterio de Éxito: Si funciona 1 rubro bien en Raspberry Pi → PAGAR VPS
Objetivos Inmediatos:
-
✅ Template y Menús Profesionales (COMPLETADO):
- ✅ Sistema modular (_gkachele/header.php, footer.php, sidebar.php)
- ✅ Sistema de menús dinámicos
- ✅ Sistema de widgets
- ⚠️ UI completa para gestionar menús (pendiente)
-
🔧 Funcionalidad Core (EN PROGRESO):
- ✅ Registro de clientes
- ✅ Login → Customizer directo (FUNCIONANDO - Hash v3)
- ✅ Dashboard del cliente (
/dashboard) - ✅ Customizer básico (
/customizer/{site_id}) - ✅ Panel admin (
/admin)
-
🔄 Gitea y Workflows (PENDIENTE):
- Integración Gitea para repos por cliente
- Workflows automáticos:
- Aceptar peticiones desde dashboard admin
- Desplegar sitios automáticamente
- Generar repositorios por cliente
- Versionado automático
- Integración con dashboard admin
-
📝 Control de Versiones:
- Git para landing page
- Versionado de templates
- Historial de cambios
- Rollback de versiones
-
🎨 Mejorar Landing (PENDIENTE):
- Diseño optimizado para Argentina
- Mejor UX/UI
- Optimización de conversión
- Performance optimizado
- Responsive mejorado
-
📊 Workflows Dashboard Admin:
- Aceptar/rechazar peticiones
- Gestionar usuarios
- Ver estadísticas
- Gestionar despliegues
- Control de versiones
- Integración con Gitea
⚠️ REQUISITOS PRINCIPALES (MEMORIZAR)
- Sincronización con Hash: Raspberry y Local deben estar sincronizados con hash
- Modularizado: Código debe estar modularizado
- PRIMERO copiar funcionalidad similar: NO inventar, copiar funcionalidad similar primero en Raspberry, luego ver qué sirve y qué no
- Iterar: Probar → Ver qué sirve → Eliminar lo que no sirve → Mejorar
Ver: MEMORIA_SINCRONIZACION.md para detalles
📍 CONEXIÓN RASPBERRY PI
Credenciales SSH:
- Host:
komkida.duckdns.orgo192.168.1.134 - Puerto:
2222 - Usuario:
pi - Password:
Gdk1983gdk45@
Comandos de conexión (CON sshpass):
# Desde WSL - CONECTAR
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134"
# COPIAR ARCHIVOS
wsl bash -c "sshpass -p 'Gdk1983gdk45@' scp -P 2222 -o StrictHostKeyChecking=no /mnt/c/word/demo/app.py pi@192.168.1.134:/home/pi/gkachele-saas/app.py"
# EJECUTAR COMANDO REMOTO
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134 'comando aqui'"
🏗️ ARQUITECTURA
Stack Tecnológico
- Backend: Flask (Python 3) - NO Docker, directo
- Base de datos: SQLite (main.db + cliente-X.db)
- Web Server: Nginx (reverse proxy)
- Dominio:
gk-saas.komkida.duckdns.org - Puerto Flask: 5001
- Puerto Nginx: 80
Estructura en Raspberry Pi
/home/pi/gkachele-saas/
├── app.py # Flask backend principal
├── database/
│ ├── main.db # DB principal (users, sites, requests, media)
│ └── sites/ # DBs por cliente
│ ├── cliente-1.db
│ └── cliente-2.db
├── sites/ # Sitios compilados/publicados
├── themes/ # Templates (como WordPress)
│ ├── gimnasio-claro/
│ ├── restaurante-moderno/
│ └── restaurante-elegante/
├── static/ # CSS, JS, imágenes
├── templates/ # HTML templates
│ ├── landing_real.html # Landing GKACHELE™
│ ├── register.html
│ ├── login.html
│ ├── dashboard.html # Dashboard CLIENTE
│ ├── customizer.html # Personalizador WordPress-like
│ ├── admin.html # Dashboard PRINCIPAL (tuyo)
│ └── client_admin.html # Admin del cliente
└── uploads/ # Media subida por clientes
Estructura en Local (Desarrollo)
C:\word\
├── demo/ # Código del SaaS
│ ├── app.py
│ ├── database/
│ ├── themes/
│ ├── templates/
│ └── static/
├── update-raspberry.sh # Script para actualizar Raspberry
└── MEMORIA_PROYECTO_COMPLETA.md # Este archivo
🔄 FLUJO COMPLETO
1. Cliente → Landing (gk-saas.komkida.duckdns.org)
2. Cliente elige plan + rubro → /register?plan=base&rubro=restaurante
3. Cliente se registra → POST /register
├── Crea usuario en main.db (tabla users)
├── Crea sitio automático (tema según rubro) en main.db (tabla sites)
└── Guarda sesión → Redirige a /dashboard (equivalente a wp-admin)
4. Dashboard → Cliente ve SUS sitios
5. Customizer → /customizer/{site_id} (sidebar + preview)
6. Cliente envía → POST /dashboard/submit/{site_id}
7. Admin → /admin (solo user_id=1) aprueba
8. Publicado → /site/{slug}
🗄️ BASES DE DATOS
main.db (SQLite) - TODO EN UNA SOLA BASE DE DATOS (Multi-tenant como WordPress)
✅ Sistema Multi-tenant: Todos los clientes en una sola base de datos, cada cliente solo ve SUS datos a través de /dashboard (equivalente a wp-admin)
Tabla: users
- id, email (UNIQUE), password (hash), plan, rubro, created_at
- Todos los usuarios/clientes están aquí
Tabla: sites
- id, user_id (FK), slug (UNIQUE), theme, status (draft/pending/published), content_json, created_at
- Todos los sitios, filtrados por user_id (cada cliente solo ve los suyos)
Tabla: requests
- id, site_id (FK), user_id (FK), status (pending/approved/rejected), created_at
- Solicitudes de publicación
Tabla: media
- id, user_id (FK), site_id (FK), filename, filepath, file_type, uploaded_at
- Archivos subidos por clientes, filtrados por user_id
Tabla: content
- id, user_id (FK), site_id (FK), section, data_json, updated_at
- Contenido por sección (futuro uso), filtrado por user_id y site_id
Tabla: settings
- id, user_id (FK), site_id, key, value, created_at, updated_at
- Configuraciones (como wp_options en WordPress), filtrado por user_id y site_id
Tabla: menus
- id, user_id (FK), site_id (FK), location (header/footer/sidebar), title, url, order_index, parent_id, created_at
- Sistema de menús dinámicos por ubicación, filtrado por user_id y site_id
Tabla: widgets
- id, user_id (FK), site_id (FK), area (sidebar/footer/etc), type, title, content, order_index, created_at, updated_at
- Sistema de widgets dinámicos por área, filtrado por user_id y site_id
🎨 TEMPLATES (Sistema WordPress-like)
Templates Disponibles
- gimnasio-claro: Tema para gimnasios (rojo/negro)
- restaurante-moderno: Tema moderno (rojo/naranja) - 2 variantes
- restaurante-elegante: Tema elegante (marrón/dorado)
Estructura de Template (Sistema Modular GKACHELE™)
themes/
├── _gkachele/ # Sistema base modular (como WordPress)
│ ├── header.php # Header con menús dinámicos
│ ├── footer.php # Footer con copyright GKACHELE™
│ └── sidebar.php # Sidebar con widgets dinámicos
├── {nombre}/ # Temas específicos
│ ├── config.json # Configuración (colores, tipografía, secciones)
│ ├── template.html # HTML del template (contenido principal)
│ └── style.css # CSS (opcional)
Sistema de Renderizado:
render_gkachele_template()concatena:header.php+template.html+sidebar.php+footer.php- Menús y widgets se cargan dinámicamente desde la base de datos
- Soporte para múltiples ubicaciones de menú (header, footer, sidebar)
- Widgets por área (sidebar, footer, etc.)
Asignación Automática
- restaurante: Aleatorio entre
restaurante-modernoyrestaurante-elegante - gimnasio/gimnasios:
gimnasio-claro - Otros:
default
🔧 CONFIGURACIÓN NGINX
Archivo: /etc/nginx/sites-available/gk-saas.komkida.duckdns.org.conf
server {
listen 80;
server_name gk-saas.komkida.duckdns.org;
location / {
proxy_pass http://localhost:5001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Comandos:
sudo nginx -t # Verificar configuración
sudo systemctl reload nginx # Recargar
tail -f /var/log/nginx/gk-saas-error.log # Ver logs
🔄 SERVICIO SYSTEMD
Archivo: /etc/systemd/system/gkachele-saas.service
[Unit]
Description=GKACHELE SaaS Flask App
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/gkachele-saas
Environment="PATH=/usr/bin:/usr/local/bin:/home/pi/.local/bin"
ExecStart=/usr/bin/python3 /home/pi/gkachele-saas/app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Comandos:
sudo systemctl start gkachele-saas # Iniciar
sudo systemctl stop gkachele-saas # Detener
sudo systemctl restart gkachele-saas # Reiniciar
sudo systemctl status gkachele-saas # Estado
journalctl -u gkachele-saas -f # Ver logs
🚀 ACTUALIZAR CÓDIGO EN RASPBERRY
Método Correcto (con sshpass desde WSL):
# 1. Copiar código actualizado
wsl bash -c "sshpass -p 'Gdk1983gdk45@' scp -P 2222 -o StrictHostKeyChecking=no /mnt/c/word/demo/app.py pi@192.168.1.134:/home/pi/gkachele-saas/app.py"
# 2. Reiniciar app (matar proceso y reiniciar)
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134 'pkill -f \"python3 app.py\" && cd ~/gkachele-saas && nohup python3 app.py > /tmp/app.log 2>&1 &'"
Instalar Servicio Systemd (una vez):
# Copiar servicio
wsl bash -c "sshpass -p 'Gdk1983gdk45@' scp -P 2222 -o StrictHostKeyChecking=no gkachele-saas.service pi@192.168.1.134:/tmp/"
# Instalar servicio
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134 'sudo mv /tmp/gkachele-saas.service /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl enable gkachele-saas && sudo systemctl start gkachele-saas'"
Configurar Cron en Raspberry (actualizar automáticamente):
# 1. Crear script de actualización
wsl bash -c "sshpass -p 'Gdk1983gdk45@' scp -P 2222 -o StrictHostKeyChecking=no update-app-raspberry.sh pi@192.168.1.134:~/scripts/update-app.sh"
# 2. Dar permisos
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134 'chmod +x ~/scripts/update-app.sh'"
# 3. Agregar a crontab (cada hora) - requiere permisos
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134 'echo \"0 * * * * /home/pi/scripts/update-app.sh\" | crontab -'"
# Verificar cron
wsl bash -c "sshpass -p 'Gdk1983gdk45@' ssh -p 2222 -o StrictHostKeyChecking=no pi@192.168.1.134 'crontab -l'"
NOTA: El cron actualiza cada hora. Para actualizar manualmente el código, usar el método de SCP arriba.
📋 RUTAS PRINCIPALES
Públicas
GET /- Landing pageGET /register- Formulario registroPOST /register- Crear usuario (JSON)GET /login- Formulario loginPOST /login- Iniciar sesión (JSON)GET /site/{slug}- Sitio público publicado
Cliente (requiere sesión)
GET /dashboard- Dashboard del clienteGET /customizer/{site_id}- PersonalizadorPOST /api/customizer/save- Guardar cambiosGET /api/customizer/preview-frame/{site_id}- Preview iframePOST /dashboard/submit/{site_id}- Enviar para aprobaciónGET /dashboard/admin- Admin del cliente (media, config)
APIs de Menús y Widgets
GET /api/menus/<site_id>- Obtener menús del sitioPOST /api/menus/<site_id>- Guardar/actualizar menúsGET /api/widgets/<site_id>- Obtener widgets del sitioPOST /api/widgets/<site_id>- Guardar/actualizar widgets
Admin Principal (solo user_id=1)
GET /admin- Dashboard principalPOST /admin/approve/{request_id}- Aprobar solicitudPOST /admin/reject/{request_id}- Rechazar solicitud
🔐 SEGURIDAD
Sesiones
- Flask
sessionconsecret_key - Cookie
SESSION_COOKIE_SAMESITE = 'Lax' - Sesión se guarda después de login exitoso
Acceso
- Clientes: Solo ven SUS sitios (filtrado por
user_iden sesión) - Admin: Solo
user_id = 1puede acceder a/admin - Passwords: Hash con
werkzeug.security.generate_password_hash
🎯 ESTADO ACTUAL
✅ Funcionando
- Landing page (GKACHELE™ original)
- Registro de clientes → Redirige a
/login(sin sesión automática) - Login de clientes → Redirige a
/dashboard - Dashboard del cliente
- Customizer básico (sidebar + preview)
- Templates: gimnasio-claro, restaurante-moderno, restaurante-elegante
- Sistema modular de templates (_gkachele/header.php, footer.php, sidebar.php)
- Sistema de menús dinámicos (header, footer, sidebar)
- Sistema de widgets dinámicos (sidebar, footer, etc.)
- Función
render_gkachele_template()para renderizado completo - APIs para gestionar menús y widgets
- Base de datos SQLite multi-tenant (main.db con tablas menus y widgets)
- Nginx reverse proxy
- Systemd service
- DuckDNS para dominio remoto
- Scripts de gestión:
ver_usuarios.py,limpiar_db.py
⚠️ Pendiente
- Drag & drop de secciones (SortableJS)
- Edición inline (contenteditable)
- Gitea para repos por cliente + automatización
- Dashboard principal para aprobar solicitudes
- Plugins sencillos (colores, tipografía avanzada)
- SSL/HTTPS (Let's Encrypt)
🎯 PRÓXIMOS OBJETIVOS (PRIORITARIOS)
-
✅ Template y Menús Profesionales (COMPLETADO):
- ✅ Sistema modular (_gkachele/header.php, footer.php, sidebar.php)
- ✅ Sistema de menús dinámicos (header, footer, sidebar)
- ✅ Múltiples ubicaciones de menú
- ✅ Sistema de widgets/áreas
- ⚠️ PENDIENTE: UI completa para gestionar menús desde customizer (actualmente solo placeholder)
-
Mejorar Landing:
- Diseño más profesional
- Mejor UX/UI
- Optimización de conversión
-
Automatización con Gitea:
- Integración Gitea para repos por cliente
- Automatización de despliegues
- Workflows automáticos
- Integración con n8n (futuro)
📦 DEPENDENCIAS
Python:
- Flask
- Werkzeug (password hashing)
- SQLite3 (built-in)
Instalación:
pip3 install Flask Werkzeug
🌐 DUCKDNS
Dominios:
- komkida.duckdns.org: Token
9c5cff88-b6d7-4704-9b10-4a69afdff797 - gkachele.duckdns.org: Token
578331b3-ad7b-4154-835d-e496465257b0
Actualizar IP:
python3 update-komkida-duckdns.py
🚀 MIGRACIÓN A VPS
Pasos:
- Copiar
/home/pi/gkachele-saas/completo - Instalar Python3, Nginx en VPS
- Copiar configuración Nginx
- Copiar servicio systemd
- Cambiar dominio (DuckDNS o dominio real)
- Configurar SSL (Let's Encrypt)
Ventajas:
- ✅ Mismo código (sin cambios)
- ✅ Misma estructura
- ✅ Más recursos
- ✅ Mejor rendimiento
📝 NOTAS IMPORTANTES
- NO usar Docker: Todo corre directamente (Python + Nginx)
- NO usar GitHub: Todo es independiente en Raspberry
- SQLite es suficiente: Para SaaS pequeño, no necesita MySQL
- Raspberry Pi 3: Recursos limitados, pero suficiente para desarrollo
- VPS recomendado: Para producción con muchos clientes
📦 BACKUP Y VERSIONADO
Hash Actual: gkachele-template-system-20250114-v1
Estado Verificado:
- ✅ Templates _gkachele en Raspberry: header.php, footer.php, sidebar.php
- ✅ Función render_gkachele_template en app.py
- ✅ Tablas menus y widgets en main.db
- ✅ Servicio gkachele-saas activo
- ✅ Flujo de registro: Registro → Login → Dashboard → Customizer
Scripts de Gestión:
ver_usuarios.py- Ver usuarios y sitios registradoslimpiar_db.py- Limpiar base de datos (con confirmación)verificar_raspberry.sh- Verificar estado en Raspberry
Última actualización: 14 Enero 2025 - 08:50