#!/bin/bash # ============================================================================= # cascade-propagation.sh # Ejecuta propagacion respetando jerarquia de niveles # Version: 1.0.0 # Sistema: NEXUS v3.4 + SIMCO + CAPVED # EPIC: EPIC-012 # ============================================================================= # # Uso: # ./cascade-propagation.sh [opciones] # # Parametros: # modulo Nombre del modulo # version Version nueva # # Opciones: # --start-level N Nivel inicial (0-3, default: auto-detectar) # --stop-level N Nivel final (0-3, default: 3) # --dry-run Simular sin ejecutar # --force Continuar aunque un nivel falle # --help Mostrar esta ayuda # # Niveles: # 0 = core/catalog # 1 = shared/knowledge-base # 2 = Proyectos base (erp-core, gamilit, trading-platform) # 3 = Proyectos hoja (verticales ERP, otros) # # Ejemplo: # ./cascade-propagation.sh auth-jwt-nestjs 2.2.0 --start-level 1 # # ============================================================================= set -e # Configuracion SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" KB_PATH="/home/isem/workspace-v1/shared/knowledge-base" NIVELES_FILE="$KB_PATH/propagacion/NIVELES-PROPAGACION.yml" CORE_CATALOG="/home/isem/workspace-v1/core/catalog" PROJECTS_PATH="/home/isem/workspace-v1/projects" # Colores GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # Funciones de logging log_ok() { echo -e "${GREEN}[OK]${NC} $1"; } log_fail() { echo -e "${RED}[FAIL]${NC} $1"; } log_info() { echo -e "${YELLOW}[INFO]${NC} $1"; } log_step() { echo -e "${BLUE}[STEP]${NC} $1"; } log_level() { echo -e "${CYAN}[NIVEL $1]${NC} $2"; } # Funcion de ayuda show_help() { head -35 "$0" | tail -28 exit 0 } # Validar parametros if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then show_help fi # Parsear argumentos posicionales MODULO="${1:-}" VERSION="${2:-}" if [ -z "$MODULO" ] || [ -z "$VERSION" ]; then echo -e "${RED}ERROR:${NC} Parametros insuficientes" echo "Uso: $0 [opciones]" echo "Ejecute '$0 --help' para mas informacion" exit 1 fi shift 2 || true # Valores por defecto START_LEVEL=-1 STOP_LEVEL=3 DRY_RUN=false FORCE=false # Parsear opciones while [[ $# -gt 0 ]]; do case $1 in --start-level) START_LEVEL=$2; shift 2 ;; --stop-level) STOP_LEVEL=$2; shift 2 ;; --dry-run) DRY_RUN=true; shift ;; --force) FORCE=true; shift ;; --help|-h) show_help ;; *) echo -e "${RED}ERROR:${NC} Opcion desconocida: $1"; exit 1 ;; esac done # Contadores PASS=0 FAIL=0 SKIP=0 echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ PROPAGACION EN CASCADA - $MODULO v$VERSION" echo "╚═══════════════════════════════════════════════════════════════╝" echo "" echo " Modulo: $MODULO" echo " Version: $VERSION" echo " Dry-run: $DRY_RUN" echo " Force: $FORCE" echo "" # Auto-detectar nivel inicial si no se especifico if [ $START_LEVEL -eq -1 ]; then log_info "Auto-detectando nivel inicial..." # Verificar si el modulo existe en core/catalog if [ -d "$CORE_CATALOG/$MODULO" ]; then START_LEVEL=0 log_ok "Modulo encontrado en core/catalog -> Nivel 0" # Verificar si existe en knowledge-base elif [ -d "$KB_PATH/modules/$MODULO" ]; then START_LEVEL=1 log_ok "Modulo encontrado en knowledge-base -> Nivel 1" else START_LEVEL=2 log_info "Modulo no encontrado en core ni KB -> Nivel 2 (proyectos)" fi fi echo "" log_info "Rango de niveles: $START_LEVEL -> $STOP_LEVEL" echo "" # Funcion para procesar nivel 0 (core/catalog) process_level_0() { log_level 0 "Core Catalog" echo " Ubicacion: $CORE_CATALOG" if [ -d "$CORE_CATALOG/$MODULO" ]; then log_info "Modulo encontrado: $CORE_CATALOG/$MODULO" if [ "$DRY_RUN" = false ]; then # Verificar documentacion if [ -f "$CORE_CATALOG/$MODULO/README.md" ]; then log_ok "README.md existe" ((PASS++)) else log_fail "README.md no encontrado" ((FAIL++)) return 1 fi else log_info "[DRY-RUN] Verificaria documentacion del modulo" fi else log_info "Modulo no existe en core/catalog - saltando" ((SKIP++)) fi return 0 } # Funcion para procesar nivel 1 (knowledge-base) process_level_1() { log_level 1 "Knowledge-Base" echo " Ubicacion: $KB_PATH" if [ "$DRY_RUN" = false ]; then # Verificar CATALOGO-MODULOS.yml if [ -f "$KB_PATH/CATALOGO-MODULOS.yml" ]; then if grep -q "$MODULO" "$KB_PATH/CATALOGO-MODULOS.yml" 2>/dev/null; then log_ok "Modulo registrado en CATALOGO-MODULOS.yml" ((PASS++)) else log_info "Modulo no registrado en catalogo (normal para modulos nuevos)" ((SKIP++)) fi else log_info "CATALOGO-MODULOS.yml no existe" ((SKIP++)) fi # Verificar version en TRAZABILIDAD if [ -f "$KB_PATH/TRAZABILIDAD-PROYECTOS.yml" ]; then log_ok "TRAZABILIDAD-PROYECTOS.yml existe" ((PASS++)) fi else log_info "[DRY-RUN] Verificaria catalogo y trazabilidad" fi return 0 } # Funcion para procesar nivel 2 (proyectos base) process_level_2() { log_level 2 "Proyectos Base" echo " Ubicacion: $PROJECTS_PATH" # Proyectos base definidos PROYECTOS_BASE=("erp-core" "gamilit" "trading-platform") for proyecto in "${PROYECTOS_BASE[@]}"; do PROJECT_PATH="$PROJECTS_PATH/$proyecto" if [ -d "$PROJECT_PATH" ]; then echo "" echo " --- $proyecto ---" if [ "$DRY_RUN" = false ]; then # Verificar si el proyecto usa el modulo if grep -rq "$MODULO" "$PROJECT_PATH/package.json" 2>/dev/null || \ grep -rq "$MODULO" "$PROJECT_PATH/apps" 2>/dev/null; then log_info "Proyecto usa $MODULO" # Intentar build (si existe package.json) if [ -f "$PROJECT_PATH/package.json" ]; then log_info "Verificando build..." # Solo verificar que existe, no ejecutar en cascada automatica log_ok "package.json existe" ((PASS++)) fi else log_info "Proyecto no parece usar $MODULO directamente" ((SKIP++)) fi else log_info "[DRY-RUN] Verificaria proyecto $proyecto" fi else log_info "Proyecto $proyecto no existe" ((SKIP++)) fi done return 0 } # Funcion para procesar nivel 3 (proyectos hoja) process_level_3() { log_level 3 "Proyectos Hoja" echo " Ubicacion: $PROJECTS_PATH (verticales y otros)" # Proyectos hoja (verticales ERP y otros) PROYECTOS_HOJA=("betting-analytics" "inmobiliaria-analytics" "platform_marketing_content") # Tambien buscar verticales en erp-suite si existe if [ -d "$PROJECTS_PATH/erp-suite/apps/verticales" ]; then for vertical in "$PROJECTS_PATH/erp-suite/apps/verticales"/*/; do if [ -d "$vertical" ]; then VERTICAL_NAME=$(basename "$vertical") PROYECTOS_HOJA+=("erp-suite:$VERTICAL_NAME") fi done fi for proyecto in "${PROYECTOS_HOJA[@]}"; do # Manejar verticales ERP if [[ "$proyecto" == *":"* ]]; then SUITE=$(echo "$proyecto" | cut -d: -f1) VERTICAL=$(echo "$proyecto" | cut -d: -f2) PROJECT_PATH="$PROJECTS_PATH/$SUITE/apps/verticales/$VERTICAL" DISPLAY_NAME="$SUITE/$VERTICAL" else PROJECT_PATH="$PROJECTS_PATH/$proyecto" DISPLAY_NAME="$proyecto" fi if [ -d "$PROJECT_PATH" ]; then echo "" echo " --- $DISPLAY_NAME ---" if [ "$DRY_RUN" = false ]; then log_ok "Proyecto existe" ((PASS++)) else log_info "[DRY-RUN] Verificaria proyecto $DISPLAY_NAME" fi else ((SKIP++)) fi done return 0 } # Ejecutar por niveles for level in $(seq $START_LEVEL $STOP_LEVEL); do echo "" echo "═══════════════════════════════════════════════════════════════" LEVEL_RESULT=0 case $level in 0) process_level_0 || LEVEL_RESULT=$? ;; 1) process_level_1 || LEVEL_RESULT=$? ;; 2) process_level_2 || LEVEL_RESULT=$? ;; 3) process_level_3 || LEVEL_RESULT=$? ;; *) log_fail "Nivel invalido: $level"; exit 1 ;; esac echo "" if [ $LEVEL_RESULT -ne 0 ]; then if [ "$FORCE" = true ]; then log_info "Nivel $level con errores, continuando (--force)" else log_fail "Nivel $level fallo. Use --force para continuar" exit 1 fi fi if [ "$DRY_RUN" = false ]; then log_ok "Nivel $level completado" else log_info "[DRY-RUN] Nivel $level simulado" fi done # Resumen echo "" echo "═══════════════════════════════════════════════════════════════" echo " RESUMEN DE CASCADA" echo "═══════════════════════════════════════════════════════════════" echo "" echo -e " ${GREEN}PASS:${NC} $PASS" echo -e " ${YELLOW}SKIP:${NC} $SKIP" echo -e " ${RED}FAIL:${NC} $FAIL" echo "" if [ $FAIL -eq 0 ]; then echo -e "${GREEN}[CASCADA COMPLETADA]${NC}" echo "" echo "Proximos pasos:" echo " 1. Generar tareas SCRUM: ./generate-scrum-tasks.sh $MODULO $VERSION feature" echo " 2. Validar: ./validate-propagation-chain.sh " exit 0 else echo -e "${RED}[CASCADA CON ERRORES]${NC}" exit 1 fi