v1.7.0: refactor max_bot to flat structure, add VCF+UserModel+NLP history context, portal pages and proxy fixes

- Refactored max_bot from nested packages to flat module structure
- Q2: Extended BotUser model (patronymic, email, org, address, vcf_raw, contact_hash, phone_verified, email_verified, last_interaction, total_conversations, total_tickets)
- Q2: VCF parser (FN, N, TEL, EMAIL, ORG, ADR), upsert on re-contact, NLP history context (_get_user_history_context -> YandexGPT)
- Q1: Broadcast preview modal with 10s confirmation timer
- Q3: CSS var(--white)->var(--bg-card), var(--text)->var(--text-primary)
- Q4: bot_settings showNotification(), editable max_bot_id
- Q5: Webhook secret passthrough via X-Max-Bot-Api-Secret
- Masking sensitive keys, dialog_cleared handler, migrate via _add_column_if_not_exists()
- Rate limit (asyncio.sleep 0.5 per 10), dead code removed, conv.intent context in contact.py
- Portal pages: bot_consent, bot_kb (edit), bot_settings, bot_test, bot_tickets, portal_settings
- Tests: 21/21 passing, added test_yandex_gpt.py, test_email_sender.py
- Deploy: deploy_full.sh, schema.sql, seed_knowledge_base.sql
This commit is contained in:
2026-05-29 02:30:30 +03:00
parent 493e0b37a1
commit 72b6879f4b
234 changed files with 26768 additions and 6240 deletions
+222
View File
@@ -0,0 +1,222 @@
#!/bin/bash
# ==========================================
# AegisOne Engineering — Full Deployment Script
# ==========================================
# Usage: bash deploy.sh [--skip-ssl]
# Run on VPS as angel user
set -e
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
log() { echo -e "${CYAN}[$(date +%H:%M:%S)]${NC} $1"; }
ok() { echo -e " ${GREEN}$1${NC}"; }
info() { echo -e " ${YELLOW}$1${NC}"; }
fail() { echo -e " ${RED}$1${NC}"; exit 1; }
SKIP_SSL=false
for arg in "$@"; do [ "$arg" = "--skip-ssl" ] && SKIP_SSL=true; done
cd "$(dirname "$0")"
echo -e "${CYAN}"
echo "=========================================="
echo " AegisOne Engineering — Deploy v2.0"
echo "=========================================="
echo -e "${NC}"
# ==========================================
# PART 1: Server Preparation
# ==========================================
log "PART 1: Server preparation"
if ! command -v docker &>/dev/null; then
log "Installing Docker..."
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
ok "Docker installed. Re-login required for docker group"
newgrp docker
else
ok "Docker already installed: $(docker --version)"
fi
# Create project structure
log "Creating /opt/projects/ structure..."
sudo mkdir -p /opt/projects/{nginx-proxy,gitea,aegisone-php,aegisone-py,portainer,project2,backups,certs,data}
sudo chown -R "$USER":"$USER" /opt/projects
ok "Structure created"
# Create Docker networks
log "Creating Docker networks..."
docker network inspect proxy-net &>/dev/null || docker network create proxy-net && ok "proxy-net"
docker network inspect aegisone-net &>/dev/null || docker network create aegisone-net && ok "aegisone-net"
docker network inspect gitea-net &>/dev/null || docker network create gitea-net && ok "gitea-net"
# ==========================================
# PART 2: Deploy nginx-proxy
# ==========================================
log "PART 2: Deploy nginx-proxy"
NGX="/opt/projects/nginx-proxy"
cp nginx/nginx.conf "$NGX/"
cp -r nginx/conf.d/* "$NGX/conf.d/"
# Generate self-signed cert as placeholder
mkdir -p "$NGX/certs/live/aegisone.ru" "$NGX/html/.well-known/acme-challenge"
cat > "$NGX/html/index.html" <<< "<!DOCTYPE html><html><head><title>AegisOne</title></head><body><h1>AegisOne Engineering</h1></body></html>"
if [ ! -f "$NGX/certs/live/aegisone.ru/fullchain.pem" ]; then
log "Generating self-signed SSL cert..."
openssl req -x509 -nodes -days 30 -newkey rsa:2048 \
-keyout "$NGX/certs/live/aegisone.ru/privkey.pem" \
-out "$NGX/certs/live/aegisone.ru/fullchain.pem" \
-subj "/CN=aegisone.ru" 2>/dev/null || {
docker run --rm -v "$NGX/certs:/certs" alpine:latest sh -c "
apk add openssl >/dev/null 2>&1
mkdir -p /certs/live/aegisone.ru
openssl req -x509 -nodes -days 30 -newkey rsa:2048 \
-keyout /certs/live/aegisone.ru/privkey.pem \
-out /certs/live/aegisone.ru/fullchain.pem \
-subj '/CN=aegisone.ru'
"
}
ok "Self-signed cert created"
fi
cp nginx/docker-compose.yml "$NGX/"
cd "$NGX" && docker compose up -d
ok "nginx-proxy started"
# ==========================================
# PART 3: Deploy aegisone-py (FastAPI + PostgreSQL)
# ==========================================
log "PART 3: Deploy aegisone-py (FastAPI + PostgreSQL)"
PY="/opt/projects/aegisone-py"
# Copy all py_service files
rsync -a --delete py_service/ "$PY/" 2>/dev/null || cp -r py_service/* "$PY/"
# Override docker-compose.yml with updated network config
cp py_service/docker-compose.yml "$PY/"
cd "$PY" && docker compose up -d --build
ok "aegisone-py started"
# ==========================================
# PART 3B: Deploy max_bot (MAX messenger bot)
# ==========================================
log "PART 3B: Deploy max_bot (MAX messenger bot on port 8002)"
BOT="/opt/projects/aegisone-py/max_bot"
mkdir -p "$BOT"
rsync -a --delete max_bot/ "$BOT/" 2>/dev/null || cp -r max_bot/* "$BOT/"
# Copy nginx config for max.aegisone.ru
cp max_bot/nginx/max-aegisone.conf "$NGX/conf.d/max-aegisone.conf"
docker compose -f "$NGX/docker-compose.yml" exec nginx nginx -s reload 2>/dev/null || true
ok "max_bot nginx config deployed"
cd "$BOT" && docker compose up -d --build
ok "max_bot started on port 8002"
# ==========================================
# PART 4: Deploy aegisone-php (Public site)
# ==========================================
log "PART 4: Deploy aegisone-php (Public site)"
PHP="/opt/projects/aegisone-php"
# Copy PHP source files from repo root (excluding certain dirs)
mkdir -p "$PHP/src"
rsync -a --delete \
--exclude='.git' --exclude='node_modules' --exclude='*.zip' \
--exclude='py_service' --exclude='aegisone-php' --exclude='nginx' \
--exclude='gitea' --exclude='portainer' --exclude='opencode.json' \
--exclude='site_aegisone.zip' \
./ "$PHP/src/"
# Copy Docker infrastructure
cp aegisone-php/Dockerfile "$PHP/"
cp aegisone-php/nginx.conf "$PHP/"
cp aegisone-php/docker-compose.yml "$PHP/"
cd "$PHP" && docker compose up -d --build
ok "aegisone-php started"
# ==========================================
# PART 5: Deploy Gitea
# ==========================================
log "PART 5: Deploy Gitea"
GITEA="/opt/projects/gitea"
cp gitea/docker-compose.yml "$GITEA/"
cd "$GITEA" && docker compose up -d
ok "Gitea started"
# ==========================================
# PART 6: Deploy Portainer (port 9000)
# ==========================================
log "PART 6: Deploy Portainer"
P="/opt/projects/portainer"
cp portainer/docker-compose.yml "$P/"
cd "$P" && docker compose up -d
ok "Portainer started on port 9000"
# ==========================================
# PART 7: Configure UFW
# ==========================================
log "PART 7: Configure UFW"
if ! sudo ufw status | grep -q "Status: active"; then
sudo ufw --force disable 2>/dev/null || true
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw allow 9000/tcp comment 'Portainer'
sudo ufw --force enable
ok "UFW configured"
else
ok "UFW already active"
fi
# ==========================================
# PART 8: Get SSL certificates
# ==========================================
if [ "$SKIP_SSL" = false ]; then
log "PART 8: Obtaining Let's Encrypt SSL certificates"
cd "$NGX"
docker compose run --rm certbot certonly --webroot \
--webroot-path=/var/www/certbot \
-d aegisone.ru -d www.aegisone.ru \
-d service.aegisone.ru \
-d max.aegisone.ru \
-d git.aegisone.ru \
--email admin@aegisone.ru \
--agree-tos --non-interactive 2>/dev/null && {
ok "SSL certificates obtained"
docker compose exec nginx nginx -s reload
ok "Nginx reloaded with real certs"
} || info "Certbot failed — run manually after DNS propagation"
else
info "SSL step skipped (--skip-ssl)"
fi
# ==========================================
# Done
# ==========================================
echo ""
echo -e "${GREEN}=========================================="
echo " Deploy complete!"
echo "==========================================${NC}"
echo ""
echo " nginx-proxy: http://81.177.141.34 → aegisone.ru"
echo " Portainer: http://81.177.141.34:9000"
echo " FastAPI (direct): http://81.177.141.34:8000"
echo " Gitea (direct): http://81.177.141.34:3000"
echo ""
echo " After DNS propagation, run certbot:"
echo " cd /opt/projects/nginx-proxy"
echo " docker compose run --rm certbot certonly --webroot \\"
echo " --webroot-path=/var/www/certbot \\"
echo " -d aegisone.ru -d www.aegisone.ru \\"
echo " -d service.aegisone.ru -d max.aegisone.ru \\"
echo " -d git.aegisone.ru \\"
echo " --email admin@aegisone.ru --agree-tos --non-interactive"
echo " docker compose exec nginx nginx -s reload"
echo ""