Skip to content

Tenant Upgrade Runbook

Last Updated: December 5, 2025

This document describes how to upgrade tenant cbapp instances to the latest code, including running migrations and restarting services.


Prerequisites

  • SSH access to server
  • cbapp repo has latest code pushed to main branch
  • Tenant is registered in cbtenant database

Quick Reference

# Variables - set these for your tenant
TENANT_SLUG="ky04"
TENANT_DIR="/home/bisenbek/projects/nominate/${TENANT_SLUG}"
TENANT_PORT="32321"  # Check cbtenant DB for actual port

# 1. Pull latest code
cd $TENANT_DIR
git fetch origin main:main
git stash  # if needed
git checkout main

# 2. Add API_KEYS to .env (if not present)
grep "API_KEYS" .env || echo 'API_KEYS=test-api-key-for-development' >> .env

# 3. Run migrations
./venv/bin/python scripts/migrate_add_import_metadata.py
./venv/bin/python scripts/add_person_indexes.py

# 4. Restart service
PID=$(ps aux | grep "run_api.py.*${TENANT_PORT}" | grep -v grep | awk '{print $2}')
kill $PID
nohup ./venv/bin/python run_api.py --host 0.0.0.0 --port $TENANT_PORT > /tmp/${TENANT_SLUG}-api.log 2>&1 &

# 5. Verify
curl http://localhost:${TENANT_PORT}/api/health

Detailed Steps

Step 1: Get Tenant Info

Query the cbtenant database for tenant details:

cd /home/bisenbek/projects/nominate/cbtenant
sqlite3 db/manager.db "SELECT slug, backend_port, directory FROM tenants;"

Output example:

mi20-clevenger|32311|/home/bisenbek/projects/nominate/mi20-clevenger
ky04|32321|/home/bisenbek/projects/nominate/ky04

Step 2: Update Code

cd /home/bisenbek/projects/nominate/<TENANT_SLUG>

# Check current remote (should be cbapp)
git remote -v

# If pointing to wrong repo, fix it:
git remote set-url origin git@github.com:Nominate-AI/cbapp.git

# Fetch and checkout main
git fetch origin main:main
git stash  # Save any local changes
git checkout main

# Verify we have latest commits
git log --oneline -3
# Should show:
# d9ddc8e Add direct DuckDB bulk import endpoint for fast CSV imports
# 0d52d39 Add API key auth, import metadata, and performance indexes
# e50e9b1 Add comprehensive documentation for cbapp development

Step 3: Configure API Keys

The bulk import feature requires API key authentication:

# Check if API_KEYS is configured
grep "API_KEYS" .env

# If not present, add it:
echo 'API_KEYS=test-api-key-for-development' >> .env

Note: For production, generate a secure API key and update both: - Tenant's .env (API_KEYS) - cbtenant's .env (CBAPP_API_KEY)

Step 4: Run Migrations

Two migrations are required for the bulk import feature:

# Add import metadata columns (import_source, import_batch_id, etc.)
./venv/bin/python scripts/migrate_add_import_metadata.py

# Add performance indexes
./venv/bin/python scripts/add_person_indexes.py

Expected output for metadata migration:

Running migration on database at .../db/pocket.db
Adding import metadata columns to person table...
✓ Added import_source column
✓ Added import_date column
✓ Added import_batch_id column
✓ Added import_filename column
✓ Added original_data column
✓ Created index on import_batch_id
Migration completed successfully!

Step 5: Restart Service

# Find and kill existing process
TENANT_PORT=32321  # Replace with actual port
PID=$(ps aux | grep "run_api.py.*${TENANT_PORT}" | grep -v grep | awk '{print $2}')
echo "Killing PID: $PID"
kill $PID

# Wait for clean shutdown
sleep 2

# Start new process
nohup ./venv/bin/python run_api.py --host 0.0.0.0 --port $TENANT_PORT > /tmp/tenant-api.log 2>&1 &
echo "Started with PID: $!"

Step 6: Verify

# Health check
curl http://localhost:${TENANT_PORT}/api/health
# Expected: {"status":"healthy"}

# Test bulk import endpoint (should return validation error, not 404)
curl -X POST http://localhost:${TENANT_PORT}/api/persons/bulk-import \
  -H "X-API-Key: test-api-key-for-development" \
  -H "Content-Type: application/json" \
  -d '{"file_path": "/tmp/test.csv", "mappings": {}, "batch_id": "test", "list_name": "test"}'
# Expected: {"detail":"File path must be within /tmp/imports"} or similar

Tenant Status

Tenant Port Code Version Migrations Status
ky04 32321 d9ddc8e (latest) ✅ Complete ✅ Running
mi20-clevenger 32311 d9ddc8e (latest) ✅ Complete ✅ Running

Last Updated: December 5, 2025


Troubleshooting

Git checkout fails with "untracked files would be overwritten"

# Remove conflicting untracked files
rm scripts/add_person_columns.py  # or whatever file is conflicting
git checkout main

Migration fails with "column already exists"

This is safe to ignore - the column was already added in a previous run.

Service won't start

Check the log file:

tail -50 /tmp/tenant-api.log

Common issues: - Port already in use: Kill the old process first - Missing dependencies: Run pip install -r requirements.txt - Database locked: Wait for other operations to complete

API key authentication fails

Verify API_KEYS is set in .env:

grep API_KEYS .env
# Should show: API_KEYS=test-api-key-for-development


  • cbapp/CLAUDE.md - Developer documentation
  • cbtenant/docs/DATABASE_ARCHITECTURE.md - Database schema details
  • GitHub Issues: Nominate-AI/cbapp#1-4 - Implementation details