Files
Autoparts-DB/scripts/backup.sh
consultoria-as a386ca5b4a
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled
Mejoras de sesion: estabilizacion, IA, Nexus Yonke y marketplace B2B
- F0 blindaje: Redis/Celery, pg_hba sin trust LAN, secretos a env 600, backups, webhook auth, jobs muertos
- F1 caja: bugs POS, reembolsos al corte, apartados, CFDI, topes de descuento en cotizacion/apartado
- F2/F7 IA de catalogo: autocategorizacion, dedup de SKUs con embeddings, OCR de facturas, descripciones, claves SAT, limpieza de fitment
- F3 IA en el flujo: vision Yonke, preguntas MeLi, venta cruzada, anomalias, sinonimos, busqueda semantica (rerank/embeddings)
- F4/F8 escala y cartera: /metrics+Prometheus+Grafana, pool, score de credito, churn, metricas multi-tenant
- Nexus Yonke (M1-M6): modelo de datos 1-de-1, alta por donador, vitrina publica, MeLi usado, consignacion, garantia por dias, reportes, etiquetas
- Marketplace B2B entre yonkes (catalogo + pedidos cross-tenant)
- Seguridad: auth en /api/admin/* (35 endpoints), alertas por tenant
- Migraciones v4.27/v4.28; timers expire-demos y rollup-metrics
2026-10-12 00:57:31 +00:00

108 lines
3.6 KiB
Bash
Executable File

#!/bin/bash
# Nexus Autoparts — Automated Backup Script
# Backs up PostgreSQL + project files, uploads to S3/GCS if configured.
# Usage: ./backup.sh [--dry-run]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
BACKUP_DIR="${PROJECT_DIR}/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="nexus_backup_${TIMESTAMP}"
DRY_RUN=false
# ─── Config ───
DB_NAME="${BACKUP_DB_NAME:-nexus_autoparts}"
DB_USER="${BACKUP_DB_USER:-postgres}"
S3_BUCKET="${BACKUP_S3_BUCKET:-}"
S3_PREFIX="${BACKUP_S3_PREFIX:-nexus-backups}"
AWS_CLI="${PROJECT_DIR}/tools/bin/aws"
RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}"
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=true
echo "[DRY-RUN] No changes will be made."
fi
mkdir -p "$BACKUP_DIR"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
# ─── Cleanup old backups (FIRST, so a full disk cannot block it) ───
log "Cleaning up backups older than $RETENTION_DAYS days ..."
if [[ "$DRY_RUN" == true ]]; then
log "DRY-RUN: would delete backups older than $RETENTION_DAYS days"
else
find "$BACKUP_DIR" -name "nexus_backup_*.tar.gz" -type f -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "nexus_backup_*.sql" -type f -mtime +$RETENTION_DAYS -delete
# Remove empty leftovers from failed runs (e.g. 0-byte dumps when disk was full)
find "$BACKUP_DIR" -name "nexus_backup_*" -type f -empty -delete
log "Cleanup complete. Disk usage: $(df -h / | awk 'NR==2{print $3"/"$2" ("$5")"}')"
fi
# ─── PostgreSQL dump ───
log "Dumping PostgreSQL database: $DB_NAME ..."
DUMP_FILE="${BACKUP_DIR}/${BACKUP_NAME}.sql"
if [[ "$DRY_RUN" == true ]]; then
log "DRY-RUN: would run pg_dump -Fc -d $DB_NAME > $DUMP_FILE"
else
sudo -u "$DB_USER" pg_dump -Fc -d "$DB_NAME" > "$DUMP_FILE"
log "Dump complete: $DUMP_FILE ($(du -h "$DUMP_FILE" | cut -f1))"
fi
# ─── Project files tar ───
log "Creating project archive ..."
ARCHIVE_FILE="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
if [[ "$DRY_RUN" == true ]]; then
log "DRY-RUN: would tar project files -> $ARCHIVE_FILE"
else
tar czf "$ARCHIVE_FILE" \
--exclude='backups/*.tar.gz' \
--exclude='backups/*.sql' \
--exclude='node_modules' \
--exclude='__pycache__' \
--exclude='.venv' \
--exclude='venv' \
--exclude='.git' \
--exclude='*.pyc' \
--exclude='pos/static/js/*.min.js' \
--exclude='pos/static/css/*.min.css' \
-C "$PROJECT_DIR" .
log "Archive complete: $ARCHIVE_FILE ($(du -h "$ARCHIVE_FILE" | cut -f1))"
fi
# ─── Combine into single backup ───
COMBINED="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
if [[ "$DRY_RUN" == true ]]; then
log "DRY-RUN: would create combined backup"
else
# Rename archive to combined and append dump
FINAL="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
mv "$ARCHIVE_FILE" "$FINAL"
log "Backup ready: $FINAL ($(du -h "$FINAL" | cut -f1))"
fi
# ─── Upload to S3 ───
if [[ -n "$S3_BUCKET" ]]; then
if [[ -x "$AWS_CLI" ]]; then
log "Uploading to s3://${S3_BUCKET}/${S3_PREFIX}/ ..."
if [[ "$DRY_RUN" == true ]]; then
log "DRY-RUN: would run aws s3 cp $COMBINED s3://$S3_BUCKET/$S3_PREFIX/"
else
"$AWS_CLI" s3 cp "$COMBINED" "s3://${S3_BUCKET}/${S3_PREFIX}/" --storage-class STANDARD_IA
log "Upload complete."
fi
else
log "WARNING: AWS CLI not found at $AWS_CLI. Skipping S3 upload."
fi
else
log "INFO: S3_BUCKET not set. Skipping cloud upload."
fi
# ─── Cleanup ───
log "Post-backup cleanup (already done at start)."
log "Done."