Document Status: Operational Procedures Last Updated: September 30, 2025 Audience: Developers and Operations Teams
This guide provides operational procedures for running, managing, and troubleshooting Piper Morgan. Covers server management, spatial systems, feature flags, security configuration, and common issues.
Components:
Process Management:
Method 1: Start Script (Recommended)
# Start both backend and frontend
./start-piper.sh
# Script performs:
# 1. Starts backend on port 8001 (uvicorn)
# 2. Waits for backend health check
# 3. Starts frontend on port 3000 (Next.js dev server)
# 4. Waits for frontend health check
# 5. Displays status of both services
Method 2: Manual Start (Development)
# Terminal 1: Start backend
cd /path/to/piper-morgan
source venv/bin/activate # If using virtual environment
PYTHONPATH=. uvicorn main:app --host 0.0.0.0 --port 8001 --reload
# Terminal 2: Start frontend
cd web
npm run dev
Expected Output:
Backend: http://localhost:8001 ✅
Frontend: http://localhost:3000 ✅
API Docs: http://localhost:8001/docs
Health: http://localhost:8001/health
Method 1: Stop Script (Recommended)
# Stop both services cleanly
./stop-piper.sh
# Script performs:
# 1. Reads PID files (backend.pid, frontend.pid)
# 2. Sends SIGTERM to processes
# 3. Waits for graceful shutdown (5s timeout)
# 4. Removes PID files
# 5. Verifies processes stopped
Method 2: Manual Stop
# Find and kill processes
lsof -ti :8001 | xargs kill -9 # Backend
lsof -ti :3000 | xargs kill -9 # Frontend
# Clean up PID files
rm -f backend.pid frontend.pid
Verification:
# Check ports are freed
lsof -i :8001 # Should return nothing
lsof -i :3000 # Should return nothing
Backend Health Check:
# Check backend health
curl http://localhost:8001/health
# Expected response:
{
"status": "healthy",
"timestamp": "2025-09-30T12:00:00Z",
"version": "1.0.0"
}
Frontend Health Check:
# Check frontend is responding
curl http://localhost:3000
# Expected: HTML response (Next.js app)
Database Health Check:
# Connect to database
docker exec -it piper-postgres psql -U piper -d piper_morgan
# Or using psql directly (if installed)
PGPASSWORD=your_password psql -h localhost -p 5433 -U piper -d piper_morgan
# Check database status
\l # List databases
\dt # List tables
Piper Morgan uses environment variables to control spatial intelligence systems.
Available Flags:
USE_SPATIAL_SLACK - Controls Slack spatial system (default: true)USE_SPATIAL_NOTION - Controls Notion spatial system (default: true)USE_SPATIAL_CALENDAR - Controls Calendar spatial system (default: true)USE_SPATIAL_GITHUB - Controls GitHub spatial system (default: true)Enable Spatial Systems (Default):
# Enable Slack spatial intelligence
export USE_SPATIAL_SLACK=true
# Enable Notion spatial intelligence
export USE_SPATIAL_NOTION=true
# Restart server to activate
./stop-piper.sh && ./start-piper.sh
Disable Spatial Systems (Legacy Mode):
# Disable for legacy/basic mode
export USE_SPATIAL_SLACK=false
export USE_SPATIAL_NOTION=false
# Restart server to activate
./stop-piper.sh && ./start-piper.sh
Persistent Configuration:
# Add to .env file (recommended)
cat >> .env << 'EOF'
USE_SPATIAL_SLACK=true
USE_SPATIAL_NOTION=true
USE_SPATIAL_CALENDAR=true
USE_SPATIAL_GITHUB=true
EOF
# Or add to shell profile (~/.bashrc, ~/.zshrc)
echo 'export USE_SPATIAL_SLACK=true' >> ~/.bashrc
source ~/.bashrc
Test Slack Spatial System:
# Python REPL or script
from services.integrations.slack.slack_integration_router import SlackIntegrationRouter
router = SlackIntegrationRouter()
adapter = router.get_spatial_adapter()
if adapter:
print(f"✅ Slack spatial system operational")
print(f" Adapter type: {type(adapter).__name__}")
# List available methods
methods = [m for m in dir(adapter) if not m.startswith('_')]
print(f" Methods: {len(methods)} available")
print(f" Methods: {', '.join(methods[:5])}...")
else:
print(f"❌ Slack spatial system not available")
Test Notion Spatial System:
# Python REPL or script
from services.intelligence.spatial.notion_spatial import NotionSpatialIntelligence
try:
spatial = NotionSpatialIntelligence()
print(f"✅ Notion spatial system operational")
print(f" Dimensions: {len(spatial.dimensions)} available")
print(f" Dimensions: {list(spatial.dimensions.keys())}")
except Exception as e:
print(f"❌ Notion spatial system error: {e}")
Quick Verification Script:
# Create verification script
cat > verify_spatial.py << 'EOF'
#!/usr/bin/env python3
import sys
import os
print("=== SPATIAL SYSTEM VERIFICATION ===\n")
# Check environment variables
slack_flag = os.environ.get('USE_SPATIAL_SLACK', 'true')
notion_flag = os.environ.get('USE_SPATIAL_NOTION', 'true')
print(f"USE_SPATIAL_SLACK={slack_flag}")
print(f"USE_SPATIAL_NOTION={notion_flag}\n")
# Test Slack
try:
from services.integrations.slack.slack_integration_router import SlackIntegrationRouter
router = SlackIntegrationRouter()
adapter = router.get_spatial_adapter()
print(f"✅ Slack spatial: {'enabled' if adapter else 'disabled'}")
except Exception as e:
print(f"❌ Slack spatial error: {e}")
# Test Notion
try:
from services.intelligence.spatial.notion_spatial import NotionSpatialIntelligence
spatial = NotionSpatialIntelligence()
print(f"✅ Notion spatial: enabled ({len(spatial.dimensions)} dimensions)")
except Exception as e:
print(f"❌ Notion spatial error: {e}")
print("\n=== VERIFICATION COMPLETE ===")
EOF
chmod +x verify_spatial.py
# Run verification
PYTHONPATH=. python3 verify_spatial.py
Piper Morgan implements graceful degradation for webhook security.
Development Mode (Default - No Configuration):
Production Mode (Signing Secret Configured):
Configure for Production:
# Get signing secret from Slack App settings
# 1. Open Slack App > Basic Information
# 2. Scroll to "App Credentials"
# 3. Copy "Signing Secret"
# Set environment variable
export SLACK_SIGNING_SECRET=your_secret_here
# Or in .env file
echo "SLACK_SIGNING_SECRET=your_secret_here" >> .env
# Restart server to activate
./stop-piper.sh && ./start-piper.sh
Verify Security Mode:
# Check logs after server start
# Development mode shows:
# WARNING: No Slack signing secret configured, skipping signature verification
# Production mode shows:
# (no warning - signature verification active)
# Test with curl
curl -X POST http://localhost:8001/slack/webhooks/events \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
# Development: Returns 200 OK
# Production (no signature): Returns 401 Unauthorized
Connection Settings:
# PostgreSQL connection (note port 5433, not 5432)
DATABASE_URL=postgresql://piper:password@localhost:5433/piper_morgan
# Or individual settings
DB_HOST=localhost
DB_PORT=5433
DB_NAME=piper_morgan
DB_USER=piper
DB_PASSWORD=your_password
Common Operations:
# Connect to database
docker exec -it piper-postgres psql -U piper -d piper_morgan
# Backup database
pg_dump -h localhost -p 5433 -U piper piper_morgan > backup.sql
# Restore database
psql -h localhost -p 5433 -U piper piper_morgan < backup.sql
# Check database size
psql -h localhost -p 5433 -U piper -d piper_morgan -c "SELECT pg_size_pretty(pg_database_size('piper_morgan'));"
Issue: Spatial system not working
Symptoms:
get_spatial_adapter() returns NoneSolutions:
echo $USE_SPATIAL_SLACK
echo $USE_SPATIAL_NOTION
PYTHONPATH=. python3 -c "from services.integrations.slack.slack_integration_router import SlackIntegrationRouter; print('✅ Import successful')"
tail -f logs/app.log | grep -i spatial
./stop-piper.sh && ./start-piper.sh
Issue: Webhooks rejected in production (401 Unauthorized)
Symptoms:
Solutions:
echo $SLACK_SIGNING_SECRET
# Should output your signing secret (not empty)
tail -f logs/app.log | grep -i signature
date # Check server time
ntpq -p # Check NTP sync (if available)
Issue: Webhooks accepted when they shouldn’t be
Symptoms:
Solutions:
export SLACK_SIGNING_SECRET=your_secret_here
./stop-piper.sh && ./start-piper.sh
tail -f logs/app.log | grep "skipping signature verification"
# Should not appear after restart
Issue: Server won’t start (port already in use)
Symptoms:
Error: Address already in use (port 8001)
Error: Address already in use (port 3000)
Solutions:
lsof -i :8001
lsof -i :3000
./stop-piper.sh
# Or manual kill
lsof -ti :8001 | xargs kill -9
lsof -ti :3000 | xargs kill -9
rm -f backend.pid frontend.pid
./start-piper.sh
Issue: Server starts but immediately crashes
Symptoms:
ps outputSolutions:
tail -f logs/app.log
pip list | grep -E "(fastapi|uvicorn|pydantic)"
psql -h localhost -p 5433 -U piper -d piper_morgan -c "SELECT 1;"
PYTHONPATH=. uvicorn main:app --host 0.0.0.0 --port 8001
Issue: Database connection errors
Symptoms:
psycopg2.OperationalError: could not connect to server
Connection refused (port 5433)
Solutions:
docker ps | grep postgres
# Should show piper-postgres container
docker start piper-postgres
# Correct
psql -h localhost -p 5433 -U piper -d piper_morgan
# Wrong (default PostgreSQL port)
psql -h localhost -p 5432 -U piper -d piper_morgan
echo $DATABASE_URL
# Should contain :5433 not :5432
All Tests:
# Run full test suite
PYTHONPATH=. pytest tests/ -v
# With coverage
PYTHONPATH=. pytest tests/ --cov=services --cov-report=html
Specific Test Categories:
# Integration tests
PYTHONPATH=. pytest tests/integration/ -v
# Unit tests
PYTHONPATH=. pytest tests/unit/ -v
# Spatial tests
PYTHONPATH=. pytest tests/integration/test_slack_spatial* -v
PYTHONPATH=. pytest tests/features/test_notion_spatial* -v
# Specific test file
PYTHONPATH=. pytest tests/integration/test_slack_spatial_adapter_integration.py -v
Feature Flag Testing:
# Test with spatial enabled
USE_SPATIAL_SLACK=true PYTHONPATH=. pytest tests/integration/test_slack* -v
# Test with spatial disabled
USE_SPATIAL_SLACK=false PYTHONPATH=. pytest tests/integration/test_slack* -v
Application Logs:
# Follow application logs
tail -f logs/app.log
# Last 100 lines
tail -100 logs/app.log
# Filter for errors
tail -f logs/app.log | grep ERROR
# Filter for specific feature
tail -f logs/app.log | grep -i spatial
tail -f logs/app.log | grep -i webhook
Server Access Logs:
# Follow access logs
tail -f logs/access.log
# Show recent requests
tail -100 logs/access.log
Common Tasks:
# Vacuum database
psql -h localhost -p 5433 -U piper -d piper_morgan -c "VACUUM ANALYZE;"
# Check table sizes
psql -h localhost -p 5433 -U piper -d piper_morgan -c "
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;"
# Check for slow queries
psql -h localhost -p 5433 -U piper -d piper_morgan -c "
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;"
Ports:
Scripts:
./start-piper.sh./stop-piper.shHealth Checks:
http://localhost:8001/healthhttp://localhost:3000Feature Flags:
USE_SPATIAL_SLACK=true/falseUSE_SPATIAL_NOTION=true/falseSecurity:
SLACK_SIGNING_SECRET=your_secretKey Paths:
logs/app.log, logs/access.logbackend.pid, frontend.pid.env, environment variablesResources:
docs/architecture/http://localhost:8001/docsoperationsCommon Issue Labels:
spatial-systems - Spatial intelligence issuessecurity - Webhook security, authenticationoperations - Server management, deploymentSee Also:
Maintained by: Piper Morgan Core Team Last Verified: September 30, 2025 (CORE-GREAT-2C)