Spaces:
Sleeping
Sleeping
| """ | |
| DB Error Detector — connectivity, schema, required columns. | |
| """ | |
| from __future__ import annotations | |
| from typing import List | |
| from ..base import ErrorDetector, DetectionResult | |
| from backend.utils.insforge_db import get_db, execute_one | |
| REQUIRED_COLUMNS = [ | |
| "id", "event_id", "student_id", | |
| "submitted_at", "session_rating" | |
| ] | |
| REQUIRED_TABLES = ["feedback_responses", "events"] | |
| class DBErrorDetector(ErrorDetector): | |
| page = "database" | |
| def __init__(self, db_path: str): | |
| self.db_path = db_path | |
| def run(self) -> List[DetectionResult]: | |
| results = [] | |
| # 1. Connectivity | |
| try: | |
| execute_one("SELECT 1") | |
| results.append(self._ok("connectivity", "Database connection successful")) | |
| except Exception as e: | |
| results.append(self._critical("connectivity", "Cannot connect to database", str(e))) | |
| return results # No point running further checks | |
| # 2. Required tables | |
| try: | |
| with get_db() as conn: | |
| with conn.cursor() as cursor: | |
| cursor.execute("SELECT table_name FROM information_schema.tables WHERE table_schema='public'") | |
| existing = {row["table_name"] for row in cursor.fetchall()} | |
| for tbl in REQUIRED_TABLES: | |
| if tbl in existing: | |
| results.append(self._ok("table_exists", f"Table '{tbl}' exists")) | |
| else: | |
| results.append(self._critical("table_exists", f"Required table '{tbl}' missing")) | |
| except Exception as e: | |
| results.append(self._critical("table_schema", "Failed to read table list", str(e))) | |
| return results | |
| # 3. Required columns | |
| try: | |
| with get_db() as conn: | |
| with conn.cursor() as cursor: | |
| cursor.execute("SELECT column_name FROM information_schema.columns WHERE table_name = 'feedback_responses'") | |
| cols = {row["column_name"] for row in cursor.fetchall()} | |
| missing = [c for c in REQUIRED_COLUMNS if c not in cols] | |
| if missing: | |
| results.append(self._warn("required_columns", | |
| f"Missing columns: {', '.join(missing)}", | |
| "Some features may not work correctly")) | |
| else: | |
| results.append(self._ok("required_columns", "All required columns present")) | |
| except Exception as e: | |
| results.append(self._warn("required_columns", "Could not verify columns", str(e))) | |
| # 4. Row count sanity | |
| try: | |
| res = execute_one("SELECT COUNT(*) as count FROM feedback_responses") | |
| count = res["count"] if res else 0 | |
| if count == 0: | |
| results.append(self._warn("row_count", "feedback_responses table is empty")) | |
| else: | |
| results.append(self._ok("row_count", f"{count} rows in feedback_responses")) | |
| except Exception as e: | |
| results.append(self._warn("row_count", "Could not count rows", str(e))) | |
| return results | |