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:
@@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# AegisOne MAX Bot + Portal — Full Auto Deploy
|
||||
# ============================================
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
REMOTE_USER="angel"
|
||||
REMOTE_HOST="81.177.141.34"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ AegisOne MAX Bot — Full Auto Deploy ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# === STEP 1: Run tests ===
|
||||
echo ">>> [1/5] Running tests..."
|
||||
cd "$SCRIPT_DIR"
|
||||
python -m pytest tests/ -v --tb=short 2>&1 || {
|
||||
echo "WARNING: Tests failed, but continuing with deploy..."
|
||||
}
|
||||
|
||||
# === STEP 2: Build archive ===
|
||||
echo ">>> [2/5] Building deployment archive..."
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
# Create exclude list for tar
|
||||
cat > /tmp/exclude_max_bot.txt << 'EXCL'
|
||||
max_bot/__pycache__
|
||||
max_bot/*.pyc
|
||||
max_bot/.pytest_cache
|
||||
max_bot/tests
|
||||
max_bot/logs
|
||||
EXCL
|
||||
|
||||
tar czf /tmp/max_bot_${TIMESTAMP}.tar.gz \
|
||||
-X /tmp/exclude_max_bot.txt \
|
||||
max_bot/
|
||||
|
||||
echo "Archive created: /tmp/max_bot_${TIMESTAMP}.tar.gz ($(du -h /tmp/max_bot_${TIMESTAMP}.tar.gz | cut -f1))"
|
||||
|
||||
# Also build py_service archive with the updated files
|
||||
cat > /tmp/exclude_py.txt << 'EXCL'
|
||||
py_service/__pycache__
|
||||
py_service/*.pyc
|
||||
py_service/.pytest_cache
|
||||
py_service/app/__pycache__
|
||||
py_service/app/routers/__pycache__
|
||||
py_service/app/templates/__pycache__
|
||||
EXCL
|
||||
|
||||
tar czf /tmp/py_service_bot_${TIMESTAMP}.tar.gz \
|
||||
-X /tmp/exclude_py.txt \
|
||||
py_service/app/templates/base.html \
|
||||
py_service/app/templates/_sidebar.html \
|
||||
py_service/app/routers/service_pages.py \
|
||||
py_service/app/templates/pages/bot_settings.html \
|
||||
py_service/app/templates/pages/bot_kb.html \
|
||||
py_service/app/templates/pages/bot_test.html \
|
||||
py_service/app/templates/pages/bot_tickets.html \
|
||||
py_service/app/templates/pages/bot_consent.html \
|
||||
py_service/app/templates/pages/portal_settings.html
|
||||
|
||||
# === STEP 3: Copy to server ===
|
||||
echo ">>> [3/5] Copying to server..."
|
||||
scp /tmp/max_bot_${TIMESTAMP}.tar.gz "$REMOTE_USER@$REMOTE_HOST:/tmp/"
|
||||
scp /tmp/py_service_bot_${TIMESTAMP}.tar.gz "$REMOTE_USER@$REMOTE_HOST:/tmp/"
|
||||
scp "$SCRIPT_DIR/sql/schema.sql" "$REMOTE_USER@$REMOTE_HOST:/tmp/bot_schema.sql"
|
||||
scp "$SCRIPT_DIR/sql/seed_knowledge_base.sql" "$REMOTE_USER@$REMOTE_HOST:/tmp/seed_kb.sql"
|
||||
|
||||
# === STEP 4: Remote deploy ===
|
||||
echo ">>> [4/5] Deploying on remote server..."
|
||||
ssh "$REMOTE_USER@$REMOTE_HOST" << 'REMOTESHELL'
|
||||
set -e
|
||||
echo "--- Remote deploy started ---"
|
||||
|
||||
# 4a. Apply SQL schema
|
||||
echo "Applying SQL schema..."
|
||||
PGPASSWORD=aegisone_pass psql -h localhost -U aegisone -d aegisone -f /tmp/bot_schema.sql 2>/dev/null || true
|
||||
|
||||
# 4b. Apply SQL seed (knowledge base)
|
||||
echo "Seeding knowledge base..."
|
||||
PGPASSWORD=aegisone_pass psql -h localhost -U aegisone -d aegisone -f /tmp/seed_kb.sql 2>/dev/null || true
|
||||
|
||||
# 4c. Deploy max_bot
|
||||
echo "Deploying max_bot service..."
|
||||
BACKUP="/opt/projects/backups/max_bot_$(date +%Y%m%d_%H%M%S)"
|
||||
if [ -d "/opt/projects/aegisone-py/max_bot" ]; then
|
||||
mkdir -p "/opt/projects/backups"
|
||||
cp -a "/opt/projects/aegisone-py/max_bot" "$BACKUP"
|
||||
echo "Backup saved to $BACKUP"
|
||||
fi
|
||||
|
||||
mkdir -p "/opt/projects/aegisone-py/max_bot"
|
||||
tar xzf /tmp/max_bot_*.tar.gz -C /opt/projects/aegisone-py/
|
||||
|
||||
cd /opt/projects/aegisone-py/max_bot
|
||||
docker compose down 2>/dev/null || true
|
||||
docker build --network host --no-cache -t max_bot-max_bot:latest .
|
||||
docker compose up -d
|
||||
|
||||
# 4d. Deploy py_service updates (portal pages) - using docker cp
|
||||
echo "Deploying portal updates..."
|
||||
# Templates
|
||||
PAGES_SRC="/opt/projects/aegisone-py/py_service/app/templates/pages"
|
||||
docker exec aegisone-app mkdir -p /app/app/templates/pages 2>/dev/null || true
|
||||
docker cp "/opt/projects/aegisone-py/py_service/app/templates/base.html" aegisone-app:/app/app/templates/base.html
|
||||
docker cp "/opt/projects/aegisone-py/py_service/app/templates/_sidebar.html" aegisone-app:/app/app/templates/_sidebar.html
|
||||
docker cp "$PAGES_SRC/bot_settings.html" aegisone-app:/app/app/templates/pages/bot_settings.html
|
||||
docker cp "$PAGES_SRC/bot_kb.html" aegisone-app:/app/app/templates/pages/bot_kb.html
|
||||
docker cp "$PAGES_SRC/bot_test.html" aegisone-app:/app/app/templates/pages/bot_test.html
|
||||
docker cp "$PAGES_SRC/bot_tickets.html" aegisone-app:/app/app/templates/pages/bot_tickets.html
|
||||
docker cp "$PAGES_SRC/bot_consent.html" aegisone-app:/app/app/templates/pages/bot_consent.html
|
||||
docker cp "$PAGES_SRC/portal_settings.html" aegisone-app:/app/app/templates/pages/portal_settings.html
|
||||
# Router
|
||||
docker cp "/opt/projects/aegisone-py/py_service/app/routers/service_pages.py" aegisone-app:/app/app/routers/service_pages.py
|
||||
docker restart aegisone-app 2>/dev/null || docker restart py_service_app_1 2>/dev/null || \
|
||||
docker compose -f /opt/projects/aegisone-py/py_service/docker-compose.yml restart app
|
||||
|
||||
# 4e. Update role permissions for engineer (add bot menu items)
|
||||
echo "Updating role permissions..."
|
||||
PGPASSWORD=aegisone_pass psql -h localhost -U aegisone -d aegisone -c "
|
||||
INSERT INTO role_menu_permissions (role, menu_key, visible)
|
||||
VALUES
|
||||
('engineer', 'bot_settings', true),
|
||||
('engineer', 'bot_kb', true),
|
||||
('engineer', 'bot_test', true),
|
||||
('engineer', 'bot_tickets', true),
|
||||
('engineer', 'bot_consent', true)
|
||||
ON CONFLICT DO NOTHING;
|
||||
" 2>/dev/null || true
|
||||
|
||||
# 4f. Register webhook subscription
|
||||
echo "Registering webhook..."
|
||||
sleep 3
|
||||
curl -s -o /dev/null -w "Health check: %{http_code}\n" https://max.aegisone.ru/health || echo "Health check failed"
|
||||
|
||||
# 4g. Cleanup temp files
|
||||
rm -f /tmp/max_bot_*.tar.gz /tmp/py_service_bot_*.tar.gz /tmp/bot_schema.sql /tmp/seed_kb.sql
|
||||
|
||||
echo "--- Remote deploy completed ---"
|
||||
REMOTESHELL
|
||||
|
||||
# === STEP 5: Verify ===
|
||||
echo ">>> [5/5] Verifying deployment..."
|
||||
sleep 3
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://max.aegisone.ru/health 2>/dev/null || echo "000")
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ Health check PASSED (HTTP $HTTP_CODE)"
|
||||
echo "✅ Bot is running at https://max.aegisone.ru"
|
||||
echo "✅ Portal: https://service.aegisone.ru/service/bot-settings"
|
||||
else
|
||||
echo "⚠️ Health check returned HTTP $HTTP_CODE"
|
||||
echo " Check the server: ssh $REMOTE_USER@$REMOTE_HOST 'docker logs max_bot'"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ Deploy completed at $(date) ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
Reference in New Issue
Block a user