- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
231 lines
8.1 KiB
Bash
Executable File
231 lines
8.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# =============================================================================
|
|
# Script: validate-ddl-organization.sh
|
|
# Propósito: Validar que todos los objetos DDL estén en los schemas correctos
|
|
# Uso: ./validate-ddl-organization.sh
|
|
# Salida: Reporte de validación en formato YAML
|
|
# Creado: 2025-11-09
|
|
# =============================================================================
|
|
|
|
set -e
|
|
|
|
BASE_DIR="/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/apps/database/ddl/schemas"
|
|
OUTPUT_FILE="/tmp/ddl-validation-$(date +%Y%m%d-%H%M%S).yaml"
|
|
|
|
echo "=== VALIDACIÓN DE ORGANIZACIÓN DDL ==="
|
|
echo "Fecha: $(date)"
|
|
echo "Base directory: $BASE_DIR"
|
|
echo ""
|
|
|
|
# Colores para output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Contadores globales
|
|
TOTAL_ISSUES=0
|
|
CRITICAL_ISSUES=0
|
|
MINOR_ISSUES=0
|
|
|
|
# =============================================================================
|
|
# 1. VALIDAR PUBLIC SCHEMA
|
|
# =============================================================================
|
|
|
|
echo "1. Validando Public Schema..."
|
|
|
|
PUBLIC_TABLES=$(find "$BASE_DIR/public/tables" -name "*.sql" 2>/dev/null | wc -l)
|
|
PUBLIC_FUNCTIONS=$(find "$BASE_DIR/public/functions" -name "*.sql" 2>/dev/null | wc -l)
|
|
PUBLIC_ENUMS=$(find "$BASE_DIR/public/enums" -name "*.sql" ! -path "*/_deprecated/*" 2>/dev/null | wc -l)
|
|
PUBLIC_VIEWS=$(find "$BASE_DIR/public/views" -name "*.sql" 2>/dev/null | wc -l)
|
|
|
|
if [ "$PUBLIC_TABLES" -gt 0 ]; then
|
|
echo -e "${RED}✗ ERROR: Tablas encontradas en public schema${NC}"
|
|
CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
|
|
else
|
|
echo -e "${GREEN}✓ No hay tablas en public schema${NC}"
|
|
fi
|
|
|
|
if [ "$PUBLIC_FUNCTIONS" -gt 0 ]; then
|
|
echo -e "${RED}✗ ERROR: Funciones encontradas en public schema${NC}"
|
|
CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
|
|
else
|
|
echo -e "${GREEN}✓ No hay funciones en public schema${NC}"
|
|
fi
|
|
|
|
if [ "$PUBLIC_ENUMS" -gt 0 ]; then
|
|
echo -e "${RED}✗ ERROR: ENUMs activos encontrados en public schema${NC}"
|
|
CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
|
|
else
|
|
echo -e "${GREEN}✓ No hay ENUMs activos en public schema${NC}"
|
|
fi
|
|
|
|
if [ "$PUBLIC_VIEWS" -le 5 ]; then
|
|
echo -e "${GREEN}✓ Public schema tiene $PUBLIC_VIEWS views (aceptable)${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠ Public schema tiene $PUBLIC_VIEWS views (considerar mover a schema dedicado)${NC}"
|
|
MINOR_ISSUES=$((MINOR_ISSUES + 1))
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
# 2. VALIDAR INDEXES CON SCHEMA CALIFICADO
|
|
# =============================================================================
|
|
|
|
echo "2. Validando Indexes con schema calificado..."
|
|
|
|
TOTAL_INDEXES=$(find "$BASE_DIR" -path "*/indexes/*.sql" -type f 2>/dev/null | wc -l)
|
|
|
|
# Buscar indexes sin schema.tabla en ON clause
|
|
UNQUALIFIED_INDEXES=0
|
|
|
|
while IFS= read -r file; do
|
|
# Extraer líneas CREATE INDEX y verificar si la siguiente línea tiene schema.tabla
|
|
if grep -q "CREATE INDEX" "$file"; then
|
|
# Obtener línea completa del CREATE INDEX + ON
|
|
INDEX_STATEMENT=$(grep -A1 "CREATE INDEX" "$file" | tr '\n' ' ')
|
|
|
|
# Verificar si contiene ON schema.tabla
|
|
if ! echo "$INDEX_STATEMENT" | grep -q "ON [a-z_]*\.[a-z_]*"; then
|
|
echo -e "${YELLOW}⚠ Index sin schema calificado: $file${NC}"
|
|
UNQUALIFIED_INDEXES=$((UNQUALIFIED_INDEXES + 1))
|
|
fi
|
|
fi
|
|
done < <(find "$BASE_DIR" -path "*/indexes/*.sql" -type f 2>/dev/null)
|
|
|
|
if [ "$UNQUALIFIED_INDEXES" -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Todos los $TOTAL_INDEXES indexes tienen schema calificado${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠ $UNQUALIFIED_INDEXES de $TOTAL_INDEXES indexes sin schema calificado${NC}"
|
|
MINOR_ISSUES=$((MINOR_ISSUES + UNQUALIFIED_INDEXES))
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
# 3. VALIDAR DISTRIBUCIÓN DE FUNCIONES
|
|
# =============================================================================
|
|
|
|
echo "3. Validando distribución de funciones..."
|
|
|
|
TOTAL_FUNCTIONS=$(find "$BASE_DIR" -path "*/functions/*.sql" ! -path "*/_deprecated/*" -type f 2>/dev/null | wc -l)
|
|
|
|
# Verificar que funciones utilitarias estén en gamilit
|
|
GAMILIT_FUNCTIONS=$(find "$BASE_DIR/gamilit/functions" -name "*.sql" 2>/dev/null | wc -l)
|
|
|
|
echo -e "${GREEN}✓ Total funciones: $TOTAL_FUNCTIONS${NC}"
|
|
echo -e "${GREEN}✓ Funciones en gamilit (utilitarias): $GAMILIT_FUNCTIONS${NC}"
|
|
|
|
# Listar funciones por schema
|
|
for schema in audit_logging gamification_system educational_content progress_tracking auth_management; do
|
|
count=$(find "$BASE_DIR/$schema/functions" -name "*.sql" ! -path "*/_deprecated/*" 2>/dev/null | wc -l)
|
|
if [ "$count" -gt 0 ]; then
|
|
echo " - $schema: $count funciones"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
# 4. VALIDAR RLS EN TABLAS CRÍTICAS
|
|
# =============================================================================
|
|
|
|
echo "4. Validando RLS en tablas críticas..."
|
|
|
|
CRITICAL_TABLES=("user_suspensions" "flagged_content" "user_activity_logs")
|
|
RLS_MISSING=0
|
|
|
|
for table in "${CRITICAL_TABLES[@]}"; do
|
|
# Buscar si hay RLS policies para esta tabla
|
|
if grep -rq "$table" "$BASE_DIR"/*/rls-policies/*.sql 2>/dev/null; then
|
|
echo -e "${GREEN}✓ Tabla crítica '$table' tiene RLS policies${NC}"
|
|
else
|
|
echo -e "${RED}✗ ERROR: Tabla crítica '$table' NO tiene RLS policies${NC}"
|
|
CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
|
|
RLS_MISSING=$((RLS_MISSING + 1))
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
# 5. VALIDAR TRIGGERS HUÉRFANOS
|
|
# =============================================================================
|
|
|
|
echo "5. Validando triggers huérfanos..."
|
|
|
|
TOTAL_TRIGGERS=$(find "$BASE_DIR" -path "*/triggers/*.sql" -type f 2>/dev/null | wc -l)
|
|
|
|
echo -e "${GREEN}✓ Total triggers: $TOTAL_TRIGGERS${NC}"
|
|
echo " (Validación manual requerida para verificar que triggers tengan tablas correspondientes)"
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
# 6. GENERAR REPORTE YAML
|
|
# =============================================================================
|
|
|
|
cat > "$OUTPUT_FILE" << EOF
|
|
validacion_ddl_organization:
|
|
fecha: "$(date -I)"
|
|
hora: "$(date +%H:%M:%S)"
|
|
|
|
resumen:
|
|
estado_general: "$([ $CRITICAL_ISSUES -eq 0 ] && echo "PASS" || echo "FAIL")"
|
|
problemas_criticos: $CRITICAL_ISSUES
|
|
problemas_menores: $MINOR_ISSUES
|
|
total_problemas: $((CRITICAL_ISSUES + MINOR_ISSUES))
|
|
|
|
public_schema:
|
|
tablas: $PUBLIC_TABLES
|
|
funciones: $PUBLIC_FUNCTIONS
|
|
enums: $PUBLIC_ENUMS
|
|
views: $PUBLIC_VIEWS
|
|
estado: "$([ $PUBLIC_TABLES -eq 0 ] && [ $PUBLIC_FUNCTIONS -eq 0 ] && [ $PUBLIC_ENUMS -eq 0 ] && echo "LIMPIO" || echo "CONTAMINADO")"
|
|
|
|
indexes:
|
|
total: $TOTAL_INDEXES
|
|
sin_schema_calificado: $UNQUALIFIED_INDEXES
|
|
porcentaje_correctos: $(awk "BEGIN {printf \"%.1f\", ($TOTAL_INDEXES - $UNQUALIFIED_INDEXES) * 100.0 / $TOTAL_INDEXES}")%
|
|
|
|
funciones:
|
|
total: $TOTAL_FUNCTIONS
|
|
en_gamilit: $GAMILIT_FUNCTIONS
|
|
|
|
rls_policies:
|
|
tablas_criticas_validadas: ${#CRITICAL_TABLES[@]}
|
|
tablas_sin_rls: $RLS_MISSING
|
|
cobertura: "$([ $RLS_MISSING -eq 0 ] && echo "100%" || echo "Incompleta")"
|
|
|
|
triggers:
|
|
total: $TOTAL_TRIGGERS
|
|
|
|
recomendacion: "$([ $CRITICAL_ISSUES -eq 0 ] && echo "APROBAR" || echo "RECHAZAR - Corregir problemas críticos")"
|
|
EOF
|
|
|
|
echo "=== RESUMEN ==="
|
|
echo ""
|
|
echo "Problemas críticos: $CRITICAL_ISSUES"
|
|
echo "Problemas menores: $MINOR_ISSUES"
|
|
echo "Total problemas: $((CRITICAL_ISSUES + MINOR_ISSUES))"
|
|
echo ""
|
|
|
|
if [ $CRITICAL_ISSUES -eq 0 ]; then
|
|
echo -e "${GREEN}✓ VALIDACIÓN EXITOSA - No hay problemas críticos${NC}"
|
|
EXIT_CODE=0
|
|
else
|
|
echo -e "${RED}✗ VALIDACIÓN FALLIDA - $CRITICAL_ISSUES problema(s) crítico(s)${NC}"
|
|
EXIT_CODE=1
|
|
fi
|
|
|
|
echo ""
|
|
echo "Reporte generado: $OUTPUT_FILE"
|
|
echo ""
|
|
|
|
# Mostrar contenido del reporte
|
|
cat "$OUTPUT_FILE"
|
|
|
|
exit $EXIT_CODE
|