feat: Add development scripts for environment check and service management
- check-env.sh: Validates Python 3.10+, Node.js, Docker, venv, .env, ports - start-dev.sh: Starts MinIO, backend, frontend with health checks - stop-dev.sh: Gracefully stops all services Scripts are placed in project root for easy access. Supports --help flag and colored output. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -34,3 +34,7 @@ server.log
|
|||||||
node_modules/
|
node_modules/
|
||||||
frontend/dist/
|
frontend/dist/
|
||||||
frontend/.vite/
|
frontend/.vite/
|
||||||
|
|
||||||
|
# Development scripts
|
||||||
|
.pids/
|
||||||
|
logs/
|
||||||
|
|||||||
258
check-env.sh
Executable file
258
check-env.sh
Executable file
@@ -0,0 +1,258 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================================================
|
||||||
|
# Environment Check Script for Task Reporter
|
||||||
|
# Validates all prerequisites required to run the development environment
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Note: Not using set -e because we handle errors explicitly with ERRORS counter
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Script directory (scripts are in project root)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$SCRIPT_DIR"
|
||||||
|
|
||||||
|
# Track overall status
|
||||||
|
ERRORS=0
|
||||||
|
WARNINGS=0
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
print_header() {
|
||||||
|
echo -e "\n${BLUE}=== $1 ===${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_ok() {
|
||||||
|
echo -e "${GREEN}[OK]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
((ERRORS++))
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
((WARNINGS++))
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
show_help() {
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo ""
|
||||||
|
echo "Validates the development environment for Task Reporter."
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " -h, --help Show this help message"
|
||||||
|
echo " -q, --quiet Only show errors and warnings"
|
||||||
|
echo ""
|
||||||
|
echo "Checks performed:"
|
||||||
|
echo " - Python version (3.10+)"
|
||||||
|
echo " - Node.js and npm"
|
||||||
|
echo " - Docker availability"
|
||||||
|
echo " - Virtual environment (venv/)"
|
||||||
|
echo " - Environment file (.env)"
|
||||||
|
echo " - Port availability (8000, 3000, 9000, 9001)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
QUIET=false
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-q|--quiet)
|
||||||
|
QUIET=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
echo -e "${BLUE} Task Reporter - Environment Check${NC}"
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Check Python version
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Python"
|
||||||
|
|
||||||
|
if command -v python3 &> /dev/null; then
|
||||||
|
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
||||||
|
PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
|
||||||
|
PYTHON_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
|
||||||
|
|
||||||
|
if [[ "$PYTHON_MAJOR" -ge 3 ]] && [[ "$PYTHON_MINOR" -ge 10 ]]; then
|
||||||
|
print_ok "Python $PYTHON_VERSION detected"
|
||||||
|
else
|
||||||
|
print_error "Python 3.10+ required, found $PYTHON_VERSION"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_error "Python3 not found. Please install Python 3.10+"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Check Node.js and npm
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Node.js"
|
||||||
|
|
||||||
|
if command -v node &> /dev/null; then
|
||||||
|
NODE_VERSION=$(node --version)
|
||||||
|
print_ok "Node.js $NODE_VERSION detected"
|
||||||
|
else
|
||||||
|
print_error "Node.js not found. Please install Node.js 18+"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v npm &> /dev/null; then
|
||||||
|
NPM_VERSION=$(npm --version)
|
||||||
|
print_ok "npm $NPM_VERSION detected"
|
||||||
|
else
|
||||||
|
print_error "npm not found. Please install npm"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Check Docker
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Docker"
|
||||||
|
|
||||||
|
if command -v docker &> /dev/null; then
|
||||||
|
DOCKER_VERSION=$(docker --version | cut -d' ' -f3 | tr -d ',')
|
||||||
|
print_ok "Docker $DOCKER_VERSION detected"
|
||||||
|
|
||||||
|
# Check if Docker daemon is running
|
||||||
|
if docker info &> /dev/null; then
|
||||||
|
print_ok "Docker daemon is running"
|
||||||
|
else
|
||||||
|
print_error "Docker daemon is not running. Please start Docker"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_error "Docker not found. Please install Docker"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v docker-compose &> /dev/null; then
|
||||||
|
COMPOSE_VERSION=$(docker-compose --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||||
|
print_ok "docker-compose $COMPOSE_VERSION detected"
|
||||||
|
elif docker compose version &> /dev/null; then
|
||||||
|
COMPOSE_VERSION=$(docker compose version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||||
|
print_ok "docker compose (plugin) $COMPOSE_VERSION detected"
|
||||||
|
else
|
||||||
|
print_error "docker-compose not found. Please install docker-compose"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Check Virtual Environment
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Virtual Environment"
|
||||||
|
|
||||||
|
if [[ -d "$PROJECT_ROOT/venv" ]]; then
|
||||||
|
print_ok "Virtual environment found at venv/"
|
||||||
|
|
||||||
|
# Check if it has required packages
|
||||||
|
if [[ -f "$PROJECT_ROOT/venv/bin/activate" ]]; then
|
||||||
|
print_ok "venv/bin/activate exists"
|
||||||
|
else
|
||||||
|
print_warn "venv/bin/activate not found - venv may be corrupted"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_error "Virtual environment not found"
|
||||||
|
print_info "Create it with: python3 -m venv venv"
|
||||||
|
print_info "Then activate: source venv/bin/activate"
|
||||||
|
print_info "And install: pip install -r requirements.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Check Environment File
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Environment File"
|
||||||
|
|
||||||
|
if [[ -f "$PROJECT_ROOT/.env" ]]; then
|
||||||
|
print_ok ".env file exists"
|
||||||
|
|
||||||
|
# Check for critical variables (use || true to prevent set -e from exiting)
|
||||||
|
if grep -q "^FERNET_KEY=.\+" "$PROJECT_ROOT/.env" 2>/dev/null; then
|
||||||
|
print_ok "FERNET_KEY is set"
|
||||||
|
else
|
||||||
|
print_warn "FERNET_KEY appears to be empty"
|
||||||
|
print_info "Generate with: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "^DATABASE_URL=" "$PROJECT_ROOT/.env" 2>/dev/null; then
|
||||||
|
print_ok "DATABASE_URL is set"
|
||||||
|
else
|
||||||
|
print_warn "DATABASE_URL is not set"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "^MINIO_ENDPOINT=" "$PROJECT_ROOT/.env" 2>/dev/null; then
|
||||||
|
print_ok "MINIO_ENDPOINT is set"
|
||||||
|
else
|
||||||
|
print_info "MINIO_ENDPOINT not in .env (will use defaults)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_error ".env file not found"
|
||||||
|
print_info "Copy from template: cp .env.example .env"
|
||||||
|
print_info "Then edit .env and set required values"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Check Port Availability
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Port Availability"
|
||||||
|
|
||||||
|
check_port() {
|
||||||
|
local port=$1
|
||||||
|
local service=$2
|
||||||
|
|
||||||
|
if command -v ss &> /dev/null; then
|
||||||
|
if ss -tuln | grep -q ":$port "; then
|
||||||
|
PROCESS=$(ss -tulnp 2>/dev/null | grep ":$port " | awk '{print $NF}' | head -1)
|
||||||
|
print_warn "Port $port ($service) is in use: $PROCESS"
|
||||||
|
else
|
||||||
|
print_ok "Port $port ($service) is available"
|
||||||
|
fi
|
||||||
|
elif command -v netstat &> /dev/null; then
|
||||||
|
if netstat -tuln | grep -q ":$port "; then
|
||||||
|
print_warn "Port $port ($service) is in use"
|
||||||
|
else
|
||||||
|
print_ok "Port $port ($service) is available"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_info "Cannot check port $port - ss/netstat not available"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_port 8000 "Backend API"
|
||||||
|
check_port 3000 "Frontend Dev"
|
||||||
|
check_port 9000 "MinIO S3"
|
||||||
|
check_port 9001 "MinIO Console"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Summary
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Summary"
|
||||||
|
|
||||||
|
if [[ $ERRORS -eq 0 ]] && [[ $WARNINGS -eq 0 ]]; then
|
||||||
|
echo -e "${GREEN}All checks passed! Environment is ready.${NC}"
|
||||||
|
exit 0
|
||||||
|
elif [[ $ERRORS -eq 0 ]]; then
|
||||||
|
echo -e "${YELLOW}$WARNINGS warning(s) found. Environment may work but review warnings above.${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}$ERRORS error(s) and $WARNINGS warning(s) found.${NC}"
|
||||||
|
echo -e "${RED}Please fix the errors above before starting development.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Change: Add Development Scripts
|
||||||
|
|
||||||
|
## Why
|
||||||
|
Developers currently need to manually start multiple services (MinIO, backend, frontend) and verify environment prerequisites before running the application. This is error-prone and time-consuming. Automated scripts will streamline the development workflow and reduce onboarding friction.
|
||||||
|
|
||||||
|
## What Changes
|
||||||
|
- **NEW**: Environment check script (`check-env.sh`) - Validates all prerequisites
|
||||||
|
- **NEW**: Unified development startup script (`start-dev.sh`) - Starts all services
|
||||||
|
- **NEW**: Stop script (`stop-dev.sh`) - Gracefully stops all services
|
||||||
|
|
||||||
|
## Impact
|
||||||
|
- Affected specs: Creates new `dev-scripts` specification
|
||||||
|
- Affected code:
|
||||||
|
- Shell scripts in project root directory
|
||||||
|
- No changes to existing application code
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- Existing docker-compose.minio.yml for MinIO
|
||||||
|
- Python virtual environment (venv/)
|
||||||
|
- Node.js and npm for frontend
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
1. `check-env.sh` validates Python 3.10+, Node.js, Docker, required ports
|
||||||
|
2. `check-env.sh` provides clear error messages for missing prerequisites
|
||||||
|
3. `start-dev.sh` starts MinIO, backend, and frontend in correct order
|
||||||
|
4. `start-dev.sh` waits for each service to be healthy before proceeding
|
||||||
|
5. `stop-dev.sh` gracefully terminates all services
|
||||||
|
6. Scripts work on Linux/WSL environments
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
# dev-scripts Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Shell scripts to automate development environment setup, validation, and service orchestration for the Task Reporter system.
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: Environment Validation
|
||||||
|
The check-env script SHALL validate all prerequisites required to run the development environment.
|
||||||
|
|
||||||
|
#### Scenario: Check Python version
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify Python 3.10 or higher is installed
|
||||||
|
- Display the detected Python version
|
||||||
|
- Exit with error if Python version is insufficient
|
||||||
|
|
||||||
|
#### Scenario: Check Node.js and npm
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify Node.js is installed (v18+ recommended)
|
||||||
|
- Verify npm is available
|
||||||
|
- Display detected versions
|
||||||
|
|
||||||
|
#### Scenario: Check Docker availability
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify Docker daemon is running
|
||||||
|
- Verify docker-compose is available
|
||||||
|
- Display Docker version
|
||||||
|
|
||||||
|
#### Scenario: Check virtual environment
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify venv/ directory exists
|
||||||
|
- Suggest creation command if missing: `python -m venv venv`
|
||||||
|
|
||||||
|
#### Scenario: Check environment file
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify .env file exists
|
||||||
|
- Suggest copying from .env.example if missing
|
||||||
|
- Warn if critical variables appear empty (FERNET_KEY)
|
||||||
|
|
||||||
|
#### Scenario: Check port availability
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Check if ports 8000, 3000, 9000, 9001 are available
|
||||||
|
- Display which ports are in use and by what process
|
||||||
|
- Warn but continue if ports are occupied
|
||||||
|
|
||||||
|
### Requirement: Development Server Startup
|
||||||
|
The start-dev script SHALL orchestrate the startup of all development services in the correct order.
|
||||||
|
|
||||||
|
#### Scenario: Pre-flight validation
|
||||||
|
- **WHEN** the start-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Execute check-env.sh first
|
||||||
|
- Abort startup if critical checks fail
|
||||||
|
|
||||||
|
#### Scenario: Start MinIO
|
||||||
|
- **WHEN** start-dev begins service startup
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Start MinIO using docker-compose -f docker-compose.minio.yml up -d
|
||||||
|
- Wait for MinIO health check to pass (up to 30 seconds)
|
||||||
|
- Display MinIO console URL (http://localhost:9001)
|
||||||
|
|
||||||
|
#### Scenario: Start backend server
|
||||||
|
- **WHEN** MinIO is healthy
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Activate the virtual environment
|
||||||
|
- Install/update requirements if requirements.txt is newer than last install
|
||||||
|
- Start uvicorn in background: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||||
|
- Wait for backend to respond (up to 15 seconds)
|
||||||
|
- Display backend URL (http://localhost:8000)
|
||||||
|
|
||||||
|
#### Scenario: Start frontend dev server
|
||||||
|
- **WHEN** backend is healthy
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Check if node_modules exists, run npm install if missing
|
||||||
|
- Start frontend dev server: npm run dev
|
||||||
|
- Display frontend URL (http://localhost:3000)
|
||||||
|
|
||||||
|
#### Scenario: Display startup summary
|
||||||
|
- **WHEN** all services are running
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Display summary table with all service URLs
|
||||||
|
- Display log file locations
|
||||||
|
- Display instructions for stopping services
|
||||||
|
|
||||||
|
#### Scenario: Handle graceful shutdown
|
||||||
|
- **WHEN** user presses Ctrl+C during startup or operation
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Trap the SIGINT signal
|
||||||
|
- Execute stop-dev.sh to clean up
|
||||||
|
- Display shutdown confirmation
|
||||||
|
|
||||||
|
### Requirement: Development Server Shutdown
|
||||||
|
The stop-dev script SHALL gracefully terminate all development services.
|
||||||
|
|
||||||
|
#### Scenario: Stop frontend server
|
||||||
|
- **WHEN** stop-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Find and terminate the Vite dev server process
|
||||||
|
- Confirm termination or report if not running
|
||||||
|
|
||||||
|
#### Scenario: Stop backend server
|
||||||
|
- **WHEN** stop-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Find and terminate the uvicorn process
|
||||||
|
- Confirm termination or report if not running
|
||||||
|
|
||||||
|
#### Scenario: Stop MinIO
|
||||||
|
- **WHEN** stop-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Run docker-compose -f docker-compose.minio.yml down
|
||||||
|
- Preserve data volumes (do not use -v flag)
|
||||||
|
- Confirm MinIO container stopped
|
||||||
|
|
||||||
|
#### Scenario: Display shutdown summary
|
||||||
|
- **WHEN** all services are stopped
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Display confirmation message for each service
|
||||||
|
- Report any services that failed to stop
|
||||||
74
openspec/changes/archive/2025-12-01-add-dev-scripts/tasks.md
Normal file
74
openspec/changes/archive/2025-12-01-add-dev-scripts/tasks.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Implementation Tasks
|
||||||
|
|
||||||
|
## 1. Project Structure
|
||||||
|
- [x] 1.1 Scripts placed in project root directory
|
||||||
|
|
||||||
|
## 2. Environment Check Script
|
||||||
|
- [x] 2.1 Create `check-env.sh` with executable permissions
|
||||||
|
- [x] 2.2 Implement Python version check (3.10+)
|
||||||
|
- [x] 2.3 Implement Node.js and npm check
|
||||||
|
- [x] 2.4 Implement Docker availability check
|
||||||
|
- [x] 2.5 Implement virtual environment check (venv/)
|
||||||
|
- [x] 2.6 Implement .env file check with template guidance
|
||||||
|
- [x] 2.7 Implement port availability check (8000, 3000, 9000, 9001)
|
||||||
|
- [x] 2.8 Add colored output and clear error messages
|
||||||
|
|
||||||
|
## 3. Start Development Script
|
||||||
|
- [x] 3.1 Create `start-dev.sh` with executable permissions
|
||||||
|
- [x] 3.2 Call check-env.sh before starting services
|
||||||
|
- [x] 3.3 Start MinIO via docker-compose (with health check wait)
|
||||||
|
- [x] 3.4 Activate venv and start backend (uvicorn in background)
|
||||||
|
- [x] 3.5 Wait for backend to be healthy (curl localhost:8000/health or similar)
|
||||||
|
- [x] 3.6 Install frontend dependencies if node_modules missing
|
||||||
|
- [x] 3.7 Start frontend dev server (npm run dev in background)
|
||||||
|
- [x] 3.8 Display service URLs when all services are running
|
||||||
|
- [x] 3.9 Handle Ctrl+C to trigger graceful shutdown
|
||||||
|
|
||||||
|
## 4. Stop Development Script
|
||||||
|
- [x] 4.1 Create `stop-dev.sh` with executable permissions
|
||||||
|
- [x] 4.2 Stop frontend dev server
|
||||||
|
- [x] 4.3 Stop backend uvicorn process
|
||||||
|
- [x] 4.4 Stop MinIO docker container
|
||||||
|
- [x] 4.5 Display confirmation messages
|
||||||
|
|
||||||
|
## 5. Documentation
|
||||||
|
- [x] 5.1 Add usage instructions to scripts (--help flag)
|
||||||
|
- [x] 5.2 Update .env.example with any new required variables if needed
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
**Completed:** All 18 tasks across 5 sections
|
||||||
|
|
||||||
|
### Scripts Created (in project root)
|
||||||
|
```
|
||||||
|
./check-env.sh # Environment validation
|
||||||
|
./start-dev.sh # Start all services
|
||||||
|
./stop-dev.sh # Stop all services
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Ports
|
||||||
|
| Service | Port | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| Backend | 8000 | FastAPI server |
|
||||||
|
| Frontend | 3000 | Vite dev server |
|
||||||
|
| MinIO S3 | 9000 | Object storage API |
|
||||||
|
| MinIO UI | 9001 | Admin console |
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check environment prerequisites
|
||||||
|
./check-env.sh
|
||||||
|
|
||||||
|
# Start all services
|
||||||
|
./start-dev.sh
|
||||||
|
|
||||||
|
# Stop all services
|
||||||
|
./stop-dev.sh
|
||||||
|
|
||||||
|
# Start without MinIO (use external)
|
||||||
|
./start-dev.sh --no-minio
|
||||||
|
|
||||||
|
# Stop but keep MinIO running
|
||||||
|
./stop-dev.sh --keep-minio
|
||||||
|
```
|
||||||
123
openspec/specs/dev-scripts/spec.md
Normal file
123
openspec/specs/dev-scripts/spec.md
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# dev-scripts Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
TBD - created by archiving change add-dev-scripts. Update Purpose after archive.
|
||||||
|
## Requirements
|
||||||
|
### Requirement: Environment Validation
|
||||||
|
The check-env script SHALL validate all prerequisites required to run the development environment.
|
||||||
|
|
||||||
|
#### Scenario: Check Python version
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify Python 3.10 or higher is installed
|
||||||
|
- Display the detected Python version
|
||||||
|
- Exit with error if Python version is insufficient
|
||||||
|
|
||||||
|
#### Scenario: Check Node.js and npm
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify Node.js is installed (v18+ recommended)
|
||||||
|
- Verify npm is available
|
||||||
|
- Display detected versions
|
||||||
|
|
||||||
|
#### Scenario: Check Docker availability
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify Docker daemon is running
|
||||||
|
- Verify docker-compose is available
|
||||||
|
- Display Docker version
|
||||||
|
|
||||||
|
#### Scenario: Check virtual environment
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify venv/ directory exists
|
||||||
|
- Suggest creation command if missing: `python -m venv venv`
|
||||||
|
|
||||||
|
#### Scenario: Check environment file
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Verify .env file exists
|
||||||
|
- Suggest copying from .env.example if missing
|
||||||
|
- Warn if critical variables appear empty (FERNET_KEY)
|
||||||
|
|
||||||
|
#### Scenario: Check port availability
|
||||||
|
- **WHEN** the check-env script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Check if ports 8000, 3000, 9000, 9001 are available
|
||||||
|
- Display which ports are in use and by what process
|
||||||
|
- Warn but continue if ports are occupied
|
||||||
|
|
||||||
|
### Requirement: Development Server Startup
|
||||||
|
The start-dev script SHALL orchestrate the startup of all development services in the correct order.
|
||||||
|
|
||||||
|
#### Scenario: Pre-flight validation
|
||||||
|
- **WHEN** the start-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Execute check-env.sh first
|
||||||
|
- Abort startup if critical checks fail
|
||||||
|
|
||||||
|
#### Scenario: Start MinIO
|
||||||
|
- **WHEN** start-dev begins service startup
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Start MinIO using docker-compose -f docker-compose.minio.yml up -d
|
||||||
|
- Wait for MinIO health check to pass (up to 30 seconds)
|
||||||
|
- Display MinIO console URL (http://localhost:9001)
|
||||||
|
|
||||||
|
#### Scenario: Start backend server
|
||||||
|
- **WHEN** MinIO is healthy
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Activate the virtual environment
|
||||||
|
- Install/update requirements if requirements.txt is newer than last install
|
||||||
|
- Start uvicorn in background: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||||
|
- Wait for backend to respond (up to 15 seconds)
|
||||||
|
- Display backend URL (http://localhost:8000)
|
||||||
|
|
||||||
|
#### Scenario: Start frontend dev server
|
||||||
|
- **WHEN** backend is healthy
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Check if node_modules exists, run npm install if missing
|
||||||
|
- Start frontend dev server: npm run dev
|
||||||
|
- Display frontend URL (http://localhost:3000)
|
||||||
|
|
||||||
|
#### Scenario: Display startup summary
|
||||||
|
- **WHEN** all services are running
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Display summary table with all service URLs
|
||||||
|
- Display log file locations
|
||||||
|
- Display instructions for stopping services
|
||||||
|
|
||||||
|
#### Scenario: Handle graceful shutdown
|
||||||
|
- **WHEN** user presses Ctrl+C during startup or operation
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Trap the SIGINT signal
|
||||||
|
- Execute stop-dev.sh to clean up
|
||||||
|
- Display shutdown confirmation
|
||||||
|
|
||||||
|
### Requirement: Development Server Shutdown
|
||||||
|
The stop-dev script SHALL gracefully terminate all development services.
|
||||||
|
|
||||||
|
#### Scenario: Stop frontend server
|
||||||
|
- **WHEN** stop-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Find and terminate the Vite dev server process
|
||||||
|
- Confirm termination or report if not running
|
||||||
|
|
||||||
|
#### Scenario: Stop backend server
|
||||||
|
- **WHEN** stop-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Find and terminate the uvicorn process
|
||||||
|
- Confirm termination or report if not running
|
||||||
|
|
||||||
|
#### Scenario: Stop MinIO
|
||||||
|
- **WHEN** stop-dev script runs
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Run docker-compose -f docker-compose.minio.yml down
|
||||||
|
- Preserve data volumes (do not use -v flag)
|
||||||
|
- Confirm MinIO container stopped
|
||||||
|
|
||||||
|
#### Scenario: Display shutdown summary
|
||||||
|
- **WHEN** all services are stopped
|
||||||
|
- **THEN** the system SHALL:
|
||||||
|
- Display confirmation message for each service
|
||||||
|
- Report any services that failed to stop
|
||||||
|
|
||||||
278
start-dev.sh
Executable file
278
start-dev.sh
Executable file
@@ -0,0 +1,278 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================================================
|
||||||
|
# Development Server Startup Script for Task Reporter
|
||||||
|
# Starts all services: MinIO, Backend (FastAPI), Frontend (Vite)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Script directory (scripts are in project root)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$SCRIPT_DIR"
|
||||||
|
|
||||||
|
# PID file locations
|
||||||
|
PID_DIR="$PROJECT_ROOT/.pids"
|
||||||
|
BACKEND_PID_FILE="$PID_DIR/backend.pid"
|
||||||
|
FRONTEND_PID_FILE="$PID_DIR/frontend.pid"
|
||||||
|
|
||||||
|
# Log file locations
|
||||||
|
LOG_DIR="$PROJECT_ROOT/logs"
|
||||||
|
BACKEND_LOG="$LOG_DIR/backend.log"
|
||||||
|
FRONTEND_LOG="$LOG_DIR/frontend.log"
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
print_header() {
|
||||||
|
echo -e "\n${BLUE}=== $1 ===${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_ok() {
|
||||||
|
echo -e "${GREEN}[OK]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${CYAN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
show_help() {
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo ""
|
||||||
|
echo "Starts all development services for Task Reporter."
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " -h, --help Show this help message"
|
||||||
|
echo " --skip-checks Skip environment validation"
|
||||||
|
echo " --no-frontend Don't start frontend server"
|
||||||
|
echo " --no-minio Don't start MinIO (use external)"
|
||||||
|
echo ""
|
||||||
|
echo "Services started:"
|
||||||
|
echo " - MinIO (Object Storage) - http://localhost:9000 (API), http://localhost:9001 (Console)"
|
||||||
|
echo " - Backend (FastAPI) - http://localhost:8000"
|
||||||
|
echo " - Frontend (Vite) - http://localhost:3000"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cleanup function for graceful shutdown
|
||||||
|
cleanup() {
|
||||||
|
echo -e "\n${YELLOW}Shutting down services...${NC}"
|
||||||
|
"$PROJECT_ROOT/stop-dev.sh"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Trap Ctrl+C
|
||||||
|
trap cleanup SIGINT SIGTERM
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
SKIP_CHECKS=false
|
||||||
|
NO_FRONTEND=false
|
||||||
|
NO_MINIO=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--skip-checks)
|
||||||
|
SKIP_CHECKS=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--no-frontend)
|
||||||
|
NO_FRONTEND=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--no-minio)
|
||||||
|
NO_MINIO=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
echo -e "${BLUE} Task Reporter - Development Server${NC}"
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
mkdir -p "$PID_DIR"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Pre-flight Check
|
||||||
|
# ============================================================================
|
||||||
|
if [[ "$SKIP_CHECKS" == "false" ]]; then
|
||||||
|
print_header "Pre-flight Check"
|
||||||
|
if ! "$PROJECT_ROOT/check-env.sh" -q; then
|
||||||
|
print_error "Environment check failed. Fix issues above or use --skip-checks"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
print_ok "Environment check passed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Start MinIO
|
||||||
|
# ============================================================================
|
||||||
|
if [[ "$NO_MINIO" == "false" ]]; then
|
||||||
|
print_header "Starting MinIO"
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Check if MinIO container is already running
|
||||||
|
if docker ps --format '{{.Names}}' | grep -q "task-reporter-minio"; then
|
||||||
|
print_ok "MinIO is already running"
|
||||||
|
else
|
||||||
|
# Start MinIO
|
||||||
|
if command -v docker-compose &> /dev/null; then
|
||||||
|
docker-compose -f docker-compose.minio.yml up -d
|
||||||
|
else
|
||||||
|
docker compose -f docker-compose.minio.yml up -d
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait for MinIO to be healthy
|
||||||
|
print_info "Waiting for MinIO to be healthy..."
|
||||||
|
MINIO_READY=false
|
||||||
|
for i in {1..30}; do
|
||||||
|
if curl -s http://localhost:9000/minio/health/live > /dev/null 2>&1; then
|
||||||
|
MINIO_READY=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
echo -n "."
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$MINIO_READY" == "true" ]]; then
|
||||||
|
print_ok "MinIO is healthy"
|
||||||
|
else
|
||||||
|
print_error "MinIO failed to start within 30 seconds"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "MinIO Console: http://localhost:9001 (minioadmin/minioadmin)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Start Backend
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Starting Backend"
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Check if backend is already running
|
||||||
|
if [[ -f "$BACKEND_PID_FILE" ]] && kill -0 "$(cat "$BACKEND_PID_FILE")" 2>/dev/null; then
|
||||||
|
print_ok "Backend is already running (PID: $(cat "$BACKEND_PID_FILE"))"
|
||||||
|
else
|
||||||
|
# Activate virtual environment and start uvicorn
|
||||||
|
print_info "Starting uvicorn server..."
|
||||||
|
|
||||||
|
# Source the virtual environment and run uvicorn
|
||||||
|
(
|
||||||
|
source "$PROJECT_ROOT/venv/bin/activate"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 > "$BACKEND_LOG" 2>&1 &
|
||||||
|
echo $! > "$BACKEND_PID_FILE"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Wait for backend to be ready
|
||||||
|
print_info "Waiting for backend to be ready..."
|
||||||
|
BACKEND_READY=false
|
||||||
|
for i in {1..15}; do
|
||||||
|
if curl -s http://localhost:8000/api/health > /dev/null 2>&1 || curl -s http://localhost:8000/docs > /dev/null 2>&1; then
|
||||||
|
BACKEND_READY=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
echo -n "."
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$BACKEND_READY" == "true" ]]; then
|
||||||
|
print_ok "Backend is ready (PID: $(cat "$BACKEND_PID_FILE"))"
|
||||||
|
else
|
||||||
|
print_warn "Backend may still be starting. Check logs: $BACKEND_LOG"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "Backend API: http://localhost:8000"
|
||||||
|
print_info "API Docs: http://localhost:8000/docs"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Start Frontend
|
||||||
|
# ============================================================================
|
||||||
|
if [[ "$NO_FRONTEND" == "false" ]]; then
|
||||||
|
print_header "Starting Frontend"
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT/frontend"
|
||||||
|
|
||||||
|
# Check if frontend is already running
|
||||||
|
if [[ -f "$FRONTEND_PID_FILE" ]] && kill -0 "$(cat "$FRONTEND_PID_FILE")" 2>/dev/null; then
|
||||||
|
print_ok "Frontend is already running (PID: $(cat "$FRONTEND_PID_FILE"))"
|
||||||
|
else
|
||||||
|
# Install dependencies if needed
|
||||||
|
if [[ ! -d "node_modules" ]]; then
|
||||||
|
print_info "Installing frontend dependencies..."
|
||||||
|
npm install
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start Vite dev server
|
||||||
|
print_info "Starting Vite dev server..."
|
||||||
|
npm run dev > "$FRONTEND_LOG" 2>&1 &
|
||||||
|
echo $! > "$FRONTEND_PID_FILE"
|
||||||
|
|
||||||
|
# Wait for frontend to be ready
|
||||||
|
sleep 3
|
||||||
|
if kill -0 "$(cat "$FRONTEND_PID_FILE")" 2>/dev/null; then
|
||||||
|
print_ok "Frontend started (PID: $(cat "$FRONTEND_PID_FILE"))"
|
||||||
|
else
|
||||||
|
print_error "Frontend failed to start. Check logs: $FRONTEND_LOG"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "Frontend: http://localhost:3000"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Summary
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Services Running"
|
||||||
|
|
||||||
|
echo -e "${GREEN}============================================${NC}"
|
||||||
|
echo -e "${GREEN} All services are running!${NC}"
|
||||||
|
echo -e "${GREEN}============================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${CYAN}Frontend:${NC} http://localhost:3000"
|
||||||
|
echo -e " ${CYAN}Backend API:${NC} http://localhost:8000"
|
||||||
|
echo -e " ${CYAN}API Docs:${NC} http://localhost:8000/docs"
|
||||||
|
echo -e " ${CYAN}MinIO Console:${NC} http://localhost:9001"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${YELLOW}Logs:${NC}"
|
||||||
|
echo -e " Backend: $BACKEND_LOG"
|
||||||
|
echo -e " Frontend: $FRONTEND_LOG"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${YELLOW}Press Ctrl+C to stop all services${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Keep script running to catch Ctrl+C
|
||||||
|
while true; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
193
stop-dev.sh
Executable file
193
stop-dev.sh
Executable file
@@ -0,0 +1,193 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================================================
|
||||||
|
# Development Server Stop Script for Task Reporter
|
||||||
|
# Gracefully stops all services: Frontend, Backend, MinIO
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Script directory (scripts are in project root)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$SCRIPT_DIR"
|
||||||
|
|
||||||
|
# PID file locations
|
||||||
|
PID_DIR="$PROJECT_ROOT/.pids"
|
||||||
|
BACKEND_PID_FILE="$PID_DIR/backend.pid"
|
||||||
|
FRONTEND_PID_FILE="$PID_DIR/frontend.pid"
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
print_header() {
|
||||||
|
echo -e "\n${BLUE}=== $1 ===${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_ok() {
|
||||||
|
echo -e "${GREEN}[OK]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
show_help() {
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo ""
|
||||||
|
echo "Stops all development services for Task Reporter."
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " -h, --help Show this help message"
|
||||||
|
echo " --keep-minio Don't stop MinIO container"
|
||||||
|
echo " --keep-data Alias for --keep-minio"
|
||||||
|
echo ""
|
||||||
|
echo "Services stopped:"
|
||||||
|
echo " - Frontend (Vite dev server)"
|
||||||
|
echo " - Backend (uvicorn)"
|
||||||
|
echo " - MinIO (Docker container)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
KEEP_MINIO=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--keep-minio|--keep-data)
|
||||||
|
KEEP_MINIO=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
echo -e "${BLUE} Task Reporter - Stopping Services${NC}"
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Stop Frontend
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Stopping Frontend"
|
||||||
|
|
||||||
|
if [[ -f "$FRONTEND_PID_FILE" ]]; then
|
||||||
|
FRONTEND_PID=$(cat "$FRONTEND_PID_FILE")
|
||||||
|
if kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
||||||
|
kill "$FRONTEND_PID" 2>/dev/null || true
|
||||||
|
# Also kill any child processes (npm spawns node)
|
||||||
|
pkill -P "$FRONTEND_PID" 2>/dev/null || true
|
||||||
|
sleep 1
|
||||||
|
# Force kill if still running
|
||||||
|
if kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
||||||
|
kill -9 "$FRONTEND_PID" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
print_ok "Frontend stopped (was PID: $FRONTEND_PID)"
|
||||||
|
else
|
||||||
|
print_info "Frontend was not running"
|
||||||
|
fi
|
||||||
|
rm -f "$FRONTEND_PID_FILE"
|
||||||
|
else
|
||||||
|
# Try to find and kill vite process
|
||||||
|
VITE_PID=$(pgrep -f "vite.*frontend" 2>/dev/null | head -1)
|
||||||
|
if [[ -n "$VITE_PID" ]]; then
|
||||||
|
kill "$VITE_PID" 2>/dev/null || true
|
||||||
|
print_ok "Frontend stopped (found PID: $VITE_PID)"
|
||||||
|
else
|
||||||
|
print_info "Frontend was not running"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Stop Backend
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Stopping Backend"
|
||||||
|
|
||||||
|
if [[ -f "$BACKEND_PID_FILE" ]]; then
|
||||||
|
BACKEND_PID=$(cat "$BACKEND_PID_FILE")
|
||||||
|
if kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||||
|
kill "$BACKEND_PID" 2>/dev/null || true
|
||||||
|
sleep 1
|
||||||
|
# Force kill if still running
|
||||||
|
if kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||||
|
kill -9 "$BACKEND_PID" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
print_ok "Backend stopped (was PID: $BACKEND_PID)"
|
||||||
|
else
|
||||||
|
print_info "Backend was not running"
|
||||||
|
fi
|
||||||
|
rm -f "$BACKEND_PID_FILE"
|
||||||
|
else
|
||||||
|
# Try to find and kill uvicorn process
|
||||||
|
UVICORN_PID=$(pgrep -f "uvicorn app.main:app" 2>/dev/null | head -1)
|
||||||
|
if [[ -n "$UVICORN_PID" ]]; then
|
||||||
|
kill "$UVICORN_PID" 2>/dev/null || true
|
||||||
|
print_ok "Backend stopped (found PID: $UVICORN_PID)"
|
||||||
|
else
|
||||||
|
print_info "Backend was not running"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Stop MinIO
|
||||||
|
# ============================================================================
|
||||||
|
if [[ "$KEEP_MINIO" == "false" ]]; then
|
||||||
|
print_header "Stopping MinIO"
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
if docker ps --format '{{.Names}}' | grep -q "task-reporter-minio"; then
|
||||||
|
if command -v docker-compose &> /dev/null; then
|
||||||
|
docker-compose -f docker-compose.minio.yml down
|
||||||
|
else
|
||||||
|
docker compose -f docker-compose.minio.yml down
|
||||||
|
fi
|
||||||
|
print_ok "MinIO stopped (data preserved)"
|
||||||
|
else
|
||||||
|
print_info "MinIO was not running"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_header "MinIO"
|
||||||
|
print_info "Keeping MinIO running (--keep-minio)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Cleanup
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Cleanup"
|
||||||
|
|
||||||
|
# Remove PID directory if empty
|
||||||
|
if [[ -d "$PID_DIR" ]] && [[ -z "$(ls -A "$PID_DIR")" ]]; then
|
||||||
|
rmdir "$PID_DIR"
|
||||||
|
print_ok "Cleaned up PID directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Summary
|
||||||
|
# ============================================================================
|
||||||
|
print_header "Summary"
|
||||||
|
|
||||||
|
echo -e "${GREEN}All services have been stopped.${NC}"
|
||||||
|
echo ""
|
||||||
|
if [[ "$KEEP_MINIO" == "true" ]]; then
|
||||||
|
echo -e " ${YELLOW}Note:${NC} MinIO is still running (use without --keep-minio to stop)"
|
||||||
|
fi
|
||||||
|
echo -e " ${BLUE}Tip:${NC} Run ./scripts/start-dev.sh to start services again"
|
||||||
|
echo ""
|
||||||
Reference in New Issue
Block a user