#!/bin/bash # consolidate-clavitor-db-production.sh # PRODUCTION VERSION - More conservative than local dev # Only removes truly unused tables, keeps operational data set -e DB="${1:-/opt/clavitor-web/clavitor.db}" BACKUP="${DB}.backup.$(date +%Y%m%d_%H%M%S)" echo "=== Clavitor DB Production Consolidation ===" echo "Target: $DB" echo "" # Pre-flight check - show current state echo "=== Current State ===" sqlite3 "$DB" <<'EOF' SELECT "=== Row Counts ==="; SELECT "accounts: " || COUNT(*) FROM accounts; SELECT "domain_scopes: " || COUNT(*) || " (KEEP - used)" FROM domain_scopes; SELECT "incidents: " || COUNT(*) FROM incidents; SELECT "incident_updates: " || COUNT(*) FROM incident_updates; SELECT "login_codes: " || COUNT(*) || " (DROP - ephemeral)" FROM login_codes; SELECT "maintenance: " || COUNT(*) || " (KEEP - 149 records)" FROM maintenance; SELECT "outages: " || COUNT(*) || " (KEEP - 1 record)" FROM outages; SELECT "pops: " || COUNT(*) || " (KEEP - source of truth)" FROM pops; SELECT "sessions: " || COUNT(*) || " (DROP - ephemeral)" FROM sessions; SELECT "telemetry: " || COUNT(*) || " (KEEP - 676k records)" FROM telemetry; SELECT "uptime: " || COUNT(*) || " (KEEP - status page)" FROM uptime; SELECT "uptime_daily: " || COUNT(*) || " (KEEP - 351 records)" FROM uptime_daily; SELECT "uptime_spans: " || COUNT(*) || " (KEEP - 66 records)" FROM uptime_spans; SELECT "vaults: " || COUNT(*) || " (DROP - obsolete)" FROM vaults; EOF echo "" read -p "Continue with backup and consolidation? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Aborted." exit 1 fi # Create backup echo "" echo "=== Creating Backup ===" cp "$DB" "$BACKUP" echo "✓ Backup: $BACKUP" echo "" echo "=== Phase 1: Drop Only Truly Unused Tables ===" # Only drop tables that are definitely not used in production # accounts (2 rows) - might be referenced, keep for now # login_codes (0 rows) - safe to drop (ephemeral) # sessions (3 rows) - safe to drop (ephemeral) # vaults (1 row) - obsolete hosted vaults sqlite3 "$DB" <<'EOF' PRAGMA foreign_keys = OFF; -- Safe drops (no production data or ephemeral) DROP TABLE IF EXISTS login_codes; DROP TABLE IF EXISTS sessions; DROP TABLE IF EXISTS vaults; PRAGMA foreign_keys = ON; EOF echo "✓ Dropped ephemeral tables (login_codes, sessions, vaults)" echo "" echo "=== Phase 2: Consolidate Status Tables (Optional) ===" # Check if we should merge maintenance/outages into incidents MAINT_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM maintenance") OUTAGE_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM outages") INCIDENT_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM incidents") echo "Maintenance records: $MAINT_COUNT" echo "Outage records: $OUTAGE_COUNT" echo "Incident records: $INCIDENT_COUNT" if [[ $INCIDENT_COUNT -eq 0 && ($MAINT_COUNT -gt 0 || $OUTAGE_COUNT -gt 0) ]]; then read -p "Merge maintenance ($MAINT_COUNT) and outages ($OUTAGE_COUNT) into incidents? (y/N) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then sqlite3 "$DB" <<'EOF' PRAGMA foreign_keys = OFF; -- Migrate maintenance windows to incidents INSERT INTO incidents (title, status, date, node_ids, created_at) SELECT 'Maintenance: ' || COALESCE(reason, 'Scheduled'), CASE WHEN end_at IS NULL THEN 'active' ELSE 'resolved' END, datetime(start_at, 'unixepoch'), '', COALESCE(start_at, strftime('%s', 'now')) FROM maintenance; -- Migrate outages to incidents INSERT INTO incidents (title, status, date, node_ids, created_at) SELECT COALESCE(description, 'Service Outage'), CASE WHEN status = 'resolved' THEN 'resolved' WHEN end_at = '' THEN 'investigating' ELSE 'monitoring' END, start_at, node_id, COALESCE(strftime('%s', start_at), strftime('%s', 'now')) FROM outages; DROP TABLE IF EXISTS maintenance; DROP TABLE IF EXISTS outages; PRAGMA foreign_keys = ON; EOF echo "✓ Merged into incidents" else echo "Skipped status table merge" fi else echo "Skipped (incidents table has data or no maintenance/outage data)" fi echo "" echo "=== Phase 3: Vacuum and Optimize ===" sqlite3 "$DB" <<'EOF' VACUUM; ANALYZE; EOF echo "✓ Database optimized" echo "" echo "=== Final State ===" sqlite3 "$DB" ".tables" echo "" echo "=== Remaining Tables ===" cat <<'TABLEDOCS' CORE TABLES: - pops: 21 regional POPs (source of truth) - telemetry: 676k+ metrics records (operational data) - uptime: Daily status per POP (status page) - uptime_daily: Aggregated daily uptime (351 records) - uptime_spans: Continuous uptime spans (66 records) - domain_scopes: 634 domain mappings (feature in use) - maintenance: Maintenance windows (149 records) OR merged - outages: Outage records (1 record) OR merged - incidents: Consolidated incidents - incident_updates: Incident timeline - accounts: 2 accounts (evaluate if needed) DROPPED: - login_codes - ephemeral verification codes - sessions - ephemeral web sessions - vaults - obsolete hosted vault feature TABLEDOCS echo "" echo "=== Done ===" echo "Backup: $BACKUP" echo "" echo "To restore: cp $BACKUP $DB"