Add brand analysis columns to onboarding database and migration scripts
This commit is contained in:
82
backend/scripts/add_brand_analysis_columns.py
Normal file
82
backend/scripts/add_brand_analysis_columns.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""
|
||||
Add brand_analysis and content_strategy_insights columns to website_analyses table.
|
||||
These columns store rich brand insights and SWOT analysis from Step 2.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
from loguru import logger
|
||||
|
||||
# Add parent directory to path
|
||||
sys.path.append(str(Path(__file__).parent.parent))
|
||||
|
||||
from sqlalchemy import text, inspect
|
||||
from services.database import SessionLocal, engine
|
||||
|
||||
|
||||
def add_brand_analysis_columns():
|
||||
"""Add brand_analysis and content_strategy_insights columns if they don't exist."""
|
||||
|
||||
db = SessionLocal()
|
||||
|
||||
try:
|
||||
# Check if columns already exist
|
||||
inspector = inspect(engine)
|
||||
columns = [col['name'] for col in inspector.get_columns('website_analyses')]
|
||||
|
||||
brand_analysis_exists = 'brand_analysis' in columns
|
||||
content_strategy_insights_exists = 'content_strategy_insights' in columns
|
||||
|
||||
if brand_analysis_exists and content_strategy_insights_exists:
|
||||
logger.info("✅ Columns already exist. No migration needed.")
|
||||
return True
|
||||
|
||||
logger.info("🔄 Starting migration to add brand analysis columns...")
|
||||
|
||||
# Add brand_analysis column if missing
|
||||
if not brand_analysis_exists:
|
||||
logger.info("Adding brand_analysis column...")
|
||||
db.execute(text("""
|
||||
ALTER TABLE website_analyses
|
||||
ADD COLUMN brand_analysis JSON
|
||||
"""))
|
||||
logger.success("✅ Added brand_analysis column")
|
||||
|
||||
# Add content_strategy_insights column if missing
|
||||
if not content_strategy_insights_exists:
|
||||
logger.info("Adding content_strategy_insights column...")
|
||||
db.execute(text("""
|
||||
ALTER TABLE website_analyses
|
||||
ADD COLUMN content_strategy_insights JSON
|
||||
"""))
|
||||
logger.success("✅ Added content_strategy_insights column")
|
||||
|
||||
db.commit()
|
||||
logger.success("🎉 Migration completed successfully!")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Migration failed: {e}")
|
||||
db.rollback()
|
||||
return False
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("=" * 60)
|
||||
logger.info("DATABASE MIGRATION: Add Brand Analysis Columns")
|
||||
logger.info("=" * 60)
|
||||
|
||||
success = add_brand_analysis_columns()
|
||||
|
||||
if success:
|
||||
logger.success("\n✅ Migration completed successfully!")
|
||||
logger.info("The website_analyses table now includes:")
|
||||
logger.info(" - brand_analysis: Brand voice, values, positioning")
|
||||
logger.info(" - content_strategy_insights: SWOT analysis, recommendations")
|
||||
else:
|
||||
logger.error("\n❌ Migration failed. Please check the error messages above.")
|
||||
sys.exit(1)
|
||||
|
||||
129
backend/scripts/migrate_user_id_to_string.py
Normal file
129
backend/scripts/migrate_user_id_to_string.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
Migration Script: Update onboarding_sessions.user_id from INTEGER to STRING
|
||||
This script updates the database schema to support Clerk user IDs (strings)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from loguru import logger
|
||||
from sqlalchemy import text
|
||||
from services.database import SessionLocal, engine
|
||||
|
||||
def migrate_user_id_column():
|
||||
"""Migrate user_id column from INTEGER to VARCHAR(255)."""
|
||||
try:
|
||||
db = SessionLocal()
|
||||
|
||||
logger.info("Starting migration: user_id INTEGER -> VARCHAR(255)")
|
||||
|
||||
# Check if table exists (SQLite compatible)
|
||||
check_table_query = """
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name='onboarding_sessions';
|
||||
"""
|
||||
|
||||
result = db.execute(text(check_table_query))
|
||||
table_exists = result.scalar()
|
||||
|
||||
if not table_exists:
|
||||
logger.warning("Table 'onboarding_sessions' does not exist. Creating it instead.")
|
||||
# Create tables using the updated models
|
||||
from models.onboarding import Base
|
||||
Base.metadata.create_all(bind=engine, checkfirst=True)
|
||||
logger.success("✅ Created onboarding_sessions table with VARCHAR user_id")
|
||||
return True
|
||||
|
||||
# Check current column type (SQLite compatible)
|
||||
check_column_query = """
|
||||
SELECT type FROM pragma_table_info('onboarding_sessions')
|
||||
WHERE name = 'user_id';
|
||||
"""
|
||||
|
||||
result = db.execute(text(check_column_query))
|
||||
current_type = result.scalar()
|
||||
|
||||
if current_type and 'varchar' in current_type.lower():
|
||||
logger.info(f"✅ Column user_id is already VARCHAR ({current_type}). No migration needed.")
|
||||
return True
|
||||
|
||||
logger.info(f"Current user_id type: {current_type}")
|
||||
|
||||
# Backup existing data count
|
||||
count_query = "SELECT COUNT(*) FROM onboarding_sessions;"
|
||||
result = db.execute(text(count_query))
|
||||
record_count = result.scalar()
|
||||
logger.info(f"Found {record_count} existing records")
|
||||
|
||||
if record_count > 0:
|
||||
logger.warning("⚠️ Found existing records. Backing up data...")
|
||||
# You may want to add backup logic here if needed
|
||||
|
||||
# SQLite doesn't support ALTER COLUMN TYPE directly
|
||||
# We need to recreate the table
|
||||
logger.info("Recreating table with VARCHAR user_id (SQLite limitation)...")
|
||||
|
||||
# Backup data
|
||||
logger.info("Backing up existing data...")
|
||||
backup_query = """
|
||||
CREATE TABLE onboarding_sessions_backup AS
|
||||
SELECT * FROM onboarding_sessions;
|
||||
"""
|
||||
db.execute(text(backup_query))
|
||||
db.commit()
|
||||
|
||||
# Drop old table
|
||||
logger.info("Dropping old table...")
|
||||
db.execute(text("DROP TABLE onboarding_sessions;"))
|
||||
db.commit()
|
||||
|
||||
# Recreate table with correct schema
|
||||
logger.info("Creating new table with VARCHAR user_id...")
|
||||
from models.onboarding import Base
|
||||
Base.metadata.create_all(bind=engine, tables=[Base.metadata.tables['onboarding_sessions']], checkfirst=False)
|
||||
db.commit()
|
||||
|
||||
# Restore data (converting integers to strings)
|
||||
logger.info("Restoring data...")
|
||||
restore_query = """
|
||||
INSERT INTO onboarding_sessions (id, user_id, current_step, progress, started_at, updated_at)
|
||||
SELECT id, CAST(user_id AS TEXT), current_step, progress, started_at, updated_at
|
||||
FROM onboarding_sessions_backup;
|
||||
"""
|
||||
db.execute(text(restore_query))
|
||||
db.commit()
|
||||
|
||||
# Drop backup table
|
||||
logger.info("Cleaning up backup table...")
|
||||
db.execute(text("DROP TABLE onboarding_sessions_backup;"))
|
||||
db.commit()
|
||||
|
||||
logger.success("✅ Table recreated successfully")
|
||||
|
||||
logger.success("🎉 Migration completed successfully!")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Migration failed: {e}")
|
||||
if db:
|
||||
db.rollback()
|
||||
return False
|
||||
finally:
|
||||
if db:
|
||||
db.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("="*60)
|
||||
logger.info("DATABASE MIGRATION: user_id INTEGER -> VARCHAR(255)")
|
||||
logger.info("="*60)
|
||||
|
||||
success = migrate_user_id_column()
|
||||
|
||||
if success:
|
||||
logger.success("\n✅ Migration completed successfully!")
|
||||
logger.info("The onboarding system now supports Clerk user IDs (strings)")
|
||||
else:
|
||||
logger.error("\n❌ Migration failed. Please check the logs above.")
|
||||
sys.exit(1)
|
||||
|
||||
73
backend/scripts/verify_current_user_data.py
Normal file
73
backend/scripts/verify_current_user_data.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
Verify current user data in the database
|
||||
Check if data is being saved with Clerk user IDs
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from loguru import logger
|
||||
from services.database import SessionLocal
|
||||
from models.onboarding import OnboardingSession, APIKey, WebsiteAnalysis, ResearchPreferences
|
||||
|
||||
def verify_user_data():
|
||||
"""Check what user_id format is being used."""
|
||||
try:
|
||||
db = SessionLocal()
|
||||
|
||||
logger.info("Checking onboarding_sessions table...")
|
||||
sessions = db.query(OnboardingSession).all()
|
||||
|
||||
logger.info(f"Found {len(sessions)} sessions:")
|
||||
for session in sessions:
|
||||
logger.info(f" Session ID: {session.id}")
|
||||
logger.info(f" User ID: {session.user_id} (type: {type(session.user_id).__name__})")
|
||||
logger.info(f" Current Step: {session.current_step}")
|
||||
logger.info(f" Progress: {session.progress}%")
|
||||
|
||||
# Check API keys for this session
|
||||
api_keys = db.query(APIKey).filter(APIKey.session_id == session.id).all()
|
||||
logger.info(f" API Keys: {len(api_keys)} found")
|
||||
for key in api_keys:
|
||||
logger.info(f" - {key.provider}")
|
||||
|
||||
# Check website analysis
|
||||
website = db.query(WebsiteAnalysis).filter(WebsiteAnalysis.session_id == session.id).first()
|
||||
if website:
|
||||
logger.info(f" Website Analysis: {website.website_url}")
|
||||
else:
|
||||
logger.info(f" Website Analysis: None")
|
||||
|
||||
# Check research preferences
|
||||
research = db.query(ResearchPreferences).filter(ResearchPreferences.session_id == session.id).first()
|
||||
if research:
|
||||
logger.info(f" Research Preferences: Found")
|
||||
else:
|
||||
logger.info(f" Research Preferences: None")
|
||||
|
||||
logger.info("")
|
||||
|
||||
if len(sessions) == 0:
|
||||
logger.warning("⚠️ No sessions found in database!")
|
||||
logger.info("This means either:")
|
||||
logger.info(" 1. No onboarding data has been saved yet")
|
||||
logger.info(" 2. Data was cleared during migration")
|
||||
logger.info("\nYou need to go through onboarding steps 1-5 again to save data with Clerk user ID")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error verifying data: {e}")
|
||||
return False
|
||||
finally:
|
||||
if db:
|
||||
db.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("="*60)
|
||||
logger.info("VERIFY CURRENT USER DATA IN DATABASE")
|
||||
logger.info("="*60)
|
||||
|
||||
verify_user_data()
|
||||
|
||||
Reference in New Issue
Block a user