235 lines
9.6 KiB
Bash
Executable File
235 lines
9.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
# Nexus Autoparts — Instance Setup Script
|
|
# Target: Raspberry Pi OS / Debian / Ubuntu
|
|
# Usage: sudo bash setup_instance.sh "Refaccionaria El Toro" "refac-eltoro"
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
|
|
set -e
|
|
|
|
BUSINESS_NAME="${1:-Refaccionaria Demo}"
|
|
INSTANCE_ID="${2:-refac-$(date +%s)}"
|
|
DB_PASSWORD="nexus_autoparts_2026"
|
|
DB_USER="nexus"
|
|
MASTER_DB="nexus_autoparts"
|
|
OWNER_PIN="${3:-1234}"
|
|
INSTALL_DIR="/home/Autopartes"
|
|
|
|
echo "╔══════════════════════════════════════════════╗"
|
|
echo "║ Nexus Autoparts — Instance Setup ║"
|
|
echo "║ Business: $BUSINESS_NAME"
|
|
echo "║ ID: $INSTANCE_ID"
|
|
echo "╚══════════════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
# ─── 1. System deps ───────────────────────────────────────────────────
|
|
|
|
echo "→ Installing system dependencies..."
|
|
apt-get update -qq
|
|
apt-get install -y -qq \
|
|
postgresql postgresql-client \
|
|
python3 python3-pip python3-venv python3-dev \
|
|
nodejs npm \
|
|
ffmpeg espeak-ng \
|
|
git curl wget \
|
|
libpq-dev gcc \
|
|
2>/dev/null
|
|
|
|
echo " ✓ System deps installed"
|
|
|
|
# ─── 2. Python deps ──────────────────────────────────────────────────
|
|
|
|
echo "→ Installing Python packages..."
|
|
# Try system packages first (faster, no compilation needed)
|
|
apt-get install -y -qq \
|
|
python3-flask python3-psycopg2 python3-sqlalchemy \
|
|
python3-jwt python3-bcrypt python3-requests \
|
|
gunicorn 2>/dev/null || true
|
|
|
|
# Install remaining packages with --break-system-packages (safe for a dedicated server)
|
|
pip3 install --break-system-packages --quiet \
|
|
flask psycopg2-binary sqlalchemy pyjwt bcrypt requests \
|
|
gunicorn faster-whisper \
|
|
2>/dev/null || \
|
|
pip3 install --break-system-packages --force-reinstall --quiet \
|
|
flask psycopg2-binary sqlalchemy PyJWT bcrypt requests \
|
|
gunicorn \
|
|
2>/dev/null || true
|
|
|
|
echo " ✓ Python packages installed"
|
|
|
|
# ─── 3. Node.js deps (WhatsApp bridge) ───────────────────────────────
|
|
|
|
if [ -d "/opt/whatsapp-bridge" ]; then
|
|
echo "→ Installing WhatsApp bridge deps..."
|
|
cd /opt/whatsapp-bridge && npm install --silent 2>/dev/null
|
|
echo " ✓ WhatsApp bridge ready"
|
|
else
|
|
echo " ⚠ WhatsApp bridge not found at /opt/whatsapp-bridge — skipping"
|
|
fi
|
|
|
|
# ─── 4. PostgreSQL setup ─────────────────────────────────────────────
|
|
|
|
echo "→ Configuring PostgreSQL..."
|
|
systemctl enable postgresql
|
|
systemctl start postgresql
|
|
|
|
# Create user if doesn't exist
|
|
su - postgres -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'\" | grep -q 1" \
|
|
|| su - postgres -c "createuser -s $DB_USER"
|
|
|
|
# Set password
|
|
su - postgres -c "psql -c \"ALTER USER $DB_USER WITH PASSWORD '$DB_PASSWORD';\""
|
|
|
|
# Create master DB if doesn't exist
|
|
su - postgres -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='$MASTER_DB'\" | grep -q 1" \
|
|
|| su - postgres -c "createdb -O $DB_USER $MASTER_DB"
|
|
|
|
echo " ✓ PostgreSQL configured"
|
|
|
|
# ─── 5. Import schema (master + tenant template) ─────────────────────
|
|
|
|
echo "→ Importing database schema..."
|
|
if [ -f "$INSTALL_DIR/vehicle_database/sql/schema.sql" ]; then
|
|
PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d $MASTER_DB \
|
|
-f "$INSTALL_DIR/vehicle_database/sql/schema.sql" 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -f "$INSTALL_DIR/sql/marketplace_schema.sql" ]; then
|
|
PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d $MASTER_DB \
|
|
-f "$INSTALL_DIR/sql/marketplace_schema.sql" 2>/dev/null || true
|
|
fi
|
|
|
|
echo " ✓ Schema imported"
|
|
|
|
# ─── 6. Create tenant for this refaccionaria ─────────────────────────
|
|
|
|
echo "→ Creating tenant database for '$BUSINESS_NAME'..."
|
|
TENANT_DB="tenant_${INSTANCE_ID//-/_}"
|
|
|
|
su - postgres -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='$TENANT_DB'\" | grep -q 1" && {
|
|
echo " ⚠ Tenant DB '$TENANT_DB' already exists — skipping creation"
|
|
} || {
|
|
# Create from template if available, else create fresh
|
|
if su - postgres -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='tenant_template'\" | grep -q 1"; then
|
|
su - postgres -c "createdb -O $DB_USER -T tenant_template $TENANT_DB"
|
|
echo " ✓ Created from tenant_template"
|
|
else
|
|
su - postgres -c "createdb -O $DB_USER $TENANT_DB"
|
|
echo " ✓ Created fresh (no template available)"
|
|
fi
|
|
}
|
|
|
|
# Apply marketplace migration to tenant
|
|
if [ -f "$INSTALL_DIR/sql/marketplace_tenant_users.sql" ]; then
|
|
PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d "$TENANT_DB" \
|
|
-f "$INSTALL_DIR/sql/marketplace_tenant_users.sql" 2>/dev/null || true
|
|
fi
|
|
|
|
# Apply plate_vehicles migration
|
|
if [ -f "$INSTALL_DIR/pos/migrations/v1.7_plates.sql" ]; then
|
|
PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d "$TENANT_DB" \
|
|
-f "$INSTALL_DIR/pos/migrations/v1.7_plates.sql" 2>/dev/null || true
|
|
fi
|
|
|
|
echo " ✓ Tenant DB ready: $TENANT_DB"
|
|
|
|
# ─── 7. Register tenant in master ────────────────────────────────────
|
|
|
|
echo "→ Registering tenant in master DB..."
|
|
PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d $MASTER_DB -c "
|
|
INSERT INTO tenants (name, db_name, is_active, subdomain)
|
|
VALUES ('$BUSINESS_NAME', '$TENANT_DB', true, '$INSTANCE_ID')
|
|
ON CONFLICT DO NOTHING;
|
|
" 2>/dev/null || true
|
|
|
|
# Get tenant ID
|
|
TENANT_ID=$(PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d $MASTER_DB -t -c "
|
|
SELECT id FROM tenants WHERE db_name = '$TENANT_DB' LIMIT 1;
|
|
" 2>/dev/null | tr -d ' ')
|
|
|
|
echo " ✓ Tenant registered: ID=$TENANT_ID"
|
|
|
|
# ─── 8. Create owner employee ────────────────────────────────────────
|
|
|
|
echo "→ Creating owner employee..."
|
|
PIN_HASH=$(python3 -c "import bcrypt; print(bcrypt.hashpw('$OWNER_PIN'.encode(), bcrypt.gensalt()).decode())")
|
|
|
|
PGPASSWORD=$DB_PASSWORD psql -U $DB_USER -h localhost -d "$TENANT_DB" -c "
|
|
INSERT INTO employees (name, role, pin, password_hash, is_active, marketplace_role)
|
|
VALUES ('Administrador', 'owner', '$PIN_HASH', '$PIN_HASH', true, 'buyer')
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
INSERT INTO branches (name, address, phone, is_active)
|
|
VALUES ('Principal', '', '', true)
|
|
ON CONFLICT DO NOTHING;
|
|
" 2>/dev/null || true
|
|
|
|
echo " ✓ Owner employee created (PIN: $OWNER_PIN)"
|
|
|
|
# ─── 9. Configure peers.json ─────────────────────────────────────────
|
|
|
|
echo "→ Configuring peers.json..."
|
|
# Get this machine's IP
|
|
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
|
|
|
cat > "$INSTALL_DIR/pos/peers.json" << EOJSON
|
|
{
|
|
"instance_name": "$BUSINESS_NAME",
|
|
"instance_id": "$INSTANCE_ID",
|
|
"tenant_id": $TENANT_ID,
|
|
"peers": [],
|
|
"peer_timeout_seconds": 3,
|
|
"notes": "Add peer instances here: {\"name\": \"Refac B\", \"url\": \"http://192.168.X.Y:5001\", \"enabled\": true}"
|
|
}
|
|
EOJSON
|
|
|
|
echo " ✓ peers.json configured (local IP: $LOCAL_IP)"
|
|
|
|
# ─── 10. Create Gunicorn systemd service ─────────────────────────────
|
|
|
|
echo "→ Setting up Gunicorn service..."
|
|
cat > /etc/systemd/system/nexus-pos.service << EOSERVICE
|
|
[Unit]
|
|
Description=Nexus Autoparts POS
|
|
After=network.target postgresql.service
|
|
|
|
[Service]
|
|
User=root
|
|
WorkingDirectory=$INSTALL_DIR/pos
|
|
Environment="PATH=/usr/local/bin:/usr/bin"
|
|
ExecStart=/usr/local/bin/gunicorn -w 2 -b 0.0.0.0:5001 --timeout 120 app:app
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOSERVICE
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable nexus-pos
|
|
# Don't start yet — let user verify config first
|
|
|
|
echo " ✓ Gunicorn service created (nexus-pos)"
|
|
|
|
# ─── Done ─────────────────────────────────────────────────────────────
|
|
|
|
echo ""
|
|
echo "╔══════════════════════════════════════════════╗"
|
|
echo "║ SETUP COMPLETE ║"
|
|
echo "╚══════════════════════════════════════════════╝"
|
|
echo ""
|
|
echo "Instance: $BUSINESS_NAME"
|
|
echo "Tenant DB: $TENANT_DB (ID: $TENANT_ID)"
|
|
echo "Owner PIN: $OWNER_PIN"
|
|
echo "Local IP: $LOCAL_IP"
|
|
echo ""
|
|
echo "To start the POS:"
|
|
echo " systemctl start nexus-pos"
|
|
echo " # or manually: cd $INSTALL_DIR/pos && gunicorn -w 2 -b 0.0.0.0:5001 app:app"
|
|
echo ""
|
|
echo "To add peers, edit: $INSTALL_DIR/pos/peers.json"
|
|
echo "To import inventory: python3 $INSTALL_DIR/scripts/import_inventory.py --tenant=$TENANT_ID --csv=inventario.csv"
|
|
echo ""
|
|
echo "Access: http://$LOCAL_IP:5001/pos/login"
|