#!/bin/bash set -e # Exit on any error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Cleanup function cleanup() { echo -e "\n${YELLOW}Cleaning up...${NC}" docker compose down exit 0 } # Trap Ctrl+C trap cleanup SIGINT SIGTERM # Get the project root directory PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$PROJECT_ROOT" echo -e "${GREEN}๐Ÿš€ Starting p1ctos4ve backend setup...${NC}" # Step 1: Start Docker services echo -e "${YELLOW}๐Ÿ“ฆ Step 1: Starting Docker services (PostgreSQL, Redis, SeaweedFS)...${NC}" docker compose up -d # Get the actual network name from docker compose (it adds project prefix) NETWORK_NAME=$(docker network ls --format "{{.Name}}" | grep "p1ctos4ve-network" | head -n 1) if [ -z "$NETWORK_NAME" ]; then NETWORK_NAME=$(docker compose config 2>/dev/null | grep -A 2 "networks:" | grep "name:" | awk '{print $2}' | tr -d '"' | head -n 1) if [ -z "$NETWORK_NAME" ]; then NETWORK_NAME="p1ctos4ve-network" fi fi echo -e "${YELLOW}Using network: ${NETWORK_NAME}${NC}" # Wait for services to be healthy echo -e "${YELLOW}โณ Waiting for services to be ready...${NC}" # Wait for PostgreSQL echo -n "Waiting for PostgreSQL..." until docker exec p1ctos4ve-postgres pg_isready -U p1ctos4ve > /dev/null 2>&1; do echo -n "." sleep 1 done echo -e " ${GREEN}โœ“${NC}" # Wait for Redis echo -n "Waiting for Redis..." until docker exec p1ctos4ve-redis redis-cli ping > /dev/null 2>&1; do echo -n "." sleep 1 done echo -e " ${GREEN}โœ“${NC}" # Wait for SeaweedFS master echo -n "Waiting for SeaweedFS master..." for i in {1..30}; do if curl -s http://localhost:9333/cluster/status > /dev/null 2>&1; then break fi echo -n "." sleep 1 done echo -e " ${GREEN}โœ“${NC}" # Wait for SeaweedFS filer echo -n "Waiting for SeaweedFS filer..." for i in {1..30}; do if curl -s http://localhost:8888 > /dev/null 2>&1; then break fi echo -n "." sleep 1 done echo -e " ${GREEN}โœ“${NC}" # Wait for SeaweedFS S3 echo -n "Waiting for SeaweedFS S3..." for i in {1..30}; do if curl -s http://localhost:8333 > /dev/null 2>&1; then break fi echo -n "." sleep 1 done echo -e " ${GREEN}โœ“${NC}" # Wait a bit more for SeaweedFS to fully initialize sleep 2 # Create S3 bucket in SeaweedFS if it doesn't exist echo -e "${YELLOW}๐Ÿ“ฆ Creating S3 bucket in SeaweedFS...${NC}" BUCKET_NAME="p1ctos4ve" if ! curl -s -X PUT "http://localhost:8333/${BUCKET_NAME}" > /dev/null 2>&1; then curl -X PUT "http://localhost:8888/buckets/${BUCKET_NAME}" > /dev/null 2>&1 || true fi echo -e "${GREEN}โœ“ Bucket ready${NC}" # Step 2: Build backend echo -e "${YELLOW}๐Ÿ”จ Step 2: Building backend...${NC}" cd "$PROJECT_ROOT" docker build -t p1ctos4ve-backend:latest -f apps/backend/Dockerfile . # Step 3: Run migrations echo -e "${YELLOW}๐Ÿ—„๏ธ Step 3: Running database migrations...${NC}" docker run --rm \ --network "${NETWORK_NAME}" \ -e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \ -e REDIS_URL="redis://redis:6379" \ -e S3_ENDPOINT="http://seaweedfs-s3:8333" \ -e S3_REGION="us-east-1" \ -e S3_BUCKET="${BUCKET_NAME}" \ -e S3_ACCESS_KEY_ID="any" \ -e S3_SECRET_ACCESS_KEY="any" \ -e S3_FORCE_PATH_STYLE="true" \ -e BETTER_AUTH_SECRET="$(openssl rand-hex 32 2>/dev/null || openssl rand -hex 32)" \ -e BETTER_AUTH_URL="http://localhost:3000" \ -e BASE_URL="http://localhost:3000" \ -e NODE_ENV="production" \ -e PORT="3000" \ p1ctos4ve-backend:latest \ bun run db:migrate # Step 4: Run unit tests echo -e "${YELLOW}๐Ÿงช Step 4: Running unit tests...${NC}" docker run --rm \ --network "${NETWORK_NAME}" \ -e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \ -e REDIS_URL="redis://redis:6379" \ -e S3_ENDPOINT="http://seaweedfs-s3:8333" \ -e S3_REGION="us-east-1" \ -e S3_BUCKET="${BUCKET_NAME}" \ -e S3_ACCESS_KEY_ID="any" \ -e S3_SECRET_ACCESS_KEY="any" \ -e S3_FORCE_PATH_STYLE="true" \ -e BETTER_AUTH_SECRET="$(openssl rand-hex 32 2>/dev/null || openssl rand -hex 32)" \ -e BETTER_AUTH_URL="http://localhost:3000" \ -e BASE_URL="http://localhost:3000" \ -e NODE_ENV="test" \ -e PORT="3000" \ p1ctos4ve-backend:latest \ bun test src/tests/unit/ UNIT_EXIT_CODE=$? if [ $UNIT_EXIT_CODE -eq 0 ]; then echo -e "${GREEN}โœ“ Unit tests passed${NC}" else echo -e "${RED}โœ— Unit tests failed${NC}" exit 1 fi # Step 5: Run integration tests echo -e "${YELLOW}๐Ÿ”— Step 5: Running integration tests...${NC}" echo -e "${YELLOW}Starting backend server for e2e tests...${NC}" BACKEND_CONTAINER=$(docker run -d \ --name p1ctos4ve-backend-test \ --network "${NETWORK_NAME}" \ -p 3000:3000 \ -e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \ -e REDIS_URL="redis://redis:6379" \ -e S3_ENDPOINT="http://seaweedfs-s3:8333" \ -e S3_REGION="us-east-1" \ -e S3_BUCKET="${BUCKET_NAME}" \ -e S3_ACCESS_KEY_ID="any" \ -e S3_SECRET_ACCESS_KEY="any" \ -e S3_FORCE_PATH_STYLE="true" \ -e BETTER_AUTH_SECRET="$(openssl rand-hex 32 2>/dev/null || openssl rand -hex 32)" \ -e BETTER_AUTH_URL="http://localhost:3000" \ -e BASE_URL="http://localhost:3000" \ -e NODE_ENV="test" \ -e PORT="3000" \ p1ctos4ve-backend:latest) # Wait for server to be ready echo -n "Waiting for backend server to start..." for i in {1..30}; do if curl -s http://localhost:3000 > /dev/null 2>&1; then break fi echo -n "." sleep 1 done echo -e " ${GREEN}โœ“${NC}" # Try e2e tests inside backend container docker exec p1ctos4ve-backend-test sh -c "bun test --preload ./src/tests/setup.ts src/tests/e2e/" || \ docker run --rm \ --network "${NETWORK_NAME}" \ -e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \ -e REDIS_URL="redis://redis:6379" \ -e S3_ENDPOINT="http://seaweedfs-s3:8333" \ -e S3_REGION="us-east-1" \ -e S3_BUCKET="${BUCKET_NAME}" \ -e S3_ACCESS_KEY_ID="any" \ -e S3_SECRET_ACCESS_KEY="any" \ -e S3_FORCE_PATH_STYLE="true" \ -e BETTER_AUTH_SECRET="$(openssl rand-hex 32 2>/dev/null || openssl rand -hex 32)" \ -e BETTER_AUTH_URL="http://p1ctos4ve-backend-test:3000" \ -e BASE_URL="http://p1ctos4ve-backend-test:3000" \ -e NODE_ENV="test" \ -e PORT="3000" \ p1ctos4ve-backend:latest \ sh -c "find src/tests/e2e -name '*.test.ts' -exec sed -i 's|http://localhost:3000|http://p1ctos4ve-backend-test:3000|g' {} \; && bun test --preload ./src/tests/setup.ts src/tests/e2e/" TEST_EXIT_CODE=$? echo -e "${YELLOW}Stopping test backend server...${NC}" docker stop p1ctos4ve-backend-test > /dev/null 2>&1 || true docker rm p1ctos4ve-backend-test > /dev/null 2>&1 || true if [ $TEST_EXIT_CODE -eq 0 ]; then echo -e "${GREEN}โœ“ Integration tests passed${NC}" else echo -e "${RED}โœ— Integration tests failed${NC}" exit 1 fi # Step 6: Start the application echo -e "${YELLOW}๐Ÿš€ Step 6: Starting the application...${NC}" echo -e "${GREEN}Application will be available at http://localhost:3000${NC}" echo -e "${YELLOW}Press Ctrl+C to stop${NC}" docker run --rm \ --network "${NETWORK_NAME}" \ -p 3000:3000 \ -e DATABASE_URL="postgresql://p1ctos4ve:p1ctos4ve_password@postgres:5432/p1ctos4ve" \ -e REDIS_URL="redis://redis:6379" \ -e S3_ENDPOINT="http://seaweedfs-s3:8333" \ -e S3_REGION="us-east-1" \ -e S3_BUCKET="${BUCKET_NAME}" \ -e S3_ACCESS_KEY_ID="any" \ -e S3_SECRET_ACCESS_KEY="any" \ -e S3_FORCE_PATH_STYLE="true" \ -e BETTER_AUTH_SECRET="$(openssl rand-hex 32 2>/dev/null || openssl rand -hex 32)" \ -e BETTER_AUTH_URL="http://localhost:3000" \ -e BASE_URL="http://localhost:3000" \ -e NODE_ENV="production" \ -e PORT="3000" \ p1ctos4ve-backend:latest