refactor: Remove deprecated INTERNAL_API_PORT (ultrathin monolith cleanup)

Architecture cleanup after migration to ultrathin monolith:

- Remove INTERNAL_API_PORT from .env files (was port 8002)
- Clean up bot_main.py: remove uvicorn, Thread, run_internal_api()
- Update validate.md to check /api/telegram/health instead of port 8002
- Add deprecation notices to old Windows deployment docs
- Update docs/telegram/README.md with architecture note

The Telegram internal API is now served at /api/telegram/internal/*
on the main backend port (8000/8001) instead of separate port 8002.

Also includes: menu updates, ServerLogsView improvements, script fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-04 03:56:27 +02:00
parent 1e244eefea
commit f1f6760bef
16 changed files with 96 additions and 85 deletions

View File

@@ -401,9 +401,9 @@ else
exit 1 exit 1
fi fi
# Telegram Bot health check # Telegram Bot health check (now part of main backend on port 8000)
if check_port_available 8002; then if curl -s http://localhost:8000/api/telegram/health > /dev/null 2>&1; then
echo "✅ Telegram bot internal API is running on port 8002" echo "✅ Telegram bot is running (via main backend)"
else else
echo "⚠️ Telegram bot is not running (optional for validation)" echo "⚠️ Telegram bot is not running (optional for validation)"
fi fi

View File

@@ -143,7 +143,7 @@ TELEGRAM_BOT_TOKEN=your_bot_token_from_botfather
BACKEND_URL=http://localhost:8000 BACKEND_URL=http://localhost:8000
# Internal API port (bot's internal API for backend callbacks) # Internal API port (bot's internal API for backend callbacks)
INTERNAL_API_PORT=8002 # INTERNAL_API_PORT=8002 # DEPRECATED: Now served via main app at /api/telegram/internal/*
# Enable internal API documentation (development only) # Enable internal API documentation (development only)
ENABLE_DOCS=false ENABLE_DOCS=false

View File

@@ -137,7 +137,7 @@ TELEGRAM_BOT_TOKEN=your_bot_token_from_botfather
BACKEND_URL=http://localhost:8000 BACKEND_URL=http://localhost:8000
# Internal API port (bot's internal API for backend callbacks) # Internal API port (bot's internal API for backend callbacks)
INTERNAL_API_PORT=8002 # INTERNAL_API_PORT=8002 # DEPRECATED: Now served via main app at /api/telegram/internal/*
# Enable internal API documentation (DISABLE in production!) # Enable internal API documentation (DISABLE in production!)
ENABLE_DOCS=false ENABLE_DOCS=false

View File

@@ -144,7 +144,7 @@ TELEGRAM_BOT_TOKEN=8483383555:AAGNY1z6WiBkvVfy1ZV_gM_JnAqW4q4MlEY
BACKEND_URL=http://localhost:8000 BACKEND_URL=http://localhost:8000
# Internal API port (bot's internal API for backend callbacks) # Internal API port (bot's internal API for backend callbacks)
INTERNAL_API_PORT=8002 # INTERNAL_API_PORT=8002 # DEPRECATED: Now served via main app at /api/telegram/internal/*
# Enable internal API documentation (development only) # Enable internal API documentation (development only)
ENABLE_DOCS=false ENABLE_DOCS=false

View File

@@ -10,8 +10,7 @@ import logging
import os import os
from pathlib import Path from pathlib import Path
from dotenv import load_dotenv from dotenv import load_dotenv
import uvicorn # Note: uvicorn and threading removed - internal API now served via main.py
from threading import Thread
# ============================================================================ # ============================================================================
# LOAD ENVIRONMENT VARIABLES FIRST - BEFORE ANY APP IMPORTS # LOAD ENVIRONMENT VARIABLES FIRST - BEFORE ANY APP IMPORTS
@@ -69,8 +68,7 @@ from backend.modules.telegram.bot.handlers import (
# Import email authentication handler # Import email authentication handler
from backend.modules.telegram.bot.email_handlers import email_login_handler from backend.modules.telegram.bot.email_handlers import email_login_handler
# Import internal API # Note: internal_api import removed - now served via main.py at /api/telegram/internal/*
from backend.modules.telegram.internal_api import internal_api
# Configure logging # Configure logging
logging.basicConfig( logging.basicConfig(
@@ -82,7 +80,7 @@ logger = logging.getLogger(__name__)
# Environment variables (already loaded above) # Environment variables (already loaded above)
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN') TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
BACKEND_URL = os.getenv('BACKEND_URL', 'http://localhost:8000') BACKEND_URL = os.getenv('BACKEND_URL', 'http://localhost:8000')
INTERNAL_API_PORT = int(os.getenv('INTERNAL_API_PORT', '8002')) # Note: INTERNAL_API_PORT removed - internal API now served via main.py
# ============================================================================ # ============================================================================
@@ -153,29 +151,10 @@ def create_telegram_application() -> Application:
return application return application
# ============================================================================
# INTERNAL API SERVER
# ============================================================================
def run_internal_api():
"""
Run the internal FastAPI server in a separate thread.
This API handles communication from the backend (saving auth codes).
"""
logger.info(f"Starting internal API on port {INTERNAL_API_PORT}...")
uvicorn.run(
internal_api,
host="0.0.0.0",
port=INTERNAL_API_PORT,
log_level="info"
)
# ============================================================================ # ============================================================================
# STARTUP/SHUTDOWN # STARTUP/SHUTDOWN
# ============================================================================ # ============================================================================
# Note: Internal API server removed - now served via main.py at /api/telegram/internal/*
async def startup(): async def startup():
""" """
@@ -247,10 +226,7 @@ async def main():
# Create Telegram application # Create Telegram application
telegram_app = create_telegram_application() telegram_app = create_telegram_application()
# Start internal API in a separate thread # Note: Internal API server removed - now served via main.py
api_thread = Thread(target=run_internal_api, daemon=True)
api_thread.start()
logger.info(f"✅ Internal API started on port {INTERNAL_API_PORT}")
# Start scheduled cleanup task in background # Start scheduled cleanup task in background
cleanup_task = asyncio.create_task(scheduled_cleanup()) cleanup_task = asyncio.create_task(scheduled_cleanup())

View File

@@ -1,9 +1,20 @@
# ROA2WEB Telegram Bot - Windows Server Deployment Guide # ROA2WEB Telegram Bot - Windows Server Deployment Guide
> ⚠️ **DEPRECATED ARCHITECTURE**
>
> This documentation refers to the OLD microservices architecture where the Telegram bot
> ran as a separate service on port 8002. The current architecture is an **ultrathin monolith**
> where everything runs on a single port (8000/8001) via `backend/main.py`.
>
> **Current Architecture**: Telegram bot runs as a background task within the unified backend.
> Internal API endpoints are now at `/api/telegram/internal/*` on the main port.
>
> See `CLAUDE.md` and `QUICK-START.md` for the current architecture.
**Target Server**: Windows Server (10.0.20.36) **Target Server**: Windows Server (10.0.20.36)
**Deployment Method**: Windows Service (NSSM) - No Docker **Deployment Method**: Windows Service (NSSM) - No Docker
**Service Name**: ROA2WEB-TelegramBot **Service Name**: ROA2WEB-TelegramBot
**Internal API Port**: 8002 **Internal API Port**: ~~8002~~ (DEPRECATED - now via main backend)
**Created**: 2025-10-22 **Created**: 2025-10-22
**Last Updated**: 2025-10-22 **Last Updated**: 2025-10-22

View File

@@ -1,5 +1,11 @@
# ROA2WEB Telegram Bot - Windows Deployment Troubleshooting Guide # ROA2WEB Telegram Bot - Windows Deployment Troubleshooting Guide
> ⚠️ **DEPRECATED ARCHITECTURE**
>
> This documentation refers to the OLD microservices architecture (port 8002).
> The current architecture is an **ultrathin monolith** - everything on port 8000/8001.
> Telegram internal API is now at `/api/telegram/internal/*` on the main backend.
This guide helps diagnose and fix common issues with Telegram bot integration on Windows Server deployments. This guide helps diagnose and fix common issues with Telegram bot integration on Windows Server deployments.
## Problem: "Link invalid sau expirat" (Invalid or expired link) ## Problem: "Link invalid sau expirat" (Invalid or expired link)

View File

@@ -1,5 +1,12 @@
# ROA2WEB Telegram Bot # ROA2WEB Telegram Bot
> ⚠️ **ARCHITECTURE NOTE**
>
> This documentation partially references the old standalone bot architecture.
> The current architecture is an **ultrathin monolith** where the Telegram bot runs
> as a background task within the main backend (`backend/main.py`) on port 8000/8001.
> The `INTERNAL_API_PORT` variable is no longer used - internal API is at `/api/telegram/internal/*`.
> **Telegram Frontend for ROA2WEB ERP System** with Direct Command Interface > **Telegram Frontend for ROA2WEB ERP System** with Direct Command Interface
## Overview ## Overview
@@ -117,8 +124,8 @@ BACKEND_URL=http://localhost:8001
# Database # Database
SQLITE_DB_PATH=./data/telegram_bot.db SQLITE_DB_PATH=./data/telegram_bot.db
# Internal API (for backend communication) # Internal API - DEPRECATED (now served via main backend at /api/telegram/internal/*)
INTERNAL_API_PORT=8002 # INTERNAL_API_PORT=8002
# Optional # Optional
LOG_LEVEL=INFO LOG_LEVEL=INFO

View File

@@ -1,5 +1,11 @@
# 🐳 Docker Testing Guide - ROA2WEB Telegram Bot # 🐳 Docker Testing Guide - ROA2WEB Telegram Bot
> ⚠️ **DEPRECATED ARCHITECTURE**
>
> This guide references the OLD microservices architecture (separate Telegram container on port 8002).
> The current architecture is an **ultrathin monolith** where the Telegram bot runs as a background
> task within the main backend (port 8000/8001). No separate Docker container needed for Telegram.
This guide provides instructions for testing the Telegram bot Docker deployment. This guide provides instructions for testing the Telegram bot Docker deployment.
## 📋 Prerequisites ## 📋 Prerequisites

View File

@@ -20,7 +20,8 @@ export const menuSections = [
items: [ items: [
{ to: '/reports/telegram', icon: 'pi pi-telegram', label: 'Telegram Bot' }, { to: '/reports/telegram', icon: 'pi pi-telegram', label: 'Telegram Bot' },
{ to: '/reports/cache-stats', icon: 'pi pi-chart-bar', label: 'Statistici Cache' }, { to: '/reports/cache-stats', icon: 'pi pi-chart-bar', label: 'Statistici Cache' },
{ to: '/data-entry/ocr-metrics', icon: 'pi pi-eye', label: 'Statistici OCR' } { to: '/data-entry/ocr-metrics', icon: 'pi pi-eye', label: 'Statistici OCR' },
{ to: '/reports/server-logs', icon: 'pi pi-server', label: 'Server Logs' }
] ]
} }
] ]

View File

@@ -70,7 +70,11 @@
<p>No log entries found</p> <p>No log entries found</p>
</div> </div>
<div v-else class="logs-container" ref="logsContainer"> <div v-else class="logs-container" ref="logsContainer">
<pre class="logs-content"><code v-for="(line, index) in logs" :key="index" :class="getLineClass(line)">{{ line }}</code></pre> <pre class="logs-content"><code
v-for="(line, index) in logs"
:key="index"
:style="getLineStyle(line)"
>{{ line }}</code></pre>
</div> </div>
</template> </template>
</Card> </Card>
@@ -173,18 +177,28 @@ const loadLogs = async () => {
} }
} }
const getLineClass = (line) => { const getLineStyle = (line) => {
const lineLower = line.toLowerCase() const lineLower = line.toLowerCase()
const baseStyle = {
display: 'block',
padding: '3px 8px',
borderRadius: '2px',
fontFamily: "'Consolas', 'Monaco', 'Courier New', monospace",
fontSize: '0.8125rem',
lineHeight: '1.6'
}
if (lineLower.includes('error') || lineLower.includes('exception') || lineLower.includes('failed')) { if (lineLower.includes('error') || lineLower.includes('exception') || lineLower.includes('failed')) {
return 'log-error' return { ...baseStyle, color: '#b91c1c', backgroundColor: 'rgba(185, 28, 28, 0.1)', fontWeight: '600' }
} }
if (lineLower.includes('warning') || lineLower.includes('warn')) { if (lineLower.includes('warning') || lineLower.includes('warn')) {
return 'log-warning' return { ...baseStyle, color: '#b45309', backgroundColor: 'rgba(180, 83, 9, 0.1)', fontWeight: '500' }
} }
if (lineLower.includes('success') || lineLower.includes('completed')) { if (lineLower.includes('success') || lineLower.includes('completed')) {
return 'log-success' return { ...baseStyle, color: '#047857', backgroundColor: 'rgba(4, 120, 87, 0.1)' }
} }
return 'log-info' // Default: pure black text on light background
return { ...baseStyle, color: '#000000', backgroundColor: 'rgba(0, 0, 0, 0.02)' }
} }
const toggleAutoRefresh = () => { const toggleAutoRefresh = () => {
@@ -329,43 +343,17 @@ onUnmounted(() => {
.logs-container { .logs-container {
max-height: 600px; max-height: 600px;
overflow-y: auto; overflow-y: auto;
background: var(--color-bg-secondary, #1e1e1e); background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: var(--radius-md); border-radius: var(--radius-md);
padding: var(--space-sm); padding: var(--space-sm);
} }
.logs-content { .logs-content {
margin: 0; margin: 0;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 0.8125rem;
line-height: 1.5;
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-all; word-break: break-all;
} background: transparent;
.logs-content code {
display: block;
padding: 2px var(--space-xs);
border-radius: 2px;
}
.log-error {
color: #f87171;
background: rgba(248, 113, 113, 0.1);
}
.log-warning {
color: #fbbf24;
background: rgba(251, 191, 36, 0.1);
}
.log-success {
color: #34d399;
background: rgba(52, 211, 153, 0.1);
}
.log-info {
color: #e5e7eb;
} }
/* Responsive */ /* Responsive */

View File

@@ -83,7 +83,7 @@ import axios from "axios";
// Telegram API uses /api/telegram (separate from reports) // Telegram API uses /api/telegram (separate from reports)
const telegramApi = axios.create({ const telegramApi = axios.create({
baseURL: import.meta.env.BASE_URL + 'api/telegram', baseURL: '/api/telegram',
headers: { 'Content-Type': 'application/json' } headers: { 'Content-Type': 'application/json' }
}); });

View File

@@ -12,7 +12,10 @@ source "$SCRIPT_DIR/scripts/service-helpers.sh"
# Service configuration # Service configuration
SERVICE_NAME="Unified Backend" SERVICE_NAME="Unified Backend"
PORT=8000 PORT=8000
LOG_FILE="/tmp/unified-backend.log" LOGS_DIR="$ROOT_DIR/logs"
LOG_FILE_STDOUT="$LOGS_DIR/backend-stdout.log"
LOG_FILE_STDERR="$LOGS_DIR/backend-stderr.log"
LOG_FILE="$LOG_FILE_STDERR" # Default for status/logs commands
BACKEND_DIR="$ROOT_DIR/backend" BACKEND_DIR="$ROOT_DIR/backend"
VENV_DIR="$BACKEND_DIR/venv" VENV_DIR="$BACKEND_DIR/venv"
ENV_FILE="$BACKEND_DIR/.env" ENV_FILE="$BACKEND_DIR/.env"
@@ -59,11 +62,16 @@ start_backend() {
print_info "Starting unified backend on port $PORT..." print_info "Starting unified backend on port $PORT..."
cd "$BACKEND_DIR" cd "$BACKEND_DIR"
# Clear old log file # Create logs directory if it doesn't exist
> "$LOG_FILE" mkdir -p "$LOGS_DIR"
# Clear old log files
> "$LOG_FILE_STDOUT"
> "$LOG_FILE_STDERR"
# Activate virtual environment and start uvicorn # Activate virtual environment and start uvicorn
nohup bash -c "source venv/bin/activate && uvicorn main:app --host 0.0.0.0 --port $PORT --reload" > "$LOG_FILE" 2>&1 & # stdout → backend-stdout.log, stderr → backend-stderr.log
nohup bash -c "source venv/bin/activate && uvicorn main:app --host 0.0.0.0 --port $PORT --reload" > "$LOG_FILE_STDOUT" 2> "$LOG_FILE_STDERR" &
BACKEND_PID=$! BACKEND_PID=$!
cd "$ROOT_DIR" cd "$ROOT_DIR"

View File

@@ -7,6 +7,9 @@
set -e # Exit on any error set -e # Exit on any error
# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'
@@ -164,13 +167,18 @@ else
source .env source .env
set +a set +a
# Clear old log files # Create logs directory if not exists
> /tmp/unified_backend_prod.log mkdir -p "$SCRIPT_DIR/logs"
# Clear old log files (use logs/ for ServerLogs UI, keep /tmp for quick access)
> "$SCRIPT_DIR/logs/backend-stdout.log"
> "$SCRIPT_DIR/logs/backend-stderr.log"
> /tmp/unified_frontend_prod.log > /tmp/unified_frontend_prod.log
# Start backend with auto-restart on crash (OOM protection) # Start backend with auto-restart on crash (OOM protection)
# Logs go to logs/backend-stderr.log for ServerLogs UI
print_message "Starting unified backend with auto-restart (includes Reports, Data Entry, and Telegram bot)..." print_message "Starting unified backend with auto-restart (includes Reports, Data Entry, and Telegram bot)..."
nohup ./run-with-restart.sh 8000 /tmp/unified_backend_prod.log > /dev/null 2>&1 & nohup ./run-with-restart.sh 8000 "$SCRIPT_DIR/logs/backend-stderr.log" > /dev/null 2>&1 &
cd - > /dev/null cd - > /dev/null
@@ -192,8 +200,8 @@ else
done done
if ! check_port 8000; then if ! check_port 8000; then
print_error "Unified Backend failed to start - check /tmp/unified_backend_prod.log" print_error "Unified Backend failed to start - check logs/backend-stderr.log"
tail -n 30 /tmp/unified_backend_prod.log tail -n 30 "$SCRIPT_DIR/logs/backend-stderr.log"
cleanup cleanup
fi fi
fi fi
@@ -253,7 +261,7 @@ echo " • Unified API Docs: http://localhost:8000/docs"
echo " • Health Check: http://localhost:8000/health" echo " • Health Check: http://localhost:8000/health"
echo echo
echo -e "${BLUE}Log Files:${NC}" echo -e "${BLUE}Log Files:${NC}"
echo " • Unified Backend: /tmp/unified_backend_prod.log" echo " • Unified Backend: logs/backend-stderr.log"
echo " • Unified Frontend: /tmp/unified_frontend_prod.log" echo " • Unified Frontend: /tmp/unified_frontend_prod.log"
echo echo
echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}" echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}"