chore: Add script to start all servers and update package.json
Some checks failed
CI / skip-ci-check (push) Successful in 1m27s
CI / skip-ci-check (pull_request) Successful in 1m26s
CI / python-lint (push) Has been cancelled
CI / test-backend (push) Has been cancelled
CI / build (push) Has been cancelled
CI / secret-scanning (push) Has been cancelled
CI / dependency-scan (push) Has been cancelled
CI / sast-scan (push) Has been cancelled
CI / workflow-summary (push) Has been cancelled
CI / lint-and-type-check (push) Has been cancelled
CI / lint-and-type-check (pull_request) Successful in 2m6s
CI / python-lint (pull_request) Successful in 1m52s
CI / test-backend (pull_request) Successful in 2m43s
CI / build (pull_request) Successful in 2m23s
CI / secret-scanning (pull_request) Successful in 1m40s
CI / dependency-scan (pull_request) Successful in 1m34s
CI / sast-scan (pull_request) Successful in 2m45s
CI / workflow-summary (pull_request) Successful in 1m26s
Some checks failed
CI / skip-ci-check (push) Successful in 1m27s
CI / skip-ci-check (pull_request) Successful in 1m26s
CI / python-lint (push) Has been cancelled
CI / test-backend (push) Has been cancelled
CI / build (push) Has been cancelled
CI / secret-scanning (push) Has been cancelled
CI / dependency-scan (push) Has been cancelled
CI / sast-scan (push) Has been cancelled
CI / workflow-summary (push) Has been cancelled
CI / lint-and-type-check (push) Has been cancelled
CI / lint-and-type-check (pull_request) Successful in 2m6s
CI / python-lint (pull_request) Successful in 1m52s
CI / test-backend (pull_request) Successful in 2m43s
CI / build (pull_request) Successful in 2m23s
CI / secret-scanning (pull_request) Successful in 1m40s
CI / dependency-scan (pull_request) Successful in 1m34s
CI / sast-scan (pull_request) Successful in 2m45s
CI / workflow-summary (pull_request) Successful in 1m26s
This commit introduces a new script, `start_all.sh`, to facilitate the simultaneous startup of the backend, admin frontend, and viewer frontend servers. Additionally, the `package.json` file is updated to include a new command, `dev:all`, for executing this script. These changes enhance the development workflow by streamlining the server startup process.
This commit is contained in:
parent
570c2cba97
commit
2e735f3b5a
@ -196,7 +196,170 @@ jobs:
|
||||
run: |
|
||||
export PYTHONPATH=$(pwd)
|
||||
python -c "from backend.db.models import Base; from backend.db.session import engine; Base.metadata.create_all(bind=engine)"
|
||||
python -c "from backend.worker import setup_auth_database_tables; setup_auth_database_tables()"
|
||||
python << 'EOF'
|
||||
# Initialize auth database schema without importing worker (avoids DeepFace/TensorFlow imports)
|
||||
from backend.db.session import auth_engine
|
||||
from sqlalchemy import text
|
||||
|
||||
if auth_engine is None:
|
||||
print("⚠️ Auth database not configured, skipping auth schema initialization")
|
||||
else:
|
||||
try:
|
||||
print("🗃️ Setting up auth database tables...")
|
||||
with auth_engine.connect() as conn:
|
||||
# Create users table
|
||||
conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
is_admin BOOLEAN DEFAULT FALSE,
|
||||
has_write_access BOOLEAN DEFAULT FALSE,
|
||||
email_verified BOOLEAN DEFAULT FALSE,
|
||||
email_confirmation_token VARCHAR(255) UNIQUE,
|
||||
email_confirmation_token_expiry TIMESTAMP,
|
||||
password_reset_token VARCHAR(255) UNIQUE,
|
||||
password_reset_token_expiry TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
"""))
|
||||
|
||||
# Add missing columns if table already exists
|
||||
for col_def in [
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS is_admin BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS has_write_access BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS email_verified BOOLEAN DEFAULT FALSE",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS email_confirmation_token VARCHAR(255)",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS email_confirmation_token_expiry TIMESTAMP",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS password_reset_token VARCHAR(255)",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS password_reset_token_expiry TIMESTAMP",
|
||||
"ALTER TABLE users ADD COLUMN IF NOT EXISTS is_active BOOLEAN DEFAULT TRUE",
|
||||
]:
|
||||
try:
|
||||
conn.execute(text(col_def))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Create unique indexes
|
||||
conn.execute(text("""
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS users_email_confirmation_token_key
|
||||
ON users(email_confirmation_token)
|
||||
WHERE email_confirmation_token IS NOT NULL;
|
||||
"""))
|
||||
conn.execute(text("""
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS users_password_reset_token_key
|
||||
ON users(password_reset_token)
|
||||
WHERE password_reset_token IS NOT NULL;
|
||||
"""))
|
||||
|
||||
# Create pending_identifications table
|
||||
conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS pending_identifications (
|
||||
id SERIAL PRIMARY KEY,
|
||||
face_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
first_name VARCHAR(255) NOT NULL,
|
||||
last_name VARCHAR(255) NOT NULL,
|
||||
middle_name VARCHAR(255),
|
||||
maiden_name VARCHAR(255),
|
||||
date_of_birth DATE,
|
||||
status VARCHAR(50) DEFAULT 'pending',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
"""))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_identifications_face_id ON pending_identifications(face_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_identifications_user_id ON pending_identifications(user_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_identifications_status ON pending_identifications(status);"))
|
||||
|
||||
# Create pending_photos table
|
||||
conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS pending_photos (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
file_path VARCHAR(512) NOT NULL,
|
||||
file_size INTEGER NOT NULL,
|
||||
mime_type VARCHAR(100) NOT NULL,
|
||||
status VARCHAR(50) DEFAULT 'pending',
|
||||
submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
reviewed_at TIMESTAMP,
|
||||
reviewed_by INTEGER,
|
||||
rejection_reason TEXT,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
"""))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_photos_user_id ON pending_photos(user_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_photos_status ON pending_photos(status);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_photos_submitted_at ON pending_photos(submitted_at);"))
|
||||
|
||||
# Create inappropriate_photo_reports table
|
||||
conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS inappropriate_photo_reports (
|
||||
id SERIAL PRIMARY KEY,
|
||||
photo_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
status VARCHAR(50) DEFAULT 'pending',
|
||||
reported_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
reviewed_at TIMESTAMP,
|
||||
reviewed_by INTEGER,
|
||||
review_notes TEXT,
|
||||
report_comment TEXT,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
UNIQUE(photo_id, user_id)
|
||||
);
|
||||
"""))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_inappropriate_photo_reports_photo_id ON inappropriate_photo_reports(photo_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_inappropriate_photo_reports_user_id ON inappropriate_photo_reports(user_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_inappropriate_photo_reports_status ON inappropriate_photo_reports(status);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_inappropriate_photo_reports_reported_at ON inappropriate_photo_reports(reported_at);"))
|
||||
|
||||
# Create pending_linkages table
|
||||
conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS pending_linkages (
|
||||
id SERIAL PRIMARY KEY,
|
||||
photo_id INTEGER NOT NULL,
|
||||
tag_id INTEGER,
|
||||
tag_name VARCHAR(255),
|
||||
user_id INTEGER NOT NULL,
|
||||
status VARCHAR(50) DEFAULT 'pending',
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
"""))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_linkages_photo_id ON pending_linkages(photo_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_linkages_tag_id ON pending_linkages(tag_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_linkages_user_id ON pending_linkages(user_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_pending_linkages_status ON pending_linkages(status);"))
|
||||
|
||||
# Create photo_favorites table
|
||||
conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS photo_favorites (
|
||||
id SERIAL PRIMARY KEY,
|
||||
photo_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
favorited_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
UNIQUE(photo_id, user_id)
|
||||
);
|
||||
"""))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_photo_favorites_photo_id ON photo_favorites(photo_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_photo_favorites_user_id ON photo_favorites(user_id);"))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_photo_favorites_favorited_at ON photo_favorites(favorited_at);"))
|
||||
|
||||
conn.commit()
|
||||
|
||||
print("✅ Auth database tables created/verified successfully")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to create auth database tables: {e}")
|
||||
EOF
|
||||
echo "✅ Database schemas initialized (main and auth)"
|
||||
|
||||
- name: Run backend tests
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
"dev:admin": "npm run dev --prefix admin-frontend",
|
||||
"dev:viewer": "npm run dev --prefix viewer-frontend",
|
||||
"dev:backend": "source venv/bin/activate && export PYTHONPATH=$(pwd) && uvicorn backend.app:app --host 127.0.0.1 --port 8000",
|
||||
"dev:all": "./start_all.sh",
|
||||
"build:admin": "npm run build --prefix admin-frontend",
|
||||
"build:viewer": "npm run build --prefix viewer-frontend",
|
||||
"build:all": "npm run build:admin && npm run build:viewer",
|
||||
|
||||
87
start_all.sh
Executable file
87
start_all.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
# Start all three servers: backend, admin-frontend, and viewer-frontend
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}🚀 Starting all PunimTag servers...${NC}"
|
||||
echo ""
|
||||
|
||||
# Function to cleanup on exit
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}Shutting down all servers...${NC}"
|
||||
kill $BACKEND_PID 2>/dev/null || true
|
||||
kill $ADMIN_PID 2>/dev/null || true
|
||||
kill $VIEWER_PID 2>/dev/null || true
|
||||
exit
|
||||
}
|
||||
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
# Start backend
|
||||
echo -e "${GREEN}📦 Starting backend server...${NC}"
|
||||
# Use explicit Python path to avoid Cursor interception
|
||||
PYTHON_BIN="/usr/bin/python3"
|
||||
if [ ! -f "$PYTHON_BIN" ]; then
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
PYTHON_BIN="$(which python3)"
|
||||
elif command -v python >/dev/null 2>&1; then
|
||||
PYTHON_BIN="$(which python)"
|
||||
else
|
||||
echo -e "${YELLOW}❌ Python3 not found${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "venv" ]; then
|
||||
source venv/bin/activate
|
||||
fi
|
||||
export PYTHONPATH="$(pwd)"
|
||||
"$PYTHON_BIN" -m uvicorn backend.app:app --host 127.0.0.1 --port 8000 --reload > /tmp/backend.log 2>&1 &
|
||||
BACKEND_PID=$!
|
||||
|
||||
# Wait a moment for backend to start
|
||||
sleep 2
|
||||
|
||||
# Start admin-frontend
|
||||
echo -e "${GREEN}📦 Starting admin-frontend...${NC}"
|
||||
cd admin-frontend
|
||||
npm run dev > /tmp/admin-frontend.log 2>&1 &
|
||||
ADMIN_PID=$!
|
||||
cd ..
|
||||
|
||||
# Start viewer-frontend
|
||||
echo -e "${GREEN}📦 Starting viewer-frontend...${NC}"
|
||||
cd viewer-frontend
|
||||
npm run dev > /tmp/viewer-frontend.log 2>&1 &
|
||||
VIEWER_PID=$!
|
||||
cd ..
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ All servers started!${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}📍 Server URLs:${NC}"
|
||||
echo -e " Backend API: ${GREEN}http://127.0.0.1:8000${NC}"
|
||||
echo -e " API Docs: ${GREEN}http://127.0.0.1:8000/docs${NC}"
|
||||
echo -e " Admin Frontend: ${GREEN}http://127.0.0.1:3000${NC}"
|
||||
echo -e " Viewer Frontend: ${GREEN}http://127.0.0.1:3001${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}📋 Logs:${NC}"
|
||||
echo -e " Backend: ${BLUE}/tmp/backend.log${NC}"
|
||||
echo -e " Admin: ${BLUE}/tmp/admin-frontend.log${NC}"
|
||||
echo -e " Viewer: ${BLUE}/tmp/viewer-frontend.log${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Press Ctrl+C to stop all servers${NC}"
|
||||
echo ""
|
||||
|
||||
# Wait for all processes
|
||||
wait
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user