From b75da7df732e6d2ee0c6ae379dd3e281eabd4208 Mon Sep 17 00:00:00 2001 From: Ashad Qureshi Date: Fri, 13 Jun 2025 21:55:04 +0500 Subject: [PATCH] Toggle is now Tick/Checkmark --- auto-analyst-backend/Dockerfile | 9 +- auto-analyst-backend/Housing.xlsx | Bin 30112 -> 0 bytes auto-analyst-backend/chat_database.db | 4 +- .../cleaned_property_data.csv | 3 - auto-analyst-backend/entrypoint.sh | 89 ++++++++ .../property_price_vs_area.png | 3 - .../scripts/init_production_db.py | 191 ++++++++++++++++++ .../custom-templates/TemplateCard.tsx | 24 ++- 8 files changed, 304 insertions(+), 19 deletions(-) delete mode 100644 auto-analyst-backend/Housing.xlsx delete mode 100644 auto-analyst-backend/cleaned_property_data.csv create mode 100644 auto-analyst-backend/entrypoint.sh delete mode 100644 auto-analyst-backend/property_price_vs_area.png create mode 100644 auto-analyst-backend/scripts/init_production_db.py diff --git a/auto-analyst-backend/Dockerfile b/auto-analyst-backend/Dockerfile index 480e44ca..d373f797 100644 --- a/auto-analyst-backend/Dockerfile +++ b/auto-analyst-backend/Dockerfile @@ -10,4 +10,11 @@ COPY --chown=user ./requirements.txt requirements.txt RUN pip install --no-cache-dir --upgrade -r requirements.txt COPY --chown=user . /app -CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"] \ No newline at end of file + +# Make entrypoint script executable +USER root +RUN chmod +x /app/entrypoint.sh +USER user + +# Use the entrypoint script instead of directly running uvicorn +CMD ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/auto-analyst-backend/Housing.xlsx b/auto-analyst-backend/Housing.xlsx deleted file mode 100644 index 86b99de34e34d3128f93432fc408d901fdff6848..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30112 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 bool: + """Check if a table exists in the database.""" + try: + inspector = inspect(engine) + tables = inspector.get_table_names() + return table_name in tables + except Exception as e: + logger.log_message(f"Error checking table existence: {e}", logging.ERROR) + return False + +def verify_database_schema(): + """Verify that all required tables exist. Only create tables on SQLite.""" + db_type = get_database_type() + logger.log_message(f"๐Ÿ” Verifying database schema for {db_type.upper()} database...", logging.INFO) + + required_tables = [ + 'users', 'chats', 'messages', 'model_usage', 'code_executions', + 'message_feedback', 'deep_analysis_reports', 'agent_templates', + 'user_template_preferences' + ] + + missing_tables = [] + existing_tables = [] + + for table in required_tables: + if not check_table_exists(table): + missing_tables.append(table) + logger.log_message(f"โŒ Missing table: {table}", logging.WARNING) + else: + existing_tables.append(table) + logger.log_message(f"โœ… Table exists: {table}", logging.INFO) + + if missing_tables: + if db_type == "sqlite": + logger.log_message(f"๐Ÿ”ง Creating missing tables on SQLite: {missing_tables}", logging.INFO) + try: + # Safe to create tables on SQLite + Base.metadata.create_all(engine) + logger.log_message("โœ… All tables created successfully on SQLite", logging.INFO) + except Exception as e: + logger.log_message(f"โŒ Failed to create tables: {e}", logging.ERROR) + raise + else: + # PostgreSQL/RDS - DO NOT create tables automatically + logger.log_message(f"โš ๏ธ WARNING: Missing tables detected in {db_type.upper()} database: {missing_tables}", logging.WARNING) + logger.log_message("๐Ÿ›ก๏ธ SAFETY: Not creating tables automatically on PostgreSQL/RDS", logging.INFO) + logger.log_message("๐Ÿ“‹ Please ensure these tables exist in your RDS database:", logging.INFO) + for table in missing_tables: + logger.log_message(f" - {table}", logging.INFO) + + # Continue without failing - the app might still work with existing tables + if 'agent_templates' in missing_tables or 'user_template_preferences' in missing_tables: + logger.log_message("โš ๏ธ Template functionality may not work without agent_templates and user_template_preferences tables", logging.WARNING) + else: + logger.log_message(f"โœ… All required tables exist in {db_type.upper()} database", logging.INFO) + +def verify_template_data(): + """Verify that agent templates are populated. Safe for all database types.""" + logger.log_message("๐Ÿ“‹ Verifying template data...", logging.INFO) + + session = session_factory() + try: + # Check if agent_templates table exists before querying + if not check_table_exists('agent_templates'): + logger.log_message("โš ๏ธ agent_templates table does not exist, skipping template verification", logging.WARNING) + return + + template_count = session.query(AgentTemplate).filter(AgentTemplate.is_active == True).count() + logger.log_message(f"๐Ÿ“Š Found {template_count} active templates", logging.INFO) + + if template_count == 0: + logger.log_message("๐Ÿ”ง No templates found, populating...", logging.INFO) + try: + populate_templates() + + # Verify population worked + new_count = session.query(AgentTemplate).filter(AgentTemplate.is_active == True).count() + logger.log_message(f"โœ… Templates populated. Total active templates: {new_count}", logging.INFO) + except Exception as e: + logger.log_message(f"โŒ Template population failed: {e}", logging.ERROR) + logger.log_message("โš ๏ธ App will continue but template functionality may not work", logging.WARNING) + else: + logger.log_message("โœ… Templates already populated", logging.INFO) + + except Exception as e: + logger.log_message(f"โŒ Error verifying templates: {e}", logging.ERROR) + logger.log_message("โš ๏ธ Template verification failed, but app will continue", logging.WARNING) + finally: + session.close() + +def test_template_api_functionality(): + """Test that template-related database operations work. Safe for all database types.""" + logger.log_message("๐Ÿงช Testing template API functionality...", logging.INFO) + + session = session_factory() + try: + # Check if agent_templates table exists before testing + if not check_table_exists('agent_templates'): + logger.log_message("โš ๏ธ agent_templates table does not exist, skipping API test", logging.WARNING) + return + + # Test basic template query + templates = session.query(AgentTemplate).filter(AgentTemplate.is_active == True).limit(5).all() + logger.log_message(f"โœ… Successfully queried {len(templates)} templates", logging.INFO) + + if templates: + sample_template = templates[0] + logger.log_message(f"๐Ÿ“„ Sample template: {sample_template.template_name} - {sample_template.display_name}", logging.INFO) + else: + logger.log_message("๐Ÿ“ญ No templates found in database", logging.INFO) + + except Exception as e: + logger.log_message(f"โŒ Template API test failed: {e}", logging.ERROR) + logger.log_message("โš ๏ธ Template API may not work properly", logging.WARNING) + finally: + session.close() + +def run_safe_initialization(): + """Run safe database initialization that respects production databases.""" + db_type = get_database_type() + logger.log_message(f"๐Ÿš€ Starting SAFE database initialization for {db_type.upper()}...", logging.INFO) + + if db_type == "postgresql": + logger.log_message("๐Ÿ›ก๏ธ PostgreSQL/RDS detected - running in SAFE mode", logging.INFO) + logger.log_message("๐Ÿ“‹ Will only verify schema and populate templates", logging.INFO) + elif db_type == "sqlite": + logger.log_message("๐Ÿ’ฝ SQLite detected - full initialization mode", logging.INFO) + + try: + # Step 1: Initialize database (safe for all types) + logger.log_message("Step 1: Basic database initialization", logging.INFO) + if db_type == "sqlite": + init_db() # Only run full init on SQLite + else: + logger.log_message("Skipping init_db() for PostgreSQL (safety)", logging.INFO) + + # Step 2: Verify schema (safe - only creates tables on SQLite) + logger.log_message("Step 2: Schema verification", logging.INFO) + verify_database_schema() + + # Step 3: Verify template data (safe for all types) + logger.log_message("Step 3: Template data verification", logging.INFO) + verify_template_data() + + # Step 4: Test functionality (safe for all types) + logger.log_message("Step 4: Functionality testing", logging.INFO) + test_template_api_functionality() + + logger.log_message(f"๐ŸŽ‰ Safe database initialization completed for {db_type.upper()}!", logging.INFO) + + except Exception as e: + logger.log_message(f"๐Ÿ’ฅ Database initialization failed: {e}", logging.ERROR) + logger.log_message("โš ๏ธ App may still start but some features might not work", logging.WARNING) + # Don't raise - let the app try to start anyway + +if __name__ == "__main__": + run_safe_initialization() \ No newline at end of file diff --git a/auto-analyst-frontend/components/custom-templates/TemplateCard.tsx b/auto-analyst-frontend/components/custom-templates/TemplateCard.tsx index e191b4b7..0b3e6b34 100644 --- a/auto-analyst-frontend/components/custom-templates/TemplateCard.tsx +++ b/auto-analyst-frontend/components/custom-templates/TemplateCard.tsx @@ -1,7 +1,6 @@ import React from 'react' import { motion } from 'framer-motion' -import { Sparkles, Lock, TrendingUp } from 'lucide-react' -import { Switch } from '../ui/switch' +import { Sparkles, Lock, TrendingUp, Check } from 'lucide-react' import { Badge } from '../ui/badge' import { TemplateAgent, TemplatePreference } from './types' @@ -24,9 +23,9 @@ export default function TemplateCard({ // Premium-only templates are only toggleable by premium users (hasAccess = true for premium) const canToggle = hasAccess - const handleToggle = (checked: boolean) => { + const handleClick = () => { if (canToggle) { - onToggleChange(template.template_id, checked) + onToggleChange(template.template_id, !isEnabled) } } @@ -106,15 +105,20 @@ export default function TemplateCard({ - {/* Toggle switch */} + {/* Checkmark selector */}
- + className={`w-6 h-6 rounded-md border-2 flex items-center justify-center transition-all duration-200 ${ + isEnabled + ? 'bg-[#FF7F7F] border-[#FF7F7F] text-white' + : 'border-gray-300 hover:border-[#FF7F7F] bg-white' + } ${!canToggle ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer hover:scale-105'}`} + > + {isEnabled && } +