{
    "title": "Database Layer & SQLite Mock",
    "description": "Chi tiết về cách hệ thống xử lý dữ liệu đồng bộ và bất đồng bộ, cùng cơ chế SQLite Mock để giả lập Postgres trong môi trường phát triển.",
    "diagram": "diagrams/database-layer.svg",
    "sections": [
        {
            "title": "1. Tổng quan (Overview)",
            "type": "text",
            "content": "Module Database cung cấp một lớp <b>Wrapper</b> thông minh để ứng dụng có thể chạy mượt mà trên cả môi trường <b>Local (SQLite)</b> và <b>Production (Postgres/StarRocks)</b> mà không cần phải viết lại các câu SQL query. Nó đặc biệt hữu ích khi Dev muốn debug thuật toán phối đồ (Fashion Match) hoặc luồng sinh mô tả (Ultra Description) tại máy cá nhân mà không có kết nối tới Data Warehouse."
        },
        {
            "title": "2. Kiến trúc & Luồng dữ liệu (Data Flow)",
            "type": "text",
            "content": "Luồng kết nối Database chia thành hai hướng chính (Sync và Async):<br><br><b>A. Async Path (Tuyến chính):</b> Sử dụng <code>aiosqlite</code> (nếu chạy local) hoặc <code>aiomysql / asyncpg</code> (trên Prod). Luồng này được dùng trực tiếp ở các FastAPI route hiện đại, đảm bảo tốc độ cao, không block thread.<br><b>B. Sync Path (Tuyến Legacy):</b> Vẫn sử dụng code tuần tự. Để tương thích với các Class cũ như <code>UltraDescDB</code>, hệ thống sinh ra một lớp <code>MockCursor</code> để bọc và \"giả lập\" hành vi của psycopg2."
        },
        {
            "title": "3. Core Logic: Cơ chế SQL Translation",
            "type": "text",
            "content": "Vì cú pháp SQL của Postgres và SQLite khác nhau, file <code>sqlite_mock.py</code> đóng vai trò là một <b>SQL Interceptor</b>, nó chặn các câu query được gửi từ code Python, biên dịch lại rồi mới đẩy xuống SQLite. Các quy tắc chính bao gồm:<br>- Thay placeholder <code>%s</code> thành <code>?</code><br>- Thay schema name: ví dụ <code>public.users</code> -> <code>pg__public__users</code><br>- Định dạng lại cấu trúc JSON: map các hàm như <code>ANY_VALUE()</code> sang <code>MIN()</code>."
        },
        {
            "title": "4. Core Logic: Connection Pool & Thundering Herd Protection",
            "type": "text",
            "content": "Hệ thống triển khai <b>Exponential Backoff</b> bên trong <code>pool_wrapper.py</code>. Khi Postgres chập chờn hoặc khởi động lại, thay vì hàng nghìn requests dội vào xin kết nối cùng lúc gây chết DB (Thundering herd), hệ thống sẽ chủ động ngắt connection lỗi và sleep tăng dần thời gian (<code>time.sleep(0.1 * (2 ** attempt))</code>) trước khi thử lại."
        },
        {
            "title": "5. Code Snippet Thực Tế (pool_wrapper.py)",
            "type": "code",
            "language": "python",
            "code": "from common.pool_wrapper import get_pooled_connection_compat\nimport time\n\ndef fetch_user_data(user_id):\n    # Connection pool tự động handle fallback và backoff\n    for attempt in range(3):\n        try:\n            with get_pooled_connection_compat() as conn:\n                with conn.cursor() as cur:\n                    # Lớp Mock sẽ tự động dịch `%s` thành `?` nếu chạy Local SQLite\n                    cur.execute(\"SELECT * FROM public.users WHERE id = %s\", (user_id,))\n                    return cur.fetchone()\n        except Exception as e:\n            time.sleep(0.1 * (2 ** attempt))  # Exponential Backoff\n    return None"
        },
        {
            "title": "6. Troubleshooting & Gotchas",
            "type": "text",
            "content": "<b>🚫 Lỗi `sqlite3.OperationalError: no such table`</b><br>Khi query các bảng nằm ngoài schema mặc định (ví dụ schema <code>canifa_ai</code>), bạn phải đảm bảo đã import data vào file <code>canifa_ai_dump.sqlite</code> và prefix tên bảng thành <code>canifa_ai__tablename</code>.<br><br><b>🚫 Lỗi khóa DB (Database is locked)</b><br>Do SQLite không hỗ trợ ghi đồng thời tốt như Postgres, nếu có nhiều Background Tasks hoặc Async Coroutines cùng thực thi lệnh <code>UPDATE</code> / <code>INSERT</code>, SQLite sẽ báo lỗi locked. Để giảm thiểu, luôn dùng <code>with conn:</code> để commit/rollback tự động và trả kết nối về pool nhanh nhất có thể."
        }
    ]
}
