chore(07): remove deprecated bash scripts and legacy env files

This commit is contained in:
2026-04-23 12:56:30 +03:00
parent 01e30ba7b5
commit d9dffdc389
14 changed files with 165 additions and 512 deletions

View File

@@ -0,0 +1,48 @@
# Phase 7 Wave 2 Summary: Backend Config Refactoring (07-02)
**Completed:** 2026-04-23
**Status:** [COMPLETED]
**Commits:** ae61fa63, 28cdc900, 938fd2da, 225972b8
---
## Accomplishments
1. **backend/config_loader.py Refactored**
- Implemented YAML parsing using PyYAML
- Enforced D-06 load order: System Env Vars > `config/backend.yaml` > `config/secrets.yaml` > Defaults
- Added robust validation for required fields (JWT_SECRET_KEY, primary_ai_provider)
- Masked sensitive values in logs
2. **backend/config_manager.py Updated**
- Refactored to handle YAML file operations (`read_config`, `update_config`)
- Removed legacy `.env` file manipulation logic
3. **backend/main.py Updated**
- Switched from direct `os.environ` access to the centralized `get_config()` dict
- Removed `load_dotenv()` and `inventory.env` references
4. **backend/entrypoint.sh Updated**
- Updated to document the new YAML configuration structure
- Added safety checks for the existence of `backend.yaml`
5. **Additional Backend Files Cleaned Up**
- Refactored `backend/ai_vision.py`, `backend/check_models.py`, `backend/ai/gemini.py`, and `backend/ai/claude.py` to use `config_loader`
- Completely removed `python-dotenv` dependency from backend
---
## Technical Details
- **Load Order (D-06):** Env Vars override YAML, YAML overrides Defaults.
- **Deprecation (D-04):** `inventory.env` is no longer used by the backend application logic.
- **Security:** Sensitive configuration values are masked in application logs to prevent data leaks.
---
## Verification
- [x] All updated Python files passed `py_compile` checks
- [x] No `load_dotenv()` or `inventory.env` references remain in backend code
- [x] Configuration loading logs which source was used for each value
- [x] Environment variables correctly override YAML values in `config_loader.py`

View File

@@ -0,0 +1,45 @@
# Phase 7 Wave 2 Summary: Python Deployment Scripts (07-03)
**Completed:** 2026-04-23
**Status:** [COMPLETED]
**Commits:** ce79c919, 1621625b, 63f72c11, 9253eb65
---
## Accomplishments
1. **scripts/deploy.py Created**
- Replaces `deploy.sh` with a secure, robust Python implementation
- Implements pre-flight checks, port availability validation, and health check polling
- Parses YAML config from `config/docker.yaml` and `config/network.yaml`
2. **scripts/run_standalone.py Created**
- Replaces `run_standalone.sh` for multi-process management without Docker
- Handles graceful shutdown (SIGINT/SIGTERM) of both backend and frontend
- Provides prefixed, colored console output for logs
3. **scripts/install_service.py Created**
- Replaces `install_service.sh` for systemd service setup
- Generates service file from template with correct YAML-based paths
4. **scripts/export_prod.py Created**
- Replaces `export_prod.sh` for production data backups
- Explicitly excludes `config/secrets.yaml` to ensure security in backups
---
## Technical Details
- **YAML Parsing (D-05):** All scripts use PyYAML to read the new centralized configuration structure.
- **Security:** Subprocess calls use `shell=False` with list arguments to prevent injection attacks.
- **Tooling:** Implemented consistent logging and color output for developer experience.
---
## Verification
- [x] All 4 Python scripts are executable (`chmod +x`)
- [x] All scripts use the proper shebang (`#!/usr/bin/env python3`)
- [x] All scripts correctly parse the YAML configuration files
- [x] Subprocess execution follows security best practices
- [x] Error handling and helpful feedback messages are present in all tools

View File

@@ -0,0 +1,44 @@
# Phase 7 Wave 3 Summary: Docker Integration & Documentation (07-04)
**Completed:** 2026-04-23
**Status:** [COMPLETED]
**Commits:** 9f267a53, 5b3a23f9, 6b7becfe, 0c6f571a, 22343941, 01e30ba7
---
## Accomplishments
1. **docker-compose.yml Updated (D-07)**
- Removed `inventory.env` `env_file` references
- Added `./config:/app/config:ro` volume mounts for `backend`, `frontend`, and `proxy`
- Documented environment variable override behavior in comments
2. **Dockerfile and entrypoint.sh Updated**
- Backend `Dockerfile` and `entrypoint.sh` refactored to use the new `/app/config/` paths
- Implemented config validation check during container startup
3. **.gitignore Rules Finalized (D-08)**
- Marked `inventory.env` as deprecated
- Confirmed rules to ignore actual configurations while tracking `.example` schema files
4. **Comprehensive Documentation (D-08)**
- **DEPLOYMENT.md:** Completely rewritten to reflect the new YAML configuration system and Python-based tooling
- **README.md:** Updated Quick Start and onboarding with the new configuration steps
- Cross-referenced all documents for consistent developer experience
---
## Technical Details
- **Single Source of Truth:** `config/` folder is now established as the central point for all configuration.
- **Security:** `secrets.yaml` is strictly ignored by git, and the Docker volume is mounted as read-only.
- **Deprecation:** All references to `inventory.env` in the deployment infrastructure have been removed.
---
## Verification
- [x] `docker compose config` passes with valid YAML syntax
- [x] `.gitignore` rules correctly protect sensitive configuration files
- [x] `DEPLOYMENT.md` and `README.md` provide clear, updated instructions
- [x] All deployment paths integrated with the new YAML structure

View File

@@ -2,9 +2,11 @@ import os
import anthropic
import json
import base64
from ..config_loader import get_config
def extract(image_bytes: bytes, prompt: str):
api_key = os.environ.get("CLAUDE_API_KEY")
config = get_config()
api_key = config.get("ai", {}).get("claude_api_key")
if not api_key:
return None

View File

@@ -5,6 +5,7 @@ import logging
from PIL import Image
from google import genai
from google.genai import types
from ..config_loader import get_config
log = logging.getLogger("ainventory")
@@ -18,9 +19,10 @@ def get_best_models():
]
def extract(image_bytes: bytes, prompt: str):
api_key = os.environ.get("GEMINI_API_KEY")
config = get_config()
api_key = config.get("ai", {}).get("gemini_api_key")
if not api_key:
log.error("CRITICAL: GEMINI_API_KEY is MISSING in environment!")
log.error("CRITICAL: gemini_api_key is MISSING in configuration!")
return None
# Log partial key for safety debug

View File

@@ -1,6 +1,5 @@
import os
import time
from dotenv import load_dotenv
from . import models
from .database import SessionLocal
from .ai import gemini, claude

View File

@@ -1,12 +1,17 @@
import os
import google.generativeai as genai
from dotenv import load_dotenv
try:
from backend.config_loader import get_config
except ImportError:
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from backend.config_loader import get_config
load_dotenv()
API_KEY = os.environ.get("GEMINI_API_KEY")
config = get_config()
API_KEY = config.get("ai", {}).get("gemini_api_key")
if not API_KEY:
print("Error: GEMINI_API_KEY not found in .env")
print("Error: gemini_api_key not found in config/backend.yaml, config/secrets.yaml or GEMINI_API_KEY environment variable")
exit(1)
genai.configure(api_key=API_KEY)

View File

@@ -72,6 +72,12 @@ def _apply_env_overrides(config):
"LOGS_DIR": (("application", "logs_dir"), str),
"BACKEND_APPLICATION_CORS_ORIGINS": (("application", "cors_origins"), str),
"EXTRA_ALLOWED_ORIGINS": (("application", "cors_origins"), str),
"ALLOWED_ORIGINS": (("application", "cors_origins"), str),
"SERVER_IP": (("application", "server_ip"), str),
"FRONTEND_PORT": (("application", "frontend_port"), str),
"FRONTEND_SSL_PORT": (("application", "frontend_ssl_port"), str),
"BACKEND_PORT": (("application", "backend_port"), str),
"BACKEND_SSL_PORT": (("application", "backend_ssl_port"), str),
}
sensitive_vars = [
@@ -136,7 +142,12 @@ def load_config() -> dict:
"application": {
"data_dir": "./data",
"logs_dir": "./logs",
"cors_origins": "http://localhost:8917"
"cors_origins": "http://localhost:8917",
"server_ip": "localhost",
"frontend_port": "8917",
"frontend_ssl_port": "8919",
"backend_port": "8918",
"backend_ssl_port": "8918"
},
"features": {
"ai_extraction_enabled": True,

222
deploy.sh
View File

@@ -1,222 +0,0 @@
#!/bin/bash
set -euo pipefail
# Phase 6, Plan 1, Task 4: Automated Deployment Script
# Usage: ./deploy.sh [production|staging|development] [--rebuild]
# Purpose: Single-command deployment with Docker Compose, pre-flight checks, and health validation
DEPLOYMENT_ENV="${1:-production}"
REBUILD_FLAG="${2:---no-rebuild}"
# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
log_info "=== TFM aInventory Deployment Script ==="
log_info "Environment: $DEPLOYMENT_ENV"
log_info "Rebuild: $REBUILD_FLAG"
# ============================================================================
# STEP 1: Pre-flight checks
# ============================================================================
log_info "Step 1/10: Running pre-flight checks..."
command -v docker &> /dev/null || log_error "Docker not installed. Please install Docker 24.0+"
log_success " ✓ Docker is installed"
command -v docker-compose &> /dev/null || log_error "Docker Compose not installed. Please install Docker Compose 2.0+"
log_success " ✓ Docker Compose is installed"
[[ -f "docker-compose.yml" ]] || log_error "docker-compose.yml not found in current directory"
log_success " ✓ docker-compose.yml found"
[[ -f "inventory.env" ]] || log_warn "inventory.env not found; attempting to create from template..."
if [[ ! -f "inventory.env" ]] && [[ -f "inventory.env.template" ]]; then
cp inventory.env.template inventory.env
log_success " ✓ inventory.env created from template (review and customize)"
elif [[ ! -f "inventory.env" ]]; then
log_error "inventory.env not found and no template available. Create inventory.env before deploying."
fi
# ============================================================================
# STEP 2: Validate environment file
# ============================================================================
log_info "Step 2/10: Validating inventory.env..."
if [[ ! -f ".env.validation.sh" ]]; then
log_warn " .env.validation.sh not found; skipping validation"
else
bash .env.validation.sh || log_error "Environment validation failed"
fi
log_success " ✓ Environment variables validated"
# ============================================================================
# STEP 3: Check port availability
# ============================================================================
log_info "Step 3/10: Checking port availability..."
# Source inventory.env to get port values
source inventory.env
BACKEND_PORT=${BACKEND_PORT:-8000}
FRONTEND_PORT=${FRONTEND_PORT:-3000}
BACKEND_SSL_PORT=${BACKEND_SSL_PORT:-8918}
FRONTEND_SSL_PORT=${FRONTEND_SSL_PORT:-8919}
for port in "$BACKEND_PORT" "$FRONTEND_PORT" "$BACKEND_SSL_PORT" "$FRONTEND_SSL_PORT"; do
if command -v netstat &> /dev/null; then
if netstat -tuln 2>/dev/null | grep -q ":$port "; then
log_error "Port $port is already in use. Choose a different port in inventory.env"
fi
else
log_warn " netstat not available; skipping port check (ensure ports are available)"
fi
done
log_success " ✓ All required ports are available"
# ============================================================================
# STEP 4: Check disk space
# ============================================================================
log_info "Step 4/10: Checking disk space..."
AVAILABLE_SPACE=$(df . | awk 'NR==2 {print $4}')
REQUIRED_SPACE=$((10 * 1024 * 1024)) # 10GB in KB
if [[ $AVAILABLE_SPACE -lt $REQUIRED_SPACE ]]; then
log_warn " Available space: $(($AVAILABLE_SPACE / 1024 / 1024))GB (recommended: 10GB+)"
else
log_success " ✓ Sufficient disk space available ($(($AVAILABLE_SPACE / 1024 / 1024))GB)"
fi
# ============================================================================
# STEP 5: Build or pull images
# ============================================================================
log_info "Step 5/10: Building Docker images..."
if [[ "$REBUILD_FLAG" == "--rebuild" ]]; then
log_info " Building with --no-cache (full rebuild)..."
docker-compose build --no-cache || log_error "Docker build failed"
else
log_info " Building with layer cache (incremental)..."
docker-compose build || log_error "Docker build failed"
fi
log_success " ✓ Docker images built successfully"
# ============================================================================
# STEP 6: Create data directories
# ============================================================================
log_info "Step 6/10: Preparing data directories..."
mkdir -p data logs config
mkdir -p data/caddy_data data/caddy_config
chmod -R 777 data logs config
log_success " ✓ Data directories created with proper permissions"
# ============================================================================
# STEP 7: Initialize database
# ============================================================================
log_info "Step 7/10: Checking database initialization..."
if [[ ! -f "data/inventory.db" ]]; then
log_info " Database not found; will be initialized on first backend startup"
log_success " ✓ Database initialization scheduled"
else
log_success " ✓ Existing database found; reusing"
fi
# ============================================================================
# STEP 8: Start services
# ============================================================================
log_info "Step 8/10: Starting Docker services..."
docker-compose up -d || log_error "Failed to start Docker services"
log_success " ✓ Services started in background"
# ============================================================================
# STEP 9: Wait for health checks
# ============================================================================
log_info "Step 9/10: Waiting for services to become healthy (max 60 seconds)..."
max_attempts=30
attempt=0
all_healthy=false
while [[ $attempt -lt $max_attempts ]]; do
# Check if all 3 services are healthy
if docker-compose ps | grep -q "healthy.*healthy.*healthy"; then
all_healthy=true
break
fi
attempt=$((attempt + 1))
remaining=$((max_attempts - attempt))
log_info " Waiting... ($remaining attempts remaining)"
sleep 2
done
if [[ "$all_healthy" == true ]]; then
log_success " ✓ All services are healthy"
else
log_warn "Services did not become healthy within timeout. Checking logs..."
docker-compose logs --tail=50 || true
log_error "Service health check timeout. Review logs above."
fi
# ============================================================================
# STEP 10: Verify connectivity
# ============================================================================
log_info "Step 10/10: Verifying service connectivity..."
if curl -sf "http://localhost:${BACKEND_PORT}/health" &> /dev/null; then
log_success " ✓ Backend API responding at http://localhost:${BACKEND_PORT}/health"
else
log_warn " Backend health check failed; services may still be initializing"
fi
if curl -sf "http://localhost:${FRONTEND_PORT}/" &> /dev/null; then
log_success " ✓ Frontend responding at http://localhost:${FRONTEND_PORT}"
else
log_warn " Frontend check failed; container may still be initializing"
fi
# ============================================================================
# Summary
# ============================================================================
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${NC} Deployment completed successfully! ${GREEN}${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "Access points:"
echo " Frontend (HTTP): http://localhost:${FRONTEND_PORT}"
echo " Backend (HTTP): http://localhost:${BACKEND_PORT}"
echo " API Docs: http://localhost:${BACKEND_PORT}/docs"
echo " Frontend (HTTPS): https://localhost:${FRONTEND_SSL_PORT}"
echo " Backend (HTTPS): https://localhost:${BACKEND_SSL_PORT}"
echo ""
echo "Useful commands:"
echo " View logs: docker-compose logs -f"
echo " Stop services: docker-compose down"
echo " Restart: docker-compose restart"
echo " Status: docker-compose ps"
echo ""
echo "For deployment in production ($DEPLOYMENT_ENV):"
echo " • Review and update JWT_SECRET_KEY in inventory.env"
echo " • Configure firewall to expose only required ports"
echo " • Set up automated backups (see docs/DEPLOYMENT_QUICKSTART.md)"
echo " • Monitor logs regularly: docker-compose logs -f"
echo ""
log_success "Deployment ready!"

View File

@@ -1,73 +0,0 @@
#!/bin/bash
# export_prod.sh - Generates a clean production bundle for distribution
echo "📦 Preparing TFM aInventory Production Bundle..."
# Extract version from frontend/VERSION.json
VERSION=$(grep '"version"' frontend/VERSION.json | head -n 1 | awk -F '"' '{print $4}')
PROD_DIR="aInventory-PROD-v${VERSION}"
# Clean previous run if it exists
rm -rf "$PROD_DIR"
rm -f "${PROD_DIR}.zip"
mkdir -p "$PROD_DIR"
echo "📂 Copying application components (excluding dev artifacts)..."
# Core application
rsync -a --exclude 'node_modules' --exclude '.next' frontend/ "$PROD_DIR/frontend/"
rsync -a --exclude '__pycache__' --exclude '.pytest_cache' --exclude '.venv' --exclude 'tests' backend/ "$PROD_DIR/backend/"
# Orchestration, Config & Scripts
mkdir -p "$PROD_DIR/config" "$PROD_DIR/scripts"
cp docker-compose.yml "$PROD_DIR/"
rsync -a config/ "$PROD_DIR/config/"
rsync -a scripts/ "$PROD_DIR/scripts/"
cp start_server.sh "$PROD_DIR/"
cp run_standalone.sh "$PROD_DIR/"
cp install_service.sh "$PROD_DIR/"
cp inventory.service.template "$PROD_DIR/"
cp USER_GUIDE.md "$PROD_DIR/"
cp README.md "$PROD_DIR/INSTALLATION_GUIDE.md"
cp inventory.env "$PROD_DIR/"
cp deploy.sh "$PROD_DIR/"
cp .git_path "$PROD_DIR/" 2>/dev/null || true
cp frontend/VERSION.json "$PROD_DIR/"
cp frontend/VERSION.json "$PROD_DIR/frontend/"
# Setup persistent volume skeleton
mkdir -p "$PROD_DIR/data"
mkdir -p "$PROD_DIR/logs"
# Place a README in the root of the release
cat <<EOF > "$PROD_DIR/README.txt"
TFM aInventory - v${VERSION}
=============================
This is a clean production build, free of development or AI-agent constraints.
TO RUN VIA DOCKER (Recommended):
1. Install Docker Desktop or Docker Engine.
2. Run: docker-compose build
3. Run: docker-compose up -d
4. Access via https://<YOUR-IP>:8909 (Accept the internal security warning).
TO INSTALL AS A LINUX SYSTEM SERVICE (Optional):
1. sudo ./install_service.sh
2. sudo systemctl start inventory
TO RUN BARE-METAL (No Docker):
1. Install Python 3.12+ and Node.js 20+.
2. Ensure you have network access for npm installs.
3. Run: ./start_server.sh
4. Access via https://<YOUR-IP>:8909
Note: Database and Logs will persist in the /data and /logs directories.
EOF
echo "🗜️ Zipping the final bundle..."
zip -r -q "${PROD_DIR}.zip" "$PROD_DIR"
# Optional: cleanup the directory to leave just the zip
# rm -rf "$PROD_DIR"
echo "✅ SUCCESS: The clean production archive is ready: ${PROD_DIR}.zip"

View File

@@ -1,69 +0,0 @@
#!/bin/bash
# install_service.sh - Installs the inventory system as a standalone systemd service
if [[ $EUID -ne 0 ]]; then
echo "🚫 This script must be run as root (use sudo)"
exit 1
fi
echo "⚙️ Installing TFM aInventory as a Standalone Linux service..."
# Detect working directory
WORKING_DIR="$(pwd)"
# 1. Dependency Checks
echo "🔍 Checking dependencies..."
for cmd in python3 node npm; do
if ! command -v $cmd &> /dev/null; then
echo "$cmd not found! Please install it before proceeding."
exit 1
fi
done
# 2. Setup Backend Environment
echo "🐍 Setting up Python Virtual Environment..."
if [ ! -d ".venv" ]; then
python3 -m venv .venv
fi
source .venv/bin/activate
pip install -q --upgrade pip
pip install -q -r backend/requirements.txt
# 3. Setup Frontend Environment
echo "📦 Installing Node dependencies (this may take a minute)..."
cd frontend
npm install --quiet
echo "🏗️ Building Frontend for Production (Next.js build)..."
npm run build
cd ..
# 4. Create the final service file from template
TEMPLATE="inventory.service.template"
TARGET="/etc/systemd/system/inventory.service"
if [ ! -f "$TEMPLATE" ]; then
echo "❌ Template file $TEMPLATE not found in current directory!"
exit 1
fi
sed "s|__WORKING_DIR__|$WORKING_DIR|g" "$TEMPLATE" > "$TARGET"
echo "📝 Service file created at $TARGET"
# 5. Reload and enable
systemctl daemon-reload
systemctl enable inventory.service
# 6. Ensure scripts are executable
chmod +x run_standalone.sh
chmod +x start_server.sh
echo ""
echo "🚀 TFM aInventory Standalone service installed and enabled!"
echo " Commands:"
echo " 👉 sudo systemctl start inventory"
echo " 👉 sudo systemctl status inventory"
echo " 👉 sudo systemctl stop inventory"
echo ""
echo "Note: The service is currently ENABLED to start on boot, but NOT started."
echo " Run 'sudo systemctl start inventory' to launch it now."

View File

@@ -1,32 +0,0 @@
# =============================================================================
# TFM aInventory - Docker Compose Environment
# =============================================================================
# This file is used by Docker Compose for host-side port mapping.
# It should match the values in config/network_config.env
# =============================================================================
SERVER_IP=192.168.84.131
# Backend Ports
BACKEND_PORT=8916
BACKEND_SSL_PORT=8918
# Frontend Ports
FRONTEND_PORT=8917
FRONTEND_SSL_PORT=8919
# Security
JWT_SECRET_KEY=change_me_in_production
# AI
GEMINI_API_KEY=AIzaSyAajthWG2agpDLyJHY11U5qFLP4WnV5z0w
CLAUDE_API_KEY=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
# External Access (CORS)
# Comma-separated list of extra IPs or FQDNs allowed to connect (e.g. Tailscale, VPN)
EXTRA_ALLOWED_ORIGINS=100.78.182.0/24
# Data and Logging (for standalone deployment)
DATA_DIR=./data
LOGS_DIR=./logs
LOG_LEVEL=INFO

View File

@@ -1,37 +0,0 @@
# =============================================================================
# TFM aInventory — Master Environment Configuration (v1.10.15)
# =============================================================================
# 1. Copy this file to 'inventory.env'
# 2. Fill in your real values
# 3. 'inventory.env' is ignored by Git to protect your secrets.
#
# SYSTEM REQUIREMENTS (before running ./start_server.sh):
# - Node.js v20+ (required for frontend build)
# - Python 3.12+ with python3.12-venv package
# On Debian/Ubuntu: sudo apt install python3.12-venv
# =============================================================================
# --- Network & Identity ---
# Use your LAN IP (e.g., 192.168.1.10) for mobile access.
SERVER_IP=localhost
# --- AI API Keys ---
# Google Gemini API Key (Required for AI label OCR onboarding)
# Get one at: https://aistudio.google.com/
GEMINI_API_KEY=your_gemini_api_key_here
# --- Security ---
# JWT secret key — generate a strong random value for production:
# python3 -c "import secrets; print(secrets.token_urlsafe(64))"
JWT_SECRET_KEY=change_me_in_production
# --- Infrastructure Ports (Host-side mapping) ---
BACKEND_PORT=8916
BACKEND_SSL_PORT=8918
FRONTEND_PORT=8917
FRONTEND_SSL_PORT=8919
# --- External Access (CORS) ---
# Comma-separated list of extra IPs or FQDNs allowed (e.g. Tailscale, VPN)
# Example: EXTRA_ALLOWED_ORIGINS=100.78.182.27,inventory.my-domain.com
EXTRA_ALLOWED_ORIGINS=

View File

@@ -1,70 +0,0 @@
#!/bin/bash
# run_standalone.sh - Headless production launcher for TFM aInventory
# manages Backend, Frontend, and SSL Proxies in a single process group.
echo "🚀 Starting TFM aInventory in Standalone Mode..."
# Trapping termination signals to clean up child processes
trap "echo 'Stopping all processes...'; kill 0" SIGINT SIGTERM EXIT
# --- CONFIGURATION (Default values, overridden by network_configinventory.env) ---
BACKEND_PORT=8000
FRONTEND_PORT=3001
BACKEND_SSL_PORT=3002
FRONTEND_SSL_PORT=3003
SERVER_IP="localhost"
# Load Configuration from file if it exists
CONFIG_PATH="$(cd "$(dirname "$0")" && pwd)/inventory.env"
if [ -f "$CONFIG_PATH" ]; then
echo "⚙️ Loading network configuration from $CONFIG_PATH..."
export $(grep -v '^#' "$CONFIG_PATH" | xargs)
fi
# 1. Activate Environment
if [ -d ".venv" ]; then
source .venv/bin/activate
fi
# 1.5 Sync Network Config to Frontend
echo "🔌 Syncing network configuration to frontend..."
mkdir -p frontend/public
cat <<EOF > frontend/public/network.json
{
"SERVER_IP": "$SERVER_IP",
"BACKEND_PORT": $BACKEND_PORT,
"BACKEND_SSL_PORT": $BACKEND_SSL_PORT,
"FRONTEND_PORT": $FRONTEND_PORT,
"FRONTEND_SSL_PORT": $FRONTEND_SSL_PORT
}
EOF
# 2. Start Backend (No Reload for Prod)
echo "🔥 Starting Backend (Uvicorn)..."
python3 -m uvicorn backend.main:app --host 0.0.0.0 --port $BACKEND_PORT &
# 3. Start Frontend (Production Start)
echo "💻 Starting Frontend (Next.js Prod)..."
cd frontend
npm run start -- -p $FRONTEND_PORT &
cd ..
# 4. Start Proxies (via npx)
echo "🛡️ Starting HTTPS Proxies..."
npx local-ssl-proxy --source $BACKEND_SSL_PORT --target $BACKEND_PORT --hostname 0.0.0.0 > /dev/null 2>&1 &
npx local-ssl-proxy --source $FRONTEND_SSL_PORT --target $FRONTEND_PORT --hostname 0.0.0.0 > /dev/null 2>&1 &
# 5. Detection of IP for logs
if [[ "$OSTYPE" == "darwin"* ]]; then
LOCAL_IP=$(ipconfig getifaddr en0 || ipconfig getifaddr en1 || echo "localhost")
else
LOCAL_IP=$(hostname -I | awk '{print $1}')
fi
echo ""
echo "✅ TFM aInventory is active at https://$LOCAL_IP:$FRONTEND_SSL_PORT"
echo " Processes are running in background. Monitoring logs..."
echo ""
# Wait for children
wait