201 lines
7.0 KiB
Bash
201 lines
7.0 KiB
Bash
#!/bin/bash
|
|
# ============================================
|
|
# Chat Switchboard - Schema Validation (v0.9)
|
|
# ============================================
|
|
# Verifies the database schema is correct after
|
|
# migration. Checks expected tables, key columns,
|
|
# and constraints. Exits non-zero on any failure.
|
|
#
|
|
# Required env vars:
|
|
# PGHOST, PGPORT, PGUSER, PGPASSWORD, PGDATABASE
|
|
#
|
|
# Usage:
|
|
# scripts/db-validate.sh
|
|
# ============================================
|
|
|
|
set -euo pipefail
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "Schema validation: ${PGDATABASE}"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
ERRORS=0
|
|
|
|
# ── Helper: check table exists ───────────────
|
|
check_table() {
|
|
local table="$1"
|
|
local exists
|
|
exists=$(psql -tAc "SELECT 1 FROM information_schema.tables WHERE table_schema='public' AND table_name='${table}';")
|
|
if [[ "${exists}" == "1" ]]; then
|
|
echo " ✓ table: ${table}"
|
|
else
|
|
echo " ✗ MISSING table: ${table}"
|
|
ERRORS=$((ERRORS + 1))
|
|
fi
|
|
}
|
|
|
|
# ── Helper: check column exists ──────────────
|
|
check_column() {
|
|
local table="$1"
|
|
local column="$2"
|
|
local exists
|
|
exists=$(psql -tAc "SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='${table}' AND column_name='${column}';")
|
|
if [[ "${exists}" == "1" ]]; then
|
|
echo " ✓ column: ${table}.${column}"
|
|
else
|
|
echo " ✗ MISSING column: ${table}.${column}"
|
|
ERRORS=$((ERRORS + 1))
|
|
fi
|
|
}
|
|
|
|
# ── Helper: check extension ──────────────────
|
|
check_extension() {
|
|
local ext="$1"
|
|
local exists
|
|
exists=$(psql -tAc "SELECT 1 FROM pg_extension WHERE extname='${ext}';")
|
|
if [[ "${exists}" == "1" ]]; then
|
|
echo " ✓ extension: ${ext}"
|
|
else
|
|
echo " ✗ MISSING extension: ${ext}"
|
|
ERRORS=$((ERRORS + 1))
|
|
fi
|
|
}
|
|
|
|
# ── 1. Extensions ────────────────────────────
|
|
echo ""
|
|
echo "Extensions:"
|
|
check_extension "pgcrypto"
|
|
|
|
# ── 2. Migration tracking ───────────────────
|
|
echo ""
|
|
echo "Migration tracking:"
|
|
check_table "schema_migrations"
|
|
MIGRATION_COUNT=$(psql -tAc "SELECT COUNT(*) FROM schema_migrations;" 2>/dev/null || echo "0")
|
|
echo " ✓ ${MIGRATION_COUNT} migrations applied"
|
|
|
|
LATEST=$(psql -tAc "SELECT version FROM schema_migrations ORDER BY version DESC LIMIT 1;" 2>/dev/null || echo "none")
|
|
echo " ✓ latest: ${LATEST}"
|
|
|
|
# ── 3. Core tables ──────────────────────────
|
|
echo ""
|
|
echo "Core tables:"
|
|
check_table "users"
|
|
check_table "provider_configs"
|
|
check_table "channels"
|
|
check_table "messages"
|
|
check_table "teams"
|
|
check_table "team_members"
|
|
check_table "refresh_tokens"
|
|
check_table "global_settings"
|
|
|
|
# ── 4. Users ────────────────────────────────
|
|
echo ""
|
|
echo "Users:"
|
|
check_column "users" "id"
|
|
check_column "users" "username"
|
|
check_column "users" "email"
|
|
check_column "users" "role"
|
|
check_column "users" "is_active"
|
|
check_column "users" "avatar_url"
|
|
check_column "users" "display_name"
|
|
check_column "users" "settings"
|
|
|
|
# ── 5. Provider Configs (replaces api_configs) ─
|
|
echo ""
|
|
echo "Provider Configs:"
|
|
check_column "provider_configs" "scope"
|
|
check_column "provider_configs" "owner_id"
|
|
check_column "provider_configs" "provider"
|
|
check_column "provider_configs" "endpoint"
|
|
check_column "provider_configs" "api_key_enc"
|
|
check_column "provider_configs" "headers"
|
|
check_column "provider_configs" "settings"
|
|
check_column "provider_configs" "is_active"
|
|
|
|
# ── 6. Model Catalog (replaces model_configs) ─
|
|
echo ""
|
|
echo "Model Catalog:"
|
|
check_table "model_catalog"
|
|
check_column "model_catalog" "provider_config_id"
|
|
check_column "model_catalog" "model_id"
|
|
check_column "model_catalog" "display_name"
|
|
check_column "model_catalog" "capabilities"
|
|
check_column "model_catalog" "pricing"
|
|
check_column "model_catalog" "visibility"
|
|
|
|
# ── 7. Personas (replaces model_presets) ────
|
|
echo ""
|
|
echo "Personas:"
|
|
check_table "personas"
|
|
check_column "personas" "scope"
|
|
check_column "personas" "owner_id"
|
|
check_column "personas" "name"
|
|
check_column "personas" "base_model_id"
|
|
check_column "personas" "provider_config_id"
|
|
check_column "personas" "system_prompt"
|
|
check_column "personas" "created_by"
|
|
|
|
# ── 8. Channels ─────────────────────────────
|
|
echo ""
|
|
echo "Channels:"
|
|
check_column "channels" "user_id"
|
|
check_column "channels" "type"
|
|
check_column "channels" "provider_config_id"
|
|
check_column "channels" "team_id"
|
|
check_column "channels" "settings"
|
|
check_table "channel_members"
|
|
check_table "channel_models"
|
|
check_table "channel_cursors"
|
|
|
|
# ── 9. Messages ─────────────────────────────
|
|
echo ""
|
|
echo "Messages:"
|
|
check_column "messages" "channel_id"
|
|
check_column "messages" "role"
|
|
check_column "messages" "parent_id"
|
|
check_column "messages" "sibling_index"
|
|
check_column "messages" "deleted_at"
|
|
check_column "messages" "participant_type"
|
|
|
|
# ── 10. Organization ────────────────────────
|
|
echo ""
|
|
echo "Organization:"
|
|
check_table "folders"
|
|
check_table "projects"
|
|
check_table "notes"
|
|
check_column "notes" "search_vector"
|
|
|
|
# ── 11. User Model Settings ────────────────
|
|
echo ""
|
|
echo "User Model Settings:"
|
|
check_table "user_model_settings"
|
|
check_column "user_model_settings" "user_id"
|
|
check_column "user_model_settings" "model_id"
|
|
check_column "user_model_settings" "hidden"
|
|
check_column "user_model_settings" "sort_order"
|
|
|
|
# ── 12. Audit Log ───────────────────────────
|
|
echo ""
|
|
echo "Audit Log:"
|
|
check_table "audit_log"
|
|
check_column "audit_log" "actor_id"
|
|
check_column "audit_log" "action"
|
|
check_column "audit_log" "resource_type"
|
|
|
|
# ═══════════════════════════════════════════
|
|
# ADD NEW MIGRATION CHECKS ABOVE THIS LINE
|
|
# ═══════════════════════════════════════════
|
|
|
|
# ── Summary ──────────────────────────────────
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
if [[ ${ERRORS} -eq 0 ]]; then
|
|
echo "✅ Schema validation passed (${MIGRATION_COUNT} migrations)"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
exit 0
|
|
else
|
|
echo "❌ Schema validation FAILED: ${ERRORS} errors"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
exit 1
|
|
fi
|