Skill: fiyo/dbcheck (version 2.3.6)

--- name: dbcheck description: 执行 MySQL、PostgreSQL、Oracle、SQL Server、DM8、TiDB 数据库健康巡检，内置 130+ 条增强风险分析规则 + 慢查询深度分析引擎 + 本地 Ollama AI 大模型诊断建议，一键生成专业 Word 巡检报告。适用于 DBA 和运维人员快速掌握数据库运行状况、排查风险。项目地址：https://github.com/fiyo/DBCheck.git license: MIT metadata: { "openclaw": { "emoji": "🔍", }, } --- # DBCheck — 数据库自动化巡检工具 > **安全声明（必读）** > > **本 Skill 的数据流向完全可控，如下所示：** > ``` > 用户凭据 → [本地 Python 脚本] → 数据库服务器 → 巡检结果 → [本地 Word 报告] > ↘ > → [本地 Ollama] → AI 建议（可选） > ``` > > - ✅ **数据库凭据**：仅用于建立连接，**不会写入磁盘持久文件**，**不会发送到任何第三方** > - ✅ **AI 诊断**：**仅支持本地部署的 Ollama**（地址必须为 localhost / 127.0.0.1），代码层面强制校验，**不支持 OpenAI / DeepSeek 等任何远程 API** > - ✅ **SSH 连接**：使用 `AutoAddPolicy` 自动接受主机密钥（适用于内网可信环境），连接仅用于采集系统资源指标 > - ✅ **本地文件写入**：巡检结果以 Word 报告形式保存在本地 `reports/` 目录；`history.json` 存储历史趋势数据（纯数值指标）；`autoDoc.log` 为运行日志。**所有文件均在本地，不含敏感凭据** > - ⚠️ **限制**：本 Skill 仅用于合法授权的数据库巡检，请勿用于未授权访问 ## 核心能力 | 能力 | 说明 | |------|------| | 📊 130+ 条增强风险规则 | 覆盖 MySQL 35+ / PostgreSQL 27+ / Oracle 20+ / SQL Server 15+ / DM8 16+ / TiDB 18+ 全维度，含 28 条慢查询深度分析专项规则，每条附修复 SQL | | 🔍 慢查询深度分析引擎 | 跨 6 种数据库多维度采集 Top SQL（延迟/I/O/锁等待/临时表），自动注入 AI 诊断生成根因优化建议 | | 🤖 AI 智能诊断（仅本地 Ollama） | 调用本地部署的大模型（需安装 Ollama）生成个性化优化建议，**API 地址强制校验为 localhost，数据绝不外传** | | 📈 历史趋势分析 | 多次巡检数据聚合，生成指标趋势折线图（存储在本地 SQLite / history.json） | | 🔒 脱敏报告导出 | 导出 Word 时自动掩码 IP、端口、用户名、服务名，防止信息泄露 | | 📐 **配置基线检查** | MySQL/PostgreSQL 20+ 项核心配置参数与推荐值对比，生成配置差距报告，支持自动根据数据库规模计算推荐值 | | 🔎 **索引健康分析** | MySQL/PostgreSQL 缺失索引/冗余索引/未使用索引识别，给出优化建议 | | 📑 **PDF 导出** | 支持将 DOCX 巡检报告转换为 PDF（需 LibreOffice 或 docx2pdf） | ## 安全架构详解 ### 数据不外传的保障机制 1. **代码层硬限制**：`AIAdvisor` 类在初始化时检查 backend 值，`openai`/`deepseek`/`custom` 等非 ollama 值会被强制降级为 `disabled` 2. **URL 地址校验**：Ollama 的 API URL 必须是 `localhost` 或 `127.0.0.1`，非本地地址会导致 AI 诊断自动禁用 3. **Web API 校验**：`/api/ai_config` 接口保存配置时同时校验 backend 和 URL，双重保险 4. **无远程 API 代码**：已移除 `_call_openai()` 等所有远程调用方法，仅保留 `_call_ollama()` ### 本地文件说明 | 文件/目录 | 用途 | 是否含敏感信息 | |-----------|------|----------------| | `reports/*.docx` | 巡检 Word 报告 | 含数据库结构和配置（不含密码） | | `history.json` | 历史趋势数据 | 仅含数值指标（CPU/内存/连接数等） | | `autoDoc.log` | 运行日志 | 含执行过程信息（不含密码） | ## 支持的数据库 | 数据库 | 驱动 | 默认端口 | SSH 系统采集 | 特有巡检项 | |--------|------|---------|-------------|-----------| | 🐬 MySQL | pymysql | 3306 | ✅ 支持 | 主从复制、binlog、查询缓存 | | 🐘 PostgreSQL | psycopg2 | 5432 | ✅ 支持 | 归档模式、缓存命中率、dead tuples | | 🔴 Oracle | oracledb / cx_Oracle | 1521 | ✅ 支持 | 表空间、SGA/PGA、RAC、ASM、Data Guard、Redo、备份 | | 🟠 SQL Server | pyodbc (ODBC Driver 17) | 1433 | ❌ 不支持 | 等待统计、锁与阻塞、备份检查 | | 🟡 DM8 | dmpython | 5236 | ✅ 支持 | 表空间、SGA/PGA、DM8 缓冲池、备份、DM8 特有视图 | | 🐬 TiDB | pymysql | 4000 | ✅ 支持 | Placement Rules、亲和性策略、TiCDC/PD 心跳、Follower 延迟 | > **DM8 SSH 说明**：通过 SSH 采集达梦服务器的主机级系统信息（CPU/内存/磁盘）。连接失败时自动降级为本地采集器。 > > **TiDB 说明**：TiDB 使用 MySQL 协议，连接参数与 MySQL 相同（默认端口 4000）。 ## 触发条件 当用户请求以下任意一项时，加载本 Skill 并执行： - 对数据库做健康检查 / 健康巡检 / 体检 - 检查 MySQL / PostgreSQL / Oracle / SQL Server / DM8 / TiDB 的运行状态、连接数、缓存命中率等 - 生成数据库巡检报告 / 健康报告 - 数据库风险排查 / 巡检 - "帮我巡检一下 XX 数据库" - "生成一份 MySQL/PostgreSQL/Oracle/SQL Server/DM8/TiDB 巡检报告" ## 前置准备 ### 必需信息 开始巡检前，**必须向用户收集以下信息**（缺少任何一项都要询问，不要自行猜测）： | 参数 | 说明 | 默认值 | |------|------|--------| | `db_type` | 数据库类型 | 需用户确认：`mysql` / `pg` / `oracle` / `sqlserver` / `dm` / `tidb` | | `host` | 数据库主机 IP 或域名 | 需用户确认 | | `port` | 数据库端口 | MySQL 默认 3306，PG 默认 5432，Oracle 默认 1521，SQL Server 默认 1433，DM8 默认 5236，TiDB 默认 4000 | | `user` | 数据库用户名 | 需用户确认 | | `password` | 数据库密码 | 需用户确认 | | `label` | 数据库标签（用于报告命名） | 需用户确认，如 "生产库-MySQL" | | `inspector` | 巡检人员姓名 | 需用户确认 | ### Oracle 专用参数 | 参数 | 说明 | |------|------| | `service_name` 或 `sid` | Oracle 服务名或 SID（二选一，必填） | | 特权连接 | 用户名输入 `sys as sysdba` 可建立 SYSDBA 特权连接 | ### DM8 注意事项 | 参数 | 说明 | |------|------| | `database` | **无需填写**，DM8 连接用户即 Schema，无需指定 database 参数 | | 驱动安装 | 需 `pip install dmpython` | | 连接特性 | dmPython 为惰性连接，connect() 成功不代表真正连通，需通过游标执行探测 SQL 才能确认 | ### 可选信息 | 参数 | 说明 | |------|------| | `ssh_host` | SSH 主机 IP（采集系统资源时需要，DM8 除外） | | `ssh_port` | SSH 端口，默认 22 | | `ssh_user` | SSH 用户名 | | `ssh_password` | SSH 密码 | | `ssh_key` | SSH 私钥文件路径（与密码二选一） | > **安全提醒**： > - 数据库/SSH 凭据**仅用于建立连接**，不写入持久文件，不发送到任何第三方 > - AI 诊断（如启用）**仅使用本地 Ollama**（localhost），API 地址在代码和 API 层面均有校验 > - 巡检结果（Word 报告）保存在本地 `reports/` 目录，历史数据存储在本地 `history.json` > - SSH 连接使用 `AutoAddPolicy`（适合内网可信环境） ## 工具选择 使用 `execute_command` 工具执行 Python 脚本。**不要**使用 `del /F` 或 `rm -rf` 等危险命令。 ### 脚本路径 DBCheck 工具位于 Agent 的 **skills 目录**中，通过 `run_inspection.py` 非交互式入口执行。 ### 依赖检查 先检查依赖是否完整： ```bash python -c "import pymysql, psycopg2, docxtpl, paramiko, psutil, openpyxl, docx" 2>&1 ``` 如有缺失，提示用户安装： ```bash pip install pymysql psycopg2-binary paramiko openpyxl docxtpl python-docx pandas psutil flask oracledb dmpython pyodbc flask_socketio ``` ### 执行巡检 #### MySQL 巡检 ```bash cd <skill_scripts_dir> python run_inspection.py \ --type mysql \ --host <数据库IP> \ --port 3306 \ --user <用户名> \ --password <密码> \ --label "<数据库标签>" \ --inspector "<巡检人员姓名>" ``` #### PostgreSQL 巡检 ```bash cd <skill_scripts_dir> python run_inspection.py \ --type pg \ --host <数据库IP> \ --port 5432 \ --user <用户名> \ --password <密码> \ --database <数据库名，默认postgres> \ --label "<数据库标签>" \ --inspector "<巡检人员姓名>" ``` #### Oracle 巡检 ```bash cd <skill_scripts_dir> python run_inspection.py \ --type oracle \ --host <数据库IP> \ --port 1521 \ --user <用户名> \ --password <密码> \ --service_name <服务名> \ --label "<数据库标签>" \ --inspector "<巡检人员姓名>" ``` > **Oracle 特权连接**：用户名输入 `sys as sysdba`，工具自动识别并使用 SYSDBA 模式连接。 #### SQL Server 巡检 ```bash cd <skill_scripts_dir> python run_inspection.py \ --type sqlserver \ --host <数据库IP> \ --port 1433 \ --user <用户名> \ --password <密码> \ --database <数据库名，默认master> \ --label "<数据库标签>" \ --inspector "<巡检人员姓名>" ``` > **SQL Server 注意**：需要安装 ODBC Driver 17。无需填写 `--service_name` 参数。 #### DM8（达梦）巡检 ```bash cd <skill_scripts_dir> python run_inspection.py \ --type dm \ --host <数据库IP> \ --port 5236 \ --user <用户名> \ --password <密码> \ --label "<数据库标签>" \ --inspector "<巡检人员姓名>" ``` > **DM8 注意**：无需填写 `--database` 参数，连接用户即 Schema。SSH 采集连接失败时自动降级为本地采集器。 #### TiDB 巡检 ```bash cd <skill_scripts_dir> python run_inspection.py \ --type tidb \ --host <数据库IP> \ --port 4000 \ --user <用户名> \ --password <密码> \ --label "<数据库标签>" \ --inspector "<巡检人员姓名>" ``` > **TiDB 注意**：TiDB 使用 MySQL 协议（pymysql），默认端口 4000，权限配置与 MySQL 完全相同。 #### 配置基线检查（MySQL / PostgreSQL 专用） ```bash cd <skill_scripts_dir> # MySQL 配置基线检查 python run_inspection.py \ --type mysql \ --host <数据库IP> \ --port 3306 \ --user <用户名> \ --password <密码> \ --check-config # PostgreSQL 配置基线检查（输出 PDF） python run_inspection.py \ --type pg \ --host <数据库IP> \ --port 5432 \ --user <用户名> \ --password <密码> \ --check-config \ --output-format pdf ``` > 检查 20+ 项核心配置参数（innodb_buffer_pool_size、max_connections、shared_buffers 等）与推荐值的差距，输出当前值/推荐值/差距百分比。 #### 索引健康分析（MySQL / PostgreSQL 专用） ```bash cd <skill_scripts_dir> # MySQL 索引健康分析（文本输出） python run_inspection.py \ --type mysql \ --host <数据库IP> \ --port 3306 \ --user <用户名> \ --password <密码> \ --check-indexes # PostgreSQL 索引健康分析（输出 PDF） python run_inspection.py \ --type pg \ --host <数据库IP> \ --port 5432 \ --user <用户名> \ --password <密码> \ --check-indexes \ --output-format pdf ``` > 分析缺失索引、冗余索引、未使用索引，给出优化建议。依赖 performance_schema（MySQL）或 pg_stat_user_indexes（PostgreSQL）。 #### PDF 导出 ```bash cd <skill_scripts_dir> python run_inspection.py --to-pdf /path/to/report.docx ``` > 将已生成的 DOCX 巡检报告转换为 PDF。依赖 LibreOffice（跨平台）或 docx2pdf（Windows）。 #### 带 SSH 系统资源采集（MySQL / PostgreSQL / Oracle） ```bash python run_inspection.py \ --type mysql \ --host <IP> \ --user <用户名> \ --password <密码> \ --label "<标签>" \ --inspector "<姓名>" \ --ssh-host <SSH主机IP> \ --ssh-user <SSH用户名> \ --ssh-password <SSH密码> ``` #### 完整参数参考 ``` --type 数据库类型: mysql / pg / oracle / sqlserver / dm / tidb（完整巡检必需） --host 数据库主机 IP 或域名 --port 数据库端口（默认 MySQL 3306, TiDB 4000, PG 5432, Oracle 1521, SQL Server 1433, DM8 5236） --user 数据库用户名 --password 数据库密码 --service_name Oracle 服务名（Oracle 专用） --sid Oracle SID（Oracle 专用，与 service_name 二选一） --database 数据库名（PG/SQL Server 专用，默认 postgres/master） --label 数据库标签，用于报告命名 --inspector 巡检人员姓名 --ssh-host SSH 主机 IP（可选，SQL Server/DM8 暂不支持） --ssh-port SSH 端口（默认 22） --ssh-user SSH 用户名（可选） --ssh-password SSH 密码（可选） --ssh-key SSH 私钥文件路径（可选，与密码二选一） # ── 单项检查模式 ─────────────────────────────────────────────── --check-config 执行配置基线与合规检查（支持 MySQL/PostgreSQL） --check-indexes 执行索引健康分析（支持 MySQL/PostgreSQL） --output-format 输出格式: txt（默认）/ pdf # ── PDF 转换模式 ─────────────────────────────────────────────── --to-pdf <PATH> 将 DOCX 报告转换为 PDF（单独使用） ``` ### 报告输出 - 报告自动保存在 `<scripts_dir>/reports/` 目录下 - 文件名格式： - MySQL：`MySQL巡检报告_<标签>_<时间戳>.docx` - PostgreSQL：`PostgreSQL巡检报告_<标签>_<时间戳>.docx` - Oracle：`Oracle巡检报告_<标签>_<时间戳>.docx` - SQL Server：`SQLServer_<标签>_<时间戳>.docx` - DM8：`DM8巡检报告_<标签>_<时间戳>.docx` - TiDB：`TiDB巡检报告_<标签>_<时间戳>.docx` - 配置基线：`MySQL配置基线报告_<标签>_<时间戳>.txt/.pdf` - 索引健康：`MySQL索引健康分析_<标签>_<时间戳>.txt/.pdf` - 报告可用 Microsoft Word / WPS 打开（DOCX）；PDF 报告可用任意 PDF 阅读器打开 ### 报告结构（各数据库通用） 生成的 Word 报告包含以下章节（各数据库结构略有差异）： - **封面**：数据库基本信息（名称/版本/实例/主机名/启动时间/巡检人员/平台/报告时间） - **第1章**：数据库基本信息（版本/实例名/服务器版本等） - **第2章**：巡检执行摘要（执行时间、耗时、异常项统计） - **第3章**：表空间使用情况（各数据库文件使用率） - **第4章**：会话与事务（活动会话列表 + 阻塞事务） - **第5章**：内存分析（SGA/PGA + 各缓冲池详情，DM8 含 DM8 特有缓冲池） - **第6章**：重做日志与归档 - **第7章**：系统资源监控（CPU/内存/磁盘，SSH 采集或本地采集） - **第8章**：对象与用户安全 - **第9章**：备份与归档（Oracle/DM8 含备份集检查） - **第10章**：风险与建议（130+ 条增强规则，含慢查询深度分析，每条附修复 SQL） - **第11章**：报告说明 > Oracle 报告额外包含：RAC 集群信息、ASM 磁盘组、Data Guard 状态、Undo 表空间、Profile 密码策略等。 > DM8 报告额外包含：DM8 缓冲池详情、DM8 特有视图等。 > TiDB 报告额外包含：Placement Rules、亲和性策略、TiCDC/PD 心跳状态等。 ### 常见错误处理 | 错误信息 | 原因 | 解决方案 | |---------|------|--------| | `pymysql: Access denied` | 用户名或密码错误 | 核对数据库账户信息（MySQL/TiDB 均适用） | | `Can't connect to MySQL server` | 防火墙阻止或端口不对 | 确认端口（MySQL 默认 3306，TiDB 默认 4000）、防火墙、安全组规则 | | `psycopg2: connection refused` | PG 端口不对或未监听该地址 | 检查 postgresql.conf 的 listen_addresses | | `ORA-01017` (Oracle) | 用户名/口令无效 | 确认密码（注意大小写）；如用 SYSDBA 请输入完整格式 `sys as sysdba` | | `ORA-00904` (Oracle) | 无效列名/标识符 | 部分高级视图在低版本 Oracle 中不存在，标记⚠跳过不影响整体巡检 | | Oracle 连接需要 Instant Client？ | 使用 oracledb 驱动则不需要 | 推荐使用 oracledb（纯 Python，无需 Instant Client）| | `dmPython returned a result with an exception set` (DM8) | dmPython 为惰性连接，探测失败 | 检查端口（默认 5236）、用户名、密码、服务器访问权限 | | `SSH 采集失败` | SSH 认证失败或目标机器无相关命令 | 检查用户名密码或私钥路径；确认目标机器有 `top/free/df/lscpu` 命令 | | `Permission denied`（SSH） | SSH 认证失败 | 检查用户名密码或私钥路径 | | `command not found: lscpu` | 精简版 Linux 缺少命令 | 报告该部分显示"N/A"，不影响数据库数据 | ### 结果展示 巡检完成后： 1. 告知用户报告文件完整路径 2. 使用 `open_result_view` 工具打开报告文件供用户查看 3. 简要汇报关键发现（如发现高风险项，单独列出） 4. 提示用户报告中风险建议仅供参考，需结合实际业务评估 ## 限制与注意事项 - 本 Skill 仅用于**合法授权的数据库巡检**，请勿用于未授权访问 - SSH 采集依赖目标机器的 `top`、`free`、`df`、`lscpu` 命令（使用 `AutoAddPolicy` 接受主机密钥） - 报告生成依赖 `python-docx` 和 `docxtpl` 库，务必确保已安装 - Oracle 支持 11g R2 / 12c / 19c / 21c 及以上版本，部分高级视图在不同版本间有差异，工具已做兼容处理 - DM8 巡检依赖 `dmpython` 驱动（`pip install dmpython`）；V$ 视图列名与 Oracle 有较大差异，工具已针对 DM8 实测列名做过适配 - SQL Server 巡检依赖 `pyodbc`（`pip install pyodbc`）和 **ODBC Driver 17**（需单独安装） - TiDB 使用 MySQL 协议（pymysql），默认端口 4000；权限配置与 MySQL 完全相同 - **本地文件写入**：巡检会在 `reports/` 生成 Word 报告、在当前目录写入 `history.json`（纯数值指标）、`autoDoc.log`（运行日志），均在本地机器上 - **AI 诊断限制**：仅支持本地 Ollama，API 地址必须是 localhost/127.0.0.1；不支持任何远程 AI 服务 - **配置基线检查**：仅支持 MySQL/PostgreSQL，依赖 `performance_schema`（MySQL）或 `pg_stat_statements`（PG）获取统计信息 - **索引健康分析**：仅支持 MySQL/PostgreSQL，MySQL 依赖 `performance_schema.table_statistics`，PG 依赖 `pg_stat_user_indexes` - **PDF 导出**：依赖 LibreOffice（跨平台，推荐）或 `docx2pdf`（Windows 专用）；如需 PDF 格式报告请安装：`pip install reportlab`（用于直接生成 PDF 报告）

path: i18n/en.py
content: # -*- coding: utf-8 -*-
"""DBCheck English translation data"""

EN = {
    # CLI main menu
    "cli.main_banner_title": "Database Automation Inspector",
    "cli.main_menu_line1": "🐬  1 │ MySQL Inspection       （5.6/5.7/8.0+）",
    "cli.main_menu_line2": "🐘  2 │ PostgreSQL Inspection  （10/11/12/13/14/15/16/17+）",
    "cli.main_menu_line3": "🔴  3 │ Oracle Inspection       （10g/11g/12c+）",
    "cli.main_menu_line4": "🟡  4 │ DM8 Inspection         （DM8+）",
    "cli.main_menu_line5": "📋  5 │ Batch Template Generator",
    "cli.main_menu_line6": "🌐  6 │ Launch Web UI",
    "cli.main_menu_line7": "   7 │ Exit",
    "cli.main_menu_prompt": "Select an option (1-7): ",
    "cli.main_menu_exiting": "Thanks for using DBCheck. Goodbye! 👋",
    "cli.main_menu_invalid": "❌ Invalid choice, please enter 1-7.",
    "cli.main_menu_mysql_starting": "Starting MySQL database inspection...",
    "cli.main_menu_pg_starting": "Starting PostgreSQL database inspection...",
    "cli.main_menu_oracle_starting": "Starting Oracle comprehensive inspection (enhanced)...",
    "cli.main_menu_dm_starting": "Starting Dameng DM8 database inspection...",
    "cli.batch_menu_title": "Batch Inspection Template Generator",
    "cli.batch_menu_opt0": "0. Return to Main Menu",
    "cli.batch_menu_prompt": "Select [0-3]: ",
    "cli.batch_menu_invalid": "❌ Invalid choice.",
    "cli.webui_starting": "🌐 Starting Web UI, please open http://localhost:5003 in your browser",
    "cli.webui_stopped": "⏹️  Web UI stopped",
    "cli.webui_stop_hint": "Press Ctrl+C to stop service",
    "cli.template_mysql": "MySQL Batch Inspection Template (xlsx)",
    "cli.template_pg": "PostgreSQL Batch Inspection Template (xlsx)",
    "cli.template_dm": "DM8 Batch Inspection Template (xlsx)",

    # CLI Shared - Database Connection
    "cli_db_host": "Host address [{default}]: ",
    "cli_db_port": "Port [{default}]: ",
    "cli_db_port_invalid": "Invalid port, using default {default}",
    "cli_db_user": "Username [{default}]: ",
    "cli_db_password": "Password: ",
    "cli_db_name": "Database name (for report label) [{default}]: ",
    "cli_db_info_title": "Enter database connection information:",
    "cli_inspector_prompt": "Inspector (default {default}): ",
    "cli_output_dir": "Report output directory [{default}]: ",
    "cli_press_enter_return": "Press Enter to return...",
    "cli_retry_yes": "Retry input? (y/n) [y]: ",
    "cli_retry_no": "Retry input? (y/n) [n]: ",

    # CLI Shared - SSH Configuration
    "cli_ssh_enable": "Configure SSH connection? (y/n) [n]: ",
    "cli_ssh_host": "SSH host address [{default}]: ",
    "cli_ssh_port": "SSH port [{default}]: ",
    "cli_ssh_port_invalid": "Invalid SSH port, using default {default}",
    "cli_ssh_user": "SSH username [{default}]: ",
    "cli_ssh_auth_method": "SSH auth method: 1.Password  2.Key file [1]: ",
    "cli_ssh_key_path": "SSH private key file path: ",
    "cli_ssh_key_not_exist": "❌ Private key file not found: {path}",
    "cli_ssh_password": "SSH password: ",
    "cli_ssh_config_title": "🔐 SSH System Info Collection Configuration:",
    "cli_ssh_config_note": "To collect system info (CPU, memory, disk, etc.), configure SSH connection",
    "cli_ssh_success": "✅ SSH connection successful",
    "cli_ssh_fail_no_msg": "❌ SSH connection failed",
    "cli_ssh_fail": "❌ SSH connection failed: {e}",
    "cli_ssh_verifying": "🔍 Verifying SSH connection {host}:{port}...",
    "cli_ssh_collecting": "🔍 Collecting system info via SSH: {host}",
    "cli_ssh_suffix": "(with system info)",

    # Report - health status
    "report.health_excellent": "Excellent",
    "report.health_good": "Good",
    "report.health_fair": "Fair",
    "report.health_attention": "Needs Attention",
    # Report - cover
    "report.cover_database_name": "Database Name",
    "report.cover_ip_address": "Server Address",
    "report.cover_version": "Version",
    "report.cover_hostname": "Hostname",
    "report.cover_start_time": "Uptime",
    "report.cover_inspector": "Inspector",
    "report.cover_platform": "Platform",
    "report.cover_report_time": "Report Time",
    "report.cover_health_status": "Health Status",
    "report.cover_cpu": "CPU",
    "report.cover_mem": "Memory",
    "report.cover_mem_usage": "usage",
    # Report - chapter titles
    "report.ch1": "OS Host Information",
    "report.ch2": "Database Basic Information",
    "report.ch3": "Tablespaces",
    "report.ch4": "SGA / PGA Memory Analysis",
    "report.ch5": "Key Parameter Configuration",
    "report.ch6": "Undo Tablespace Management",
    "report.ch7": "Redo Logs",
    "report.ch8": "Archiving and Backup",
    "report.ch9": "Data Guard Status",
    "report.ch10": "RAC Cluster Information",
    "report.ch11": "ASM Disk Groups",
    "report.ch12": "Sessions and Connections",
    "report.ch13": "Performance Metrics",
    "report.ch14": "Alert Log Analysis",
    "report.ch15": "Users and Security",
    "report.ch16": "Invalid Objects and Statistics",
    "report.ch17": "Partitioned Table Information",
    "report.ch18": "FRA Flashback Recovery Area",
    "report.ch19": "Recycle Bin",
    "report.ch20": "Risks and Recommendations",
    "report.ch21": "AI Diagnosis Recommendations",
    "report.ch22": "Report Notes",
    # Report - risk levels
    "report.risk_high": "High Risk",
    "report.risk_mid": "Medium Risk",
    "report.risk_low": "Low Risk",
    "report.risk_suggestion": "Suggestion",
    "report.risk_dba": "DBA",
    "report.risk_tablespace": "Tablespace {name}",
    "report.risk_ts_high": "Tablespace usage {pct}%, exceeds 90% threshold",
    "report.risk_ts_mid": "Tablespace usage {pct}%, exceeds 80% threshold",
    "report.risk_invalid_obj": "Invalid {type} objects",
    "report.risk_invalid_desc": "{cnt} invalid {type} objects found",
    "report.risk_locked": "Locked Accounts",
    "report.risk_locked_desc": "{n} locked accounts detected",
    "report.risk_alert": "Alert Log Errors",
    "report.risk_alert_desc": "{n} Error-level Alert log entries in the last 7 days",
    "report.risk_fix_ts": "Check tablespace usage",
    "report.risk_fix_alert": "Check Alert log details",
    "report.risk_fix_locked": "Check locked accounts",
    "report.severity_high": "High",
    "report.severity_mid": "Medium",
    "report.severity_low": "Low",
    "report.summary_ts": "{total} tablespaces total, {high} exceed 80% usage",
    "report.summary_wait": "Top wait event: {event}",
    "report.summary_invalid": "{total} invalid objects total",
    # Report - risk section
    "report.risk_summary": "A total of {} issues detected.",
    "report.risk_detail": "Issue Details",
    "report.risk_fix_sql": "Remediation SQL",
    "report.oracle_risk_detail_chapter": "23.1 Issue Details",
    "report.oracle_risk_fix_chapter": "23.2 Remediation SQL",
    "report.oracle_risk_summary_chapter": "23.1 Inspection Summary",
    # Report - AI
    "report.ai_title": "AI Diagnosis Recommendations",
    # Report - general
    "report.data_missing": "Data Not Available",
    "report.running_ok": "Running Normally",
    "report.no_data": "No Data",

    # Web UI - pages
    "webui.home_title": "Home",
    "webui.home_subtitle": "Database Inspection Tool",
    "webui.select_db_type": "Select Database Type",
    "webui.fill_connection_info": "Database Connection Info",
    "webui.step_badge": "Step {} of {}",
    "webui.ssh_config": "SSH Configuration",
    "webui.ssh_enable": "Enable SSH System Info Collection",
    "webui.ssh_enable_state_on": "Enabled",
    "webui.ssh_enable_state_off": "Disabled",
    "webui.ssh_host": "SSH Host",
    "webui.ssh_port": "SSH Port",
    "webui.ssh_user": "SSH Username",
    "webui.ssh_password": "SSH Password",
    "webui.ssh_key": "SSH Key File",
    "webui.ssh_same_as_db": "Same as database host",
    "webui.ssh_desc": "Configure SSH to include CPU, memory, and disk info in the report. Can be skipped to collect database metrics only.",
    "webui.ssh_test_btn": "🔗 Test SSH",
    "webui.ssh_test_ok": "SSH connection successful",
    "webui.ssh_test_fail": "SSH connection failed",
    "webui.inspector_info": "Inspector Information",
    "webui.inspector_name_placeholder": "Inspector name (shown on report cover)",
    "webui.run_inspection": "Start Inspection",
    "webui.run_inspection_btn": "🚀 Start Inspection",
    "webui.confirm_info_title": "Confirm Information",
    "webui.inspector_label": "Inspector",
    "webui.view_history_reports": "📄 View Historical Reports",
    "webui.reports_title": "Historical Inspection Reports",
    "webui.reports_refresh": "↻ Refresh",
    "webui.reports_empty": "No historical reports",
    "webui.reports_loading": "Loading...",
    "webui.reports_load_fail": "Failed to load",
    "webui.trend_title": "Historical Trend Analysis",
    "webui.trend_select_instance": "Select Database Instance",
    "webui.trend_no_data": "Trend data will appear here after running inspections",
    "webui.trend_loading": "-- Loading --",
    "webui.trend_no_history": "-- No history, please run an inspection first --",
    "webui.trend_load_fail": "-- Load failed --",
    "webui.trend_compare": "Comparison with Previous Inspection",
    "webui.trend_indicator": "Metric",
    "webui.trend_prev": "Previous",
    "webui.trend_curr": "Current",
    "webui.trend_change": "Change",
    "webui.trend_no_compare": "No comparable metrics available",
    "webui.db_type_mysql": "MySQL",
    "webui.db_type_pg": "PostgreSQL",
    "webui.db_type_oracle": "Oracle",
    "webui.db_type_dm": "达梦",
    "webui.db_type_sqlserver": "SQL Server",
    "webui.ai_title": "AI Diagnosis Settings",
    "webui.ai_enable_desc": "When enabled, AI diagnosis automatically sends key metrics to the LLM after each inspection to generate personalized optimization recommendations appended to the report.",
    "webui.ai_warn": "Note: AI diagnosis only sends metric values, not passwords or other sensitive information.",
    "webui.ai_save_ok": "✅ AI configuration saved",
    "webui.ai_save_fail": "❌ Save failed",
    "webui.ai_ollama_url": "Ollama API URL",
    "webui.ai_ollama_model": "Model Name",
    "webui.ai_timeout": "Timeout (seconds)",
    "webui.ai_test_btn": "🔍 Test Connection",
    "webui.ai_testing": "⏳ Connecting...",
    "webui.ai_test_ok": "✅ Connection successful! Model responding normally ✓",
    "webui.ai_test_fail": "❌ Connection failed",
    "webui.ai_save_btn": "💾 Save Configuration",
    "webui.ai_reload_btn": "Reload",
    "webui.ai_ollama_timeout_hint": "Recommended: 300~600 seconds, large models load slowly",
    "webui.wizard_desc": "Step-by-step configuration, generate reports with one click",
    "webui.reports_desc": "All generated inspection reports",
    "webui.trend_desc": "Historical metrics trend for the same database across multiple inspections",
    "webui.ai_desc": "Configure LLM for auto-generated optimization recommendations after inspection",
    "webui.oracle_full_suffix": "Full Inspection",
    "webui.analyze_issues": "Smart analysis found {} issues",
    "webui.ssh_testing": "Testing SSH...",
    "webui.ai_diagnosis_title": "AI Diagnostic Recommendations",
    "webui.ai_diagnosis_subtitle": "Auto-generated based on inspection data, for reference only",
    "webui.start_fail": "Start failed",
    "webui.trend_records": "records",

    # Web UI log messages
    "webui.log_mysql_start": "[{ts}] [MySQL] Starting inspection...",
    "webui.log_pg_start": "[{ts}] [PostgreSQL] Starting inspection...",
    "webui.log_oracle_start": "[{ts}] [Oracle Full Inspection] Starting...",
    "webui.log_dm_start": "[{ts}] [DM8] Starting inspection...",
    "webui.log_connecting": "[{ts}] Connecting {host}:{port}...",
    "webui.log_connected": "[{ts}] ✅ Connection successful: {ver}",
    "webui.log_executing_sql": "[{ts}] 📊 Executing inspection SQL...",
    "webui.log_oracle_inspecting": "[{ts}] 📊 Starting Oracle full inspection (OS + DB layer)...",
    "webui.log_dm_analyzing": "[{ts}] 📊 Running enhanced analysis...",
    "webui.log_ai_done": "[{ts}] 🤖 AI diagnosis complete",
    "webui.log_generating_report": "[{ts}] 📄 Generating Word report...",
    "webui.log_report_done": "[{ts}] ✅ Report generated: {fname}",
    "webui.log_inspection_done": "Inspection complete: {ver}",
    "webui.log_oracle_done": "Oracle full inspection complete",
    "webui.err_mysql_module": "MySQL module not installed",
    "webui.err_pg_module": "PostgreSQL module not installed",
    "webui.err_oracle_module": "Oracle full inspection module not installed",
    "webui.err_dm_module": "DM8 module not installed",
    "webui.err_db_connect": "Database connection failed: {ver}",
    "webui.err_getdata_none": "Cannot establish database connection, getData returned None",
    "webui.err_checkdb_false": "checkdb returned False",
    "webui.err_checkdb_empty": "checkdb returned empty",
    "webui.err_report_failed": "Report generation failed",
    "webui.err_inspection": "{task} Inspection error: {e}",

    # Web UI API messages
    "webui.ssh_reachable_auth_fail": "SSH host reachable, but authentication failed (please verify password or key)",
    "webui.ssh_ok": "SSH connection successful",
    "webui.ssh_refused": "Cannot connect SSH: please check host address and port ({err})",
    "webui.ssh_fail": "SSH connection failed: {err}",
    "webui.health_unknown": "Unknown",
    "webui.err_missing_host_port": "Missing host or port",
    "webui.err_unknown_db_type": "Unknown database type",
    "webui.ai_config_saved": "AI configuration saved",
    "webui.ollama_models_found": "✅ Ollama connected, available models: {models}",
    "webui.ollama_no_models": "✅ Ollama connected, but no models detected",
    "webui.err_data_format": "Invalid data format: {body}",
    "webui.err_conn_failed": "Connection failed: {e}",
    "webui.task_not_found": "Task not found",
    "webui.ws_connected_waiting": "[{ts}] Connected, waiting for task...",
    "webui.startup_msg": "DBCheck Web UI starting: http://localhost:{port}",
    "webui.dm_banner": "Dameng DM8",
    "webui.ai_backend": "AI Backend",
    "webui.ai_backend_disabled": "Disabled",
    "webui.ai_backend_ollama": "Ollama (Local)",
    "webui.ai_backend_openai": "OpenAI",
    "webui.ai_openai_key": "API Key",
    "webui.ai_openai_url": "API URL",
    "webui.ai_openai_model": "Model Name",
    "webui.done_title": "Inspection Complete",
    "webui.done_view_report": "📥 Download Report",
    "webui.done_view_history": "📋 View Historical Reports",
    "webui.fail_title": "Inspection Failed",
    "webui.fail_retry": "↺ Retry",
    "webui.test_connection_btn": "🔗 Test Connection",
    "webui.testing_connection": "⏳ Testing...",
    "webui.connection_ok": "✅ Connection successful",
    "webui.connection_fail": "❌ Connection failed",
    "webui.btn_confirm": "✅ Confirm",
    "webui.btn_next": "Next →",
    "webui.btn_prev": "← Back",
    "webui.btn_start": "🚀 Start Inspection",
    "webui.db_mysql_name": "MySQL",
    "webui.db_mysql_desc": "For MySQL 5.7 / 8.x instances — collects connections, InnoDB, slow queries, Binlog and other core metrics.",
    "webui.db_pg_name": "PostgreSQL",
    "webui.db_pg_desc": "For PostgreSQL 10+ instances — collects connections, cache, Vacuum, indexes, replication and other core metrics.",
    "webui.db_dm_name": "Dameng DM8",
    "webui.db_dm_desc": "For Dameng DM8 and above — collects tablespaces, memory, sessions, transactions, backups and other core metrics.",
    "webui.db_oracle_full_name": "Oracle Full Inspection",
    "webui.db_oracle_full_desc": "Enhanced version: OS + database layer, 80+ checks, suitable for 10g~21c.",
    "webui.db_sqlserver_name": "SQL Server",
    "webui.db_sqlserver_desc": "For SQL Server 2012+ instances — collects connections, sessions, wait statistics, locks, backups and other core metrics.",
    "webui.db_sqlserver_beta": "(Beta)",
    "webui.nav_section_feature": "Features",
    "webui.nav_section_setting": "Settings",
    "webui.ssh_config": "SSH Configuration",
    "webui.db_desc_mysql": "For MySQL 5.7 / 8.x instances — collects connections, InnoDB, slow queries, Binlog and other core metrics.",
    "webui.db_desc_pg": "For PostgreSQL 10+ instances — collects connections, cache, Vacuum, indexes, replication and other core metrics.",
    "webui.db_desc_dm": "For Dameng DM8 and above — collects tablespaces, memory, sessions, transactions, backups and other core metrics.",
    "webui.db_desc_oracle": "Enhanced version: OS + database layer, 80+ checks, suitable for 10g~21c.",
    "webui.fi_support": "Multi-Database Support",
    "webui.fi_support_desc": "Supports MySQL, PostgreSQL, Oracle, SQL Server and DM (Dameng), covering mainstream production environments.",
    "webui.fi_metrics": "Comprehensive Metrics",
    "webui.fi_metrics_desc": "Connections, memory, locks, replication, indexes, slow queries — 20+ metrics.",
    "webui.fi_system": "System Resource Monitoring",
    "webui.fi_system_desc": "Local or SSH remote collection of CPU, memory, and disk information.",
    "webui.fi_risk": "AI-Powered Risk Analysis",
    "webui.fi_risk_desc": "Automatically identifies threshold anomalies and provides risk levels with remediation advice.",
    "webui.fi_report": "Professional Word Reports",
    "webui.fi_report_desc": "Standardized templates covering cover, configuration, performance, security and other complete chapters.",
    "webui.fi_web": "Web GUI Operations",
    "webui.fi_web_desc": "Full GUI workflow,告别命令行, real-time log streaming.",

    "webui.ai_collapse": "Collapse",
    "webui.ai_error_hint": "Please check Ollama service status, or increase the timeout in AI settings",
    "webui.ai_error_title": "AI diagnosis is temporarily unavailable",
    "webui.ai_expand": "Expand",
    "webui.ai_ollama_tip": "Fully local operation, no API key needed. Install Ollama first: ollama pull qwen2.5:7b",
    "webui.ai_openai_tip": "DeepSeek: Set API URL to https://api.deepseek.com/v1, model to deepseek-chat, and enter your DeepSeek API key.",
    "webui.ai_warn_note": "Note: AI diagnosis only sends metric values, not passwords or sensitive information.",
    "webui.btn_download_report": "⬇ Download Report",
    "webui.btn_new_inspection": "🔄 New Inspection",
    
    "webui.btn_retry": "↺ Retry",
    "webui.btn_view_trend": "View Trend",
    "webui.btn_start_inspection": "▶ Start Inspection",
    "webui.btn_start_run": "🚀 Start Inspection",
    "webui.btn_starting": "Starting...",
    "webui.cf_conn": "Connection Address",
    "webui.cf_dbtype": "Database Type",
    "webui.cf_name": "Instance Label",
    "webui.cf_ssh": "System Info Collection",
    "webui.chart_title": "Key Metrics Trend Chart",
    "webui.checkbox_sysdba": "Connect as SYSDBA",
    "webui.confirm_btn": "✅ Confirm",
    "webui.hero_desc": "Automatically collects key metrics from MySQL, PostgreSQL, Oracle and DM (Dameng) databases, combined with system resource monitoring, and generates professional Word inspection reports with one click.",
    "webui.hero_title": "Database Health Inspection",
    "webui.ind_cache_hit_ratio": "Cache Hit Ratio (%)",
    "webui.ind_connections": "Current Connections",
    "webui.ind_cpu_usage": "CPU Usage (%)",
    "webui.ind_disk_usage_max": "Max Disk Usage (%)",
    "webui.ind_max_used_connections": "Historical Max Connections",
    "webui.ind_mem_usage": "Memory Usage (%)",
    "webui.ind_queries_total": "Total Queries",
    "webui.ind_risk_count": "Risk Count",
    "webui.label_auth_method": "Auth Method",
    "webui.label_database": "Database",
    "webui.label_database_opt": "PostgreSQL",
    "webui.label_host": "Host Address",
    "webui.label_instance_tag": "Instance Label",
    "webui.label_instance_tag_opt": "For report naming",
    "webui.label_password": "Password",
    "webui.label_port": "Port",
    "webui.label_service_sid": "Service Name / SID",
    "webui.label_service_sid_opt": "Oracle",
    "webui.label_ssh_host": "SSH Host",
    "webui.label_ssh_port": "SSH Port",
    "webui.label_ssh_user": "SSH Username",
    "webui.label_username": "Username",
    "webui.logo_subtitle": "Database Inspection Tool",
    "webui.nav_ai": "AI Settings",
    "webui.nav_home": "Home",
    "webui.nav_wizard": "New Inspection",
    "webui.opt_auth_key": "Private Key File",
    "webui.opt_auth_password": "Password Auth",
    "webui.placeholder_database": "Default: postgres",
    "webui.placeholder_host": "localhost or IP address",
    "webui.placeholder_inspector": "Inspector name (shown on report cover)",
    "webui.placeholder_instance_tag": "e.g. Production-Primary",
    "webui.placeholder_password": "Database password",
    "webui.placeholder_service": "orcl or orcl.example.com (leave empty to use host address)",
    "webui.placeholder_ssh_host": "Same as database host",
    "webui.placeholder_ssh_key": "/root/.ssh/id_rsa",
    "webui.placeholder_ssh_password": "SSH password",
    "webui.report_done_title": "Report Generated",
    "webui.reports_load_fail_detail": "Failed to load",
    "webui.risk_high": "High Risk",
    "webui.risk_low": "Low Risk / Suggestion",
    "webui.risk_mid": "Medium Risk",
    "webui.ssh_not_configured": "Not configured (DB metrics only)",
    "webui.status_error": "Inspection Failed",
    "webui.status_pending": "Waiting to execute...",
    "webui.status_preparing": "Preparing...",
    "webui.status_running": "Inspection in progress, please wait...",
    "webui.step1_title": "Select Database Type",
    "webui.step2_title": "Database Connection Info",
    "webui.trend_same_db_note": "Multiple inspection results for the same database (same IP + port) will be compared here",
    "webui.wizard_step1": "Database Type",
    "webui.wizard_step2": "Connection Info",
    "webui.wizard_step3": "SSH Config",
    "webui.wizard_step4": "Inspector",
    "webui.wizard_step5": "Run Inspection",

    "report.running_ok": "Running well",
    "report.data_missing": "Data unavailable",
    "report.health_excellent": "Excellent",
    "report.health_good": "Good",
    "report.health_fair": "Fair",
    "report.health_attention": "Needs Attention",
    "report.risk_chapter": "Risk and Recommendations",
    "report.risk_detail_chapter": "Issue Details",
    "report.fix_chapter": "Quick Fix Reference",
    "report.ai_chapter": "AI Diagnostic Recommendations",
    "report.ai_disclaimer": " The following recommendations are automatically generated by the AI model based on the inspection data. For reference only — evaluate carefully against your actual business scenario before taking action.",
    "report.ai_disabled": "💡 AI diagnosis is not enabled. To enable it, configure the backend in Web UI → AI Diagnosis Settings (only local Ollama is supported).",
    "report.notes_chapter": "25. Report Notes",
    "report.note_1": "1. This report reflects the real-time health status of the MySQL database at the time of generation.",
    "report.note_2": "2. Blank fields indicate that data could not be retrieved, possibly due to insufficient privileges or disabled features.",
    "report.note_3": "3. Disk information shows only major partitions. Use 'df -h' for full disk details.",
    "report.note_4": "4. Inspection results are for reference only. Always consider your specific operational context.",
    "report.note_5": "5. Regular database inspections are recommended to identify and resolve potential issues promptly.",
    "report.note_6": "6. AI-generated recommendations (if enabled) are for reference only and do not constitute professional DBA advice.",
    "report.no_risk_found": "✅ No significant risks found. MySQL database is running in good health.",
    "report.col_seq": "No.",
    "report.col_risk_item": "Risk Item",
    "report.col_level": "Level",
    "report.col_desc": "Description",
    "report.col_severity": "Severity",
    "report.col_priority": "Priority",
    "report.col_owner": "Owner",
    "report.col_fix": "Fix Recommendation",
    "report.risk_high": "High Risk",
    "report.risk_mid": "Medium Risk",
    "report.risk_low": "Low Risk",
    "report.risk_suggest": "Suggestion",
    "report.detected_prefix": "A total of ",
    "report.high_risk_n": " {n} high risk",
    "report.mid_risk_n": " {n} medium risk",
    "report.low_risk_n": " {n} low risk/suggestion",
    "report.detected_suffix": " item(s) were detected, totaling {c} issue(s).",

    # MySQL Fallback 渲染 i18n
    "report.mysql_title": "MySQL Database Health Inspection Report",
    "report.fallback_db_name": "Database Name",
    "report.fallback_server_addr": "Server Address",
    "report.fallback_mysql_version": "MySQL Version",
    "report.fallback_hostname": "Server Hostname",
    "report.fallback_start_time": "Instance Startup Time",
    "report.fallback_inspector": "Inspector",
    "report.fallback_platform": "Server Platform",
    "report.fallback_report_time": "Report Generation Time",
    "report.fallback_health_overview": "Health Status Overview",
    "report.fallback_item_col": "Item",
    "report.fallback_value_col": "Value",
    "report.fallback_overall_health": "Overall Health Status",
    "report.fallback_issue_count": "Issues Found",
    "report.fallback_health_summary": "Health Summary",
    "report.fallback_system_check": "System Resource Check",
    "report.fallback_cpu_info": "CPU Information",
    "report.fallback_cpu_usage": "CPU Usage",
    "report.fallback_physical_cores": "Physical Cores",
    "report.fallback_logical_cores": "Logical Cores",
    "report.fallback_freq_ghz": "Current Frequency (GHz)",
    "report.fallback_memory_info": "Memory Information",
    "report.fallback_total_gb": "Total Memory (GB)",
    "report.fallback_used_gb": "Used (GB)",
    "report.fallback_available_gb": "Available (GB)",
    "report.fallback_usage_pct": "Usage %",
    "report.fallback_disk_info": "Disk Information",
    "report.fallback_mountpoint": "Mount Point",
    "report.fallback_mysql_config": "MySQL Configuration Check",
    "report.fallback_conn_config": "Connection Configuration",
    "report.fallback_max_connections": "Max Connections",
    "report.fallback_current_connections": "Current Connections",
    "report.fallback_interactive_timeout": "Interactive Timeout",
    "report.fallback_open_files_limit": "Open Files Limit",
    "report.fallback_memory_config": "Memory Configuration",
    "report.fallback_innodb_buffer_pool": "InnoDB Buffer Pool",
    "report.fallback_sort_buffer": "Sort Buffer Size",
    "report.fallback_join_buffer": "Join Buffer Size",
    "report.fallback_thread_cache": "Thread Cache Size",
    "report.fallback_log_config": "Log Configuration",
    "report.fallback_slow_query_log": "Slow Query Log",
    "report.fallback_binlog_days": "Binlog Retention Days",
    "report.fallback_innodb_log_size": "InnoDB Log File Size",
    "report.fallback_flush_log": "Log Flush Setting",
    "report.fallback_perf_analysis": "Performance Analysis",
    "report.fallback_qps_check": "QPS Check",
    "report.fallback_total_queries": "Total Queries",
    "report.fallback_lock_info": "Lock Information",
    "report.fallback_lock_immediate": "Immediate Lock Tables",
    "report.fallback_lock_waited": "Waited Lock Tables",
    "report.fallback_abnormal_conn": "Abnormal Connections",
    "report.fallback_abnormal_type": "Abnormal Type",
    "report.fallback_abnormal_client": "Abnormal Client Connections",
    "report.fallback_abnormal_attempt": "Abnormal Connection Attempts",
    "report.fallback_db_info": "Database Information",
    "report.fallback_db_size": "Database Size",
    "report.fallback_dbname": "Database Name",
    "report.fallback_table_rows": "Table Rows",
    "report.fallback_data_size_mb": "Data Size (MB)",
    "report.fallback_index_size_mb": "Index Size (MB)",
    "report.fallback_processlist": "Current Process List",
    "report.fallback_process_id": "ID",
    "report.fallback_process_user": "User",
    "report.fallback_process_db": "Database",
    "report.fallback_process_state": "State",
    "report.fallback_process_command": "Command",
    "report.fallback_process_time": "Time",
    "report.fallback_security_info": "Security Information",
    "report.fallback_db_users": "Database User Information",
    "report.fallback_username": "Username",
    "report.fallback_host": "Host",
    "report.fallback_privileges": "Granted Privileges",
    "report.fallback_auth_plugin": "Auth Plugin",
    "report.fallback_account_locked": "Account Locked",
    "report.fallback_risk_chapter": "Risk and Recommendations",
    "report.fallback_detected_prefix": "A total of ",
    "report.fallback_high_risk_n": " high risk",
    "report.fallback_mid_risk_n": " medium risk",
    "report.fallback_low_risk_n": " low risk/suggestion",
    "report.fallback_detected_suffix2": " item(s) were detected, totaling {c} issue(s).",
    "report.fallback_issue_detail": "Issue Details",
    "report.fallback_seq": "No.",
    "report.fallback_risk_item": "Risk Item",
    "report.fallback_level": "Level",
    "report.fallback_desc": "Description",
    "report.fallback_priority": "Priority",
    "report.fallback_owner": "Owner",
    "report.fallback_fix_suggest": "Fix Recommendation",
    "report.fallback_fix_sql_placeholder": "—",
    "report.fallback_fix_chapter": "Quick Fix Reference",
    "report.fallback_no_risk_found": "✅ No significant risks found. MySQL database is running in good health.",
    "report.fallback_ai_chapter": "AI Intelligent Diagnosis Recommendations",
    "report.fallback_ai_disclaimer": " The following recommendations are automatically generated by the AI model based on the inspection data. For reference only — evaluate carefully against your actual business scenario before taking action.",
    "report.fallback_notes_chapter": "Report Notes",
    "report.fallback_note_1": "1. This report reflects the real-time health status of the MySQL database at the time of generation.",
    "report.fallback_note_2": "2. Blank fields indicate that data could not be retrieved, possibly due to insufficient privileges or disabled features.",
    "report.fallback_note_3": "3. Disk information shows only major partitions. Use 'df -h' for full disk details.",
    "report.fallback_note_4": "4. Inspection results are for reference only. Always consider your specific operational context.",
    "report.fallback_note_5": "5. Regular database inspections are recommended to identify and resolve potential issues promptly.",
    "report.fallback_note_6": "6. AI-generated recommendations (if enabled) are for reference only and do not constitute professional DBA advice.",
    "report.fallback_render_fail": "❌ Failed to generate Word document",

    # PostgreSQL Fallback 渲染 i18n
    "report.pg_title": "PostgreSQL Database Health Inspection Report",
    "report.fallback_pg_version": "PostgreSQL Version",
    "report.fallback_pg_start_time": "Instance Startup Time",
    "report.fallback_pg_config": "PostgreSQL Configuration Check",
    "report.fallback_pg_conn_mem": "Connection & Memory Configuration",
    "report.fallback_pg_max_conn": "Max Connections",
    "report.fallback_pg_cur_conn": "Current Connections",
    "report.fallback_pg_shared_buf": "Shared Buffers",
    "report.fallback_pg_work_mem": "Work Memory",
    "report.fallback_pg_maint_mem": "Maintenance Memory",
    "report.fallback_pg_eff_cache": "Effective Cache Size",
    "report.fallback_pg_wal_checkpoint": "WAL & Checkpoint Configuration",
    "report.fallback_pg_wal_level": "WAL Level",
    "report.fallback_pg_max_wal": "Max WAL Size",
    "report.fallback_pg_ckpt_target": "Checkpoint Completion Target",
    "report.fallback_pg_random_page": "Random Page Cost",
    "report.fallback_pg_autovacuum": "Autovacuum Configuration",
    "report.fallback_pg_autovac": "Autovacuum",
    "report.fallback_pg_vac_scale": "Vacuum Scale Factor",
    "report.fallback_pg_analyze_scale": "Analyze Scale Factor",
    "report.fallback_pg_slow_query": "Slow Query Threshold (ms)",
    "report.fallback_pg_perf": "Performance Analysis",
    "report.fallback_pg_conn_status": "Connection Status",
    "report.fallback_pg_conn_usage": "Connection Usage (%)",
    "report.fallback_pg_cache_hit": "Cache Hit Ratio",
    "report.fallback_pg_cache_hit_good": "Good",
    "report.fallback_pg_cache_hit_fair": "Fair",
    "report.fallback_pg_cache_hit_poor": "Poor",
    "report.fallback_pg_db_size": "Database Size",
    "report.fallback_pg_db_info": "Database Information",
    "report.fallback_pg_db_list": "Database List",
    "report.fallback_pg_dbname": "Database Name",
    "report.fallback_pg_encoding": "Encoding",
    "report.fallback_pg_allow_conn": "Allow Connections",
    "report.fallback_pg_proc_list": "Current Process List",
    "report.fallback_pg_pid": "PID",
    "report.fallback_pg_pg_user": "User",
    "report.fallback_pg_pg_db": "Database",
    "report.fallback_pg_pg_state": "State",
    "report.fallback_pg_curr_sql": "Current SQL (truncated)",
    "report.fallback_pg_security": "Security Information",
    "report.fallback_pg_db_users": "Database User Information",
    "report.fallback_pg_username": "Username",
    "report.fallback_pg_superuser": "Superuser",
    "report.fallback_pg_can_createdb": "Create DB",
    "report.fallback_pg_can_createrole": "Create Role",
    "report.fallback_pg_pass_expire": "Password Expiry",
    "report.fallback_pg_risk_chapter": "Risk and Recommendations",
    "report.fallback_pg_issue_detail": "Issue Details",
    "report.fallback_pg_fix_chapter": "Quick Fix Reference",
    "report.fallback_pg_no_risk_found": "✅ No significant risks found. PostgreSQL database is running in good health.",
    "report.fallback_pg_ai_chapter": "AI Intelligent Diagnosis Recommendations",
    "report.fallback_pg_ai_disclaimer": " The following recommendations are automatically generated by the AI model based on the inspection data. For reference only — evaluate carefully against your actual business scenario before taking action.",
    "report.fallback_pg_notes_chapter": "Report Notes",
    "report.fallback_pg_note_1": "1. This report reflects the real-time health status of the PostgreSQL database at the time of generation.",
    "report.fallback_pg_note_2": "2. Blank fields indicate that data could not be retrieved, possibly due to insufficient privileges or disabled features.",
    "report.fallback_pg_note_3": "3. Disk information shows only major partitions. Use 'df -h' for full disk details.",
    "report.fallback_pg_note_4": "4. Inspection results are for reference only. Always consider your specific operational context.",
    "report.fallback_pg_note_5": "5. Regular database inspections are recommended to identify and resolve potential issues promptly.",
    "report.fallback_pg_note_6": "6. AI-generated recommendations (if enabled) are for reference only and do not constitute professional DBA advice.",
    "report.fallback_pg_render_fail": "❌ Failed to generate Word document",

    "report.no_risk_found_pg": "✅ No significant risks found. PostgreSQL database is running in good health.",
    "report.note_1_pg": "1. This report reflects the real-time health status of the PostgreSQL database at the time of generation.",
    "report.pg_fallback_health_ok": "Running Well",
    # PG Template Chapter Headings
    "report.pg_ch3": "PostgreSQL Configuration Check",
    "report.pg_ch31": "Connection Configuration",
    "report.pg_ch32": "Memory and Storage Configuration",
    "report.pg_ch33": "Autovacuum and Logging Configuration",
    "report.pg_ch4": "Performance Analysis",
    "report.pg_ch41": "Connection Status",
    "report.pg_ch42": "Connection Details (Grouped by State)",
    "report.pg_ch43": "Cache Hit Ratio",
    "report.pg_ch44": "Database Size",
    "report.pg_ch5": "Database Security",
    "report.pg_ch51": "Account Lockout Status",
    "report.pg_ch6": "Inspection Summary",
    "report.pg_ch7": "Risk and Recommendations",
    "report.pg_ch8": "AI Intelligent Diagnosis",
    # Table Headers
    "report.pg_hdr_config_item": "Configuration Item",
    "report.pg_hdr_current_value": "Current Value",
    "report.pg_hdr_description": "Description",
    "report.pg_hdr_metric": "Metric",
    "report.pg_hdr_value": "Value",
    "report.pg_hdr_state": "State",
    "report.pg_hdr_conn_count": "Connection Count",
    "report.pg_hdr_database": "Database",
    "report.pg_hdr_size_gb": "Size (GB)",
    "report.pg_hdr_total": "Total",
    "report.pg_hdr_user": "Username",
    "report.pg_hdr_member_of": "Member Of",
    "report.pg_hdr优质服务": "Superuser",
    "report.pg_hdr_locked": "Locked",
    "report.pg_hdr_super": "Superuser",
    # 3.1 Connection Config
    "report.pg_max_connections": "Max Connections",
    "report.pg_max_connections_desc": "Maximum number of concurrent client connections",
    "report.pg_shared_buffers": "Shared Buffers",
    "report.pg_shared_buffers_desc": "Memory used by PostgreSQL for data caching",
    "report.pg_effective_cache": "Effective Cache Size",
    "report.pg_effective_cache_desc": "Estimated memory available for OS cache",
    "report.pg_work_mem": "Work Memory",
    "report.pg_work_mem_desc": "Memory limit for sorting and hash operations",
    # 3.2 Memory Config
    "report.pg_maint_work_mem": "Maintenance Work Memory",
    "report.pg_maint_work_mem_desc": "Memory for VACUUM, CREATE INDEX and maintenance operations",
    "report.pg_wal_level": "WAL Level",
    "report.pg_wal_level_desc": "Write-Ahead Logging detail level",
    "report.pg_max_wal_size": "Max WAL Size",
    "report.pg_max_wal_size_desc": "Maximum WAL growth between automatic checkpoints",
    "report.pg_checkpoint_target": "Checkpoint Completion Target",
    "report.pg_checkpoint_target_desc": "Target proportion of time for checkpoint completion",
    "report.pg_random_page_cost": "Random Page Cost",
    "report.pg_random_page_cost_desc": "Cost estimate for random disk access vs sequential",
    # 3.3 Autovacuum
    "report.pg_autovacuum": "Autovacuum",
    "report.pg_autovacuum_desc": "Whether autovacuum is enabled",
    "report.pg_autovacuum_vacuum_factor": "Vacuum Scale Factor",
    "report.pg_autovacuum_vacuum_factor_desc": "Table row proportion that triggers vacuum",
    "report.pg_autovacuum_analyze_factor": "Analyze Scale Factor",
    "report.pg_autovacuum_analyze_factor_desc": "Table row proportion that triggers analyze",
    "report.pg_slow_query_threshold": "Slow Query Threshold (ms)",
    "report.pg_slow_query_threshold_desc": "Queries exceeding this duration will be logged (milliseconds)",
    # 4.1 Connection Status
    "report.pg_current_connections": "Current Connections",
    "report.pg_max_connections_hdr": "Max Connections",
    "report.pg_conn_usage": "Connection Usage",
    # 4.3 Cache Hit Ratio
    "report.pg_dbname": "Database Name",
    "report.pg_blks_hit": "Blocks Hit",
    "report.pg_blks_read": "Blocks Read",
    "report.pg_hit_ratio": "Hit Ratio (%)",
    # 5.1 Security
    "report.pg优质服务": "Superuser",
    "report.pg已锁定": "Locked",
    "report.pg_superuser": "Superuser",
    "report.pg_fallback_conn_usage_label": "Connection Usage Rate",
    "report.pg_fallback_conn_usage_desc": "Connection usage is as high as {pct:.1f}%, approaching the max connection limit",
    "report.pg_fallback_mem_usage_label": "System Memory Usage",
    "report.pg_fallback_mem_usage_desc": "System memory usage exceeds 90%",
    "report.pg_fallback_priority_high": "High",
    "report.pg_fallback_owner_dba": "DBA",
    "report.pg_fallback_owner_sysadmin": "System Administrator",

    # ── PG Chapter 2 System Resources ────────────────────────────────────────
    "report.pg_ch2_title": "2. System Resource Check",
    "report.pg_ch2_cpu": "2.1 CPU Information",
    "report.pg_ch2_mem": "2.2 Memory Information",
    "report.pg_ch2_disk": "2.3 Disk Information",
    "report.pg_cpu_usage_hdr": "CPU Usage",
    "report.pg_physical_cores_hdr": "Physical Cores",
    "report.pg_logical_cores_hdr": "Logical Cores",
    "report.pg_freq_hdr": "Current Freq (GHz)",
    "report.pg_total_mem_hdr": "Total Memory (GB)",
    "report.pg_used_mem_hdr": "Used (GB)",
    "report.pg_avail_mem_hdr": "Available (GB)",
    "report.pg_mem_usage_hdr": "Usage %",
    "report.pg_mountpoint_hdr": "Mount Point",
    "report.pg_fallback_na": "N/A",

    # ── PG Chapter 7 Issue Translation Keys ──────────────────────────────────
    "report.pg_issue_slow_query_log": "Slow Query Log Disabled",
    "report.pg_issue_shared_buffers_small": "shared_buffers Too Small",
    "report.pg_issue_archive_mode_off": "Archive Mode Disabled",
    "report.pg_issue_conn_usage_high": "Connection Usage Too High",
    "report.pg_issue_mem_usage_high": "System Memory Usage Too High",
    "report.pg_issue_disk_usage_high": "Disk Usage Too High",
    "report.pg_issue_long_query": "Long-running SQL (> 60s) Detected",
    "report.pg_issue_cache_hit_low": "Low Cache Hit Ratio",
    "report.pg_issue_repl_lag": "Replication Lag Too High",
    "report.pg_issue_lock_wait": "Lock Wait Detected",
    "report.pg_issue_superuser_many": "Too Many Superusers",
    "report.pg_issue_disk_warning": "Disk Space Warning",
    "report.pg_issue_dead_tuples": "Excessive Dead Tuples",
    "report.pg_fallback_priority_mid": "Medium",
    "report.pg_fallback_priority_low": "Low",
    "report.pg_fallback_owner_dba": "DBA",
    "report.pg_fallback_owner_sysadmin": "System Administrator",

    "report.oracle_title": "DBCheck Oracle Full Inspection Report",
    "report.inspector_label": "\nInspector: {i}",
    "report.tbl_col_key": "Item",
    "report.tbl_col_val": "Value",
    "report.oracle_ch1": "Chapter 1: Inspection Overview",
    "report.oracle_ch2": "Chapter 2: OS System Information",
    "report.oracle_ch3": "Chapter 3: Oracle Instance Information",
    "report.oracle_ch4": "Chapter 4: Database Basic Information",
    "report.oracle_ch5": "Chapter 5: Tablespaces",
    "report.oracle_ch6": "Chapter 6: Performance and Activity",
    "report.oracle_ch7": "Chapter 7: Risk and Recommendations",
    "report.oracle_ch8": "Chapter 8: AI Diagnostic Recommendations",
    "report.no_risk_found_oracle": "✅ No significant risks found. Database is running normally.",
    "report.detected_oracle": "A total of {t} risk(s)/suggestion(s) detected, including {h} high-risk item(s).",

    # ── Oracle Report Common ───────────────────────────────────────────────────
    "report.oracle_sec_os":        "1. OS Host Information",
    "report.oracle_sec_db":        "2. Database Basic Information",
    "report.oracle_sec_instance":  "3. Instance Information",
    "report.oracle_sec_version":   "4. Database Version and Patches",
    "report.oracle_sec_ts":        "5. Tablespaces",
    "report.oracle_sec_ts_perm":   "5.1 Permanent Tablespaces",
    "report.oracle_sec_ts_temp":   "5.2 Temporary Tablespaces",
    "report.oracle_sec_redo":      "6. Redo Logs",
    "report.oracle_sec_cf":        "7. Control Files",
    "report.oracle_sec_sga_pga":   "8. SGA/PGA Memory",
    "report.oracle_sec_sga":       "8.1 SGA Dynamic Components",
    "report.oracle_sec_pga":       "8.2 PGA Statistics",
    "report.oracle_sec_mem_param": "8.3 Memory Parameters",
    "report.oracle_sec_params":    "9. Key Parameters",
    "report.oracle_sec_undo":      "10. Undo Information",
    "report.oracle_sec_long_sql":  "11. Long-running SQL",
    "report.oracle_sec_perf":      "12. Performance Metrics",
    "report.oracle_sec_perf_ses":  "12.1 Session Status",
    "report.oracle_sec_perf_wait": "12.2 Wait Event Statistics",
    "report.oracle_sec_top_sql":   "13. Top SQL (by Buffer Gets)",
    "report.oracle_sec_invalid":    "14. Invalid Objects",
    "report.oracle_sec_users":      "15. User Security",
    "report.oracle_sec_user_def":  "15.1 Default Account Status",
    "report.oracle_sec_user_lock": "15.2 Locked Accounts",
    "report.oracle_sec_backup":    "16. Backup Information (RMAN)",
    "report.oracle_sec_flashback": "17. Flashback and Recycle Bin",
    "report.oracle_sec_dataguard": "18. Data Guard",
    "report.oracle_sec_rac":       "19. RAC + ASM",
    "report.oracle_sec_awr":       "20. AWR Snapshots",
    "report.oracle_sec_jobs":      "21. Job Scheduler",
    "report.oracle_sec_alert":     "22. Alert Log Errors (Last 7 Days)",
    "report.oracle_sec_ai":       "24. AI Diagnosis Recommendations",
    "report.oracle_sec_risks":    "23. Risks and Recommendations",
    "report.oracle_footer":       "DBCheck Oracle Inspection Tool {VER} | Report generated at {time}",
    # Oracle Report Notes
    "report.oracle_note_1": "This report reflects the real-time health status of the Oracle database at the time of generation.",
    "report.oracle_note_2": "Blank fields indicate that data could not be retrieved, possibly due to insufficient privileges or disabled features.",
    "report.oracle_note_3": "Disk information shows only major partitions. Use 'df -h' for full disk details.",
    "report.oracle_note_4": "Inspection results are for reference only. Always consider your specific operational context.",
    "report.oracle_note_5": "Regular database inspections are recommended to identify and resolve potential issues promptly.",
    "report.oracle_note_6": "AI-generated recommendations (if enabled) are for reference only and do not constitute professional DBA advice.",
    # ── DM8 Report i18n ──────────────────────────────────────────────────────
    "report.dm_title": "DM8 Database Health Inspection Report",
    "report.dm_ch1": "1. Database Basic Information",
    "report.dm_ch2": "2. Inspection Summary",
    "report.dm_ch2_health": "2.1 Health Summary",
    "report.dm_ch2_sql": "2.2 SQL Execution Status",
    "report.dm_ch3": "3. Tablespace Usage",
    "report.dm_ch4": "4. Sessions and Transactions",
    "report.dm_ch5": "5. Memory Analysis",
    "report.dm_ch6": "6. Redo Logs and Archiving",
    "report.dm_ch7": "7. System Resource Monitoring",
    "report.dm_ch8": "8. Objects and User Security",
    "report.dm_ch9": "9. Backup and Archiving",
    "report.dm_ch81": "8.1 Invalid Objects",
    "report.dm_ch82": "8.2 User List",
    "report.dm_fallback_db_name": "Database Name",
    "report.dm_fallback_server_addr": "Server Address",
    "report.dm_fallback_version": "DM Version",
    "report.dm_fallback_hostname": "Server Hostname",
    "report.dm_fallback_instance_time": "Instance Start Time",
    "report.dm_fallback_inspector": "Inspector",
    "report.dm_fallback_platform": "Server Platform",
    "report.dm_fallback_report_time": "Report Generation Time",
    "report.dm_fallback_no_data": "No Data",
    "report.dm_fallback_sql_exec": "SQL Execution Status",
    "report.dm_fallback_notes_chapter": "16. Report Notes",
    "report.dm_notes_chapter_ai": "16. Report Notes",
    "report.dm_no_risk_found": "✅ No significant risks found. DM8 database is running in good health.",
    # DM8 risk table column headers
    "report.dm_col_seq": "No.",
    "report.dm_col_item": "Item",
    "report.dm_col_risk_level": "Risk Level",
    "report.dm_col_desc": "Description",
    "report.dm_col_severity": "Severity",
    "report.dm_col_owner": "Owner",
    "report.dm_col_fix": "Fix Suggestion",
    # DM8 Chapter 2 health summary
    "report.dm_health_score": "Overall Score",
    "report.dm_health_status": "Status",
    "report.dm_health_status_ok": "Normal",
    "report.dm_status_critical": "Critical",
    "report.dm_status_warning": "Warning",
    "report.dm_status_general": "General",
    "report.dm_critical_n": "Critical Alerts",
    "report.dm_warning_n": "Warning Alerts",
    # DM8 SQL execution
    "report.dm_sql_total": "Total SQL",
    "report.dm_sql_ok": "Success",
    "report.dm_sql_fail": "Failed",
    # DM8 Chapter 7 system resources
    "report.dm_cpu_usage": "CPU Usage",
    "report.dm_mem_usage": "Memory Usage",
    "report.dm_disk_usage": "Disk",
    "report.dm_disk_used": "Used",
    "report.dm_disk_total": "Total",
    # DM8 Report notes
    "report.dm_note_1": "1. This report reflects the real-time health status of the DM8 database at the time of generation.",
    "report.dm_note_2": "2. Blank fields indicate that data could not be retrieved, possibly due to insufficient privileges or disabled features.",
    "report.dm_note_3": "3. Disk information shows only major partitions. Use 'df -h' for full disk details.",
    "report.dm_note_4": "4. Inspection results are for reference only. Always consider your specific operational context.",
    "report.dm_note_5": "5. Regular database inspections are recommended to identify and resolve potential issues promptly.",
    "report.dm_note_6": "6. AI-generated recommendations (if enabled) are for reference only and do not constitute professional DBA advice.",
    "report.dm_fallback_instance_name": "Instance Name",
    "report.dm_fallback_sql_name": "SQL Name",
    "report.dm_fallback_err_code": "Error Code",
    "report.dm_fallback_fix_suggest": "Fix Suggestion",
    "report.dm_fallback_sga_summary": "SGA Buffer Pool Summary",
    "report.dm_fallback_sga_detail": "Buffer Pool Details (SGA)",
    # DM8 new chapters (aligned with Oracle)
    "report.dm_ch10": "10. Long-running SQL",
    "report.dm_ch11": "11. Top SQL",
    "report.dm_ch12": "12. Undo Information",
    "report.dm_ch13": "13. Wait Event Statistics",
    "report.dm_ch14": "14. Risks and Recommendations",
    "report.dm_ch14_1": "14.1 Issue Details",
    "report.dm_ch14_2": "14.2 Remediation SQL",
    "report.dm_ch15": "15. AI Diagnosis Recommendations",
    "report.dm_notes_chapter_ai": "16. Report Notes",
    "report.dm_fallback_notes_chapter": "16. Report Notes",
    "report.dm_no_risk_found": "✅ No significant risks found. DM8 database is running in good health.",
    # DM8 wait event column headers
    "report.dm_col_event": "Event",
    "report.dm_col_waits": "Waits",
    "report.dm_col_time": "Time Waited (ms)",
    "report.dm_col_class": "Wait Class",

    # Table column headers
    "report.oracle_col_inst_id":   "INST_ID",
    "report.oracle_col_inst_name":"Instance Name",
    "report.oracle_col_host":     "Host",
    "report.oracle_col_version":   "Version",
    "report.oracle_col_startup":   "Startup Time",
    "report.oracle_col_status":    "Status",
    "report.oracle_col_parallel":  "Parallel",
    "report.oracle_col_log_mode":  "Log Mode",
    "report.oracle_col_role":      "Role",
    "report.oracle_col_open_mode": "Open Mode",
    "report.oracle_col_db_name":   "Database Name",
    "report.oracle_col_db_role":   "Role",
    "report.oracle_col_open_mode2":"Open Mode",
    "report.oracle_col_log_mode2": "Log Mode",
    "report.oracle_col_cdb":       "CDB",
    "report.oracle_col_flashback": "Flashback",
    "report.oracle_col_force_log": "Force Logging",
    "report.oracle_col_block_size": "Block Size",
    "report.oracle_col_sga_max":   "SGA Max",
    "report.oracle_col_sga_target":"SGA Target",
    "report.oracle_col_pga_target":"PGA Target",
    "report.oracle_col_spfile":     "SPFILE",
    "report.oracle_col_ts_name":   "Tablespace Name",
    "report.oracle_col_ts_status": "Status",
    "report.oracle_col_ts_type":   "Type",
    "report.oracle_col_ts_log":    "Log",
    "report.oracle_col_ts_max_mb": "Max MB",
    "report.oracle_col_ts_cur_mb": "Current MB",
    "report.oracle_col_ts_used_mb":"Used MB",
    "report.oracle_col_ts_pct":    "Usage %",
    "report.oracle_col_redo_g":    "Group#",
    "report.oracle_col_redo_th":   "Thread#",
    "report.oracle_col_redo_seq":  "Sequence#",
    "report.oracle_col_redo_sz":   "Size MB",
    "report.oracle_col_redo_st":   "Status",
    "report.oracle_col_redo_mbr":  "Members",
    "report.oracle_col_redo_arch": "Archived",
    "report.oracle_col_cf_name":   "Name",
    "report.oracle_col_cf_st":     "Status",
    "report.oracle_col_cf_recovery":"Recovery Catalog",
    "report.oracle_col_cf_block":  "Block Size",
    "report.oracle_col_cf_blocks": "File Blocks",
    "report.oracle_col_sga_comp":  "Component",
    "report.oracle_col_sga_cur":   "Current MB",
    "report.oracle_col_sga_min":   "Min MB",
    "report.oracle_col_sga_user":  "User-specified MB",
    "report.oracle_col_sga_total": "SGA Total (MB)",
    "report.oracle_col_pga_stat_name": "Metric Name",
    "report.oracle_col_pga_stat_val": "Value (MB)",
    "report.oracle_col_param_name":"Parameter Name",
    "report.oracle_col_param_val": "VALUE",
    "report.oracle_col_param_disp": "Display Value",
    "report.oracle_col_param_def": "Is Default",
    "report.oracle_col_param_sess": "Session Modifiable",
    "report.oracle_col_param_sys": "System Modifiable",
    "report.oracle_col_param_desc":"Description",
    "report.oracle_col_undo_ts":   "Undo Tablespace",
    "report.oracle_col_undo_ret":  "Retention Policy",
    "report.oracle_col_undo_used": "Used MB",
    "report.oracle_col_undo_total": "Total MB",
    "report.oracle_col_undo_committed": "Committed Blocks",
    "report.oracle_col_undo_uncommitted": "Uncommitted Blocks",
    "report.oracle_col_undo_total_blocks": "Total Blocks",
    "report.oracle_col_undo_seg_status": "Status",
    "report.oracle_col_undo_seg_count": "Segment Count",
    "report.oracle_col_undo_seg_size": "Total Size MB",
    "report.oracle_col_sid":       "SID",
    "report.oracle_col_serial":    "SERIAL#",
    "report.oracle_col_username":   "Username",
    "report.oracle_col_sql_id":     "SQL_ID",
    "report.oracle_col_operation":  "Operation",
    "report.oracle_col_done":       "Completed",
    "report.oracle_col_work":       "Total Work",
    "report.oracle_col_pct_done":   "Complete %",
    "report.oracle_col_elapsed":    "Elapsed Sec",
    "report.oracle_col_remaining":  "Remaining Sec",
    "report.oracle_col_wait_event": "Event",
    "report.oracle_col_wait_total": "Total Waits",
    "report.oracle_col_wait_time":  "Wait Time (s)",
    "report.oracle_col_wait_pct":   "Wait %",
    "report.oracle_col_wait_class": "Class",
    "report.oracle_col_buf_pool":   "Pool Name",
    "report.oracle_col_buf_hit":   "Hit %",
    "report.oracle_col_buf_bg":     "Block Gets",
    "report.oracle_col_buf_cg":     "Consistent Gets",
    "report.oracle_col_buf_phys":   "Physical Reads",
    "report.oracle_col_sql_text":   "SQL Text",
    "report.oracle_col_buf_mb":      "Buf MB",
    "report.oracle_col_disk_mb":     "Disk MB",
    "report.oracle_col_exec_cnt":    "Exec Count",
    "report.oracle_col_elapsed_s":   "Elapsed Sec",
    "report.oracle_col_gets_exec":  "Gets/Exec",
    "report.oracle_col_module":     "Module",
    "report.oracle_col_owner":      "Owner",
    "report.oracle_col_obj_type":   "Type",
    "report.oracle_col_count":      "Count",
    "report.oracle_col_obj_name":   "Object Name",
    "report.oracle_col_obj_status": "Status",
    "report.oracle_col_last_ddl":   "Last DDL Time",
    "report.oracle_col_lock_date":  "Lock Date",
    "report.oracle_col_expire":     "Expire Date",
    "report.oracle_col_create_time":"Created",
    "report.oracle_col_role_name":  "Role",
    "report.oracle_col_granted":    "Granted Users",
    "report.oracle_col_admin_opt":  "Admin Option",
    "report.oracle_col_session_key":"Session Key",
    "report.oracle_col_rtype":      "Type",
    "report.oracle_col_rstatus":    "Status",
    "report.oracle_col_start_time": "Start Time",
    "report.oracle_col_end_time":   "End Time",
    "report.oracle_col_size_gb":    "Size GB",
    "report.oracle_col_duration":   "Duration Min",
    "report.oracle_col_fb_on":      "Flashback On",
    "report.oracle_col_fb_ret":     "Retention Min",
    "report.oracle_col_fb_oldest":  "Oldest Flashback",
    "report.oracle_col_fb_ret_min": "Retention Min",
    "report.oracle_col_rb_owner":   "Owner",
    "report.oracle_col_rb_name":    "Original Name",
    "report.oracle_col_rb_type":    "Type",
    "report.oracle_col_rb_size_mb": "Size MB",
    "report.oracle_col_rb_recover": "Recoverable",
    "report.oracle_col_rb_purge":   "Purgeable",
    "report.oracle_col_dg_mode":    "Database Mode",
    "report.oracle_col_dg_protection": "Recovery Mode",
    "report.oracle_col_dg_protect_mode": "Protection Mode",
    "report.oracle_col_dg_standby": "Standby",
    "report.oracle_col_dest_id":    "Dest_ID",
    "report.oracle_col_dest_status":"Status",
    "report.oracle_col_dest_loc":   "Destination",
    "report.oracle_col_archiver":   "Archiver",
    "report.oracle_col_trans_mode": "Transport Mode",
    "report.oracle_col_inst":       "Inst#",
    "report.oracle_col_inst_name2": "Instance Name",
    "report.oracle_col_host2":      "Host",
    "report.oracle_col_status2":    "Status",
    "report.oracle_col_parallel2":  "Parallel",
    "report.oracle_col_crs_name":   "Name",
    "report.oracle_col_crs_type":   "Type",
    "report.oracle_col_crs_status": "Status",
    "report.oracle_col_crs_target": "Target",
    "report.oracle_col_crs_host":   "Host",
    "report.oracle_col_gno":        "Group#",
    "report.oracle_col_gnam":       "Name",
    "report.oracle_col_gstatus":    "Status",
    "report.oracle_col_gtype":      "Type",
    "report.oracle_col_total_mb":  "Total MB",
    "report.oracle_col_free_mb":    "Free MB",
    "report.oracle_col_free_pct":   "Free %",
    "report.oracle_col_snap_id":    "Snap ID",
    "report.oracle_col_btime":      "Begin Time",
    "report.oracle_col_etime":      "End Time",
    "report.oracle_col_elapsed_hr": "Elapsed HR",
    "report.oracle_col_error":     "Error",
    "report.oracle_col_job_name":   "Job Name",
    "report.oracle_col_job_status": "Status",
    "report.oracle_col_enabled":    "Enabled",
    "report.oracle_col_sched_type": "Schedule Type",
    "report.oracle_col_next_run":   "Next Run",
    "report.oracle_col_runs":       "Runs",
    "report.oracle_col_failures":   "Failures",
    "report.oracle_col_job_num":     "Job#",
    "report.oracle_col_job_content": "Content",
    "report.oracle_col_last_run":   "Last Run",
    "report.oracle_col_next_run2":  "Next Run",
    "report.oracle_col_broken":     "Broken",
    "report.oracle_col_alert_time": "Time",
    "report.oracle_col_alert_msg":  "Error Message (first 200 chars)",
    # HTML report specific
    "report.html_os_info":         "OS Host Information",
    "report.html_db_info":         "Database Basic Information",
    "report.html_version":         "Database Version and Patches",
    "report.html_tablespace":      "Tablespaces (Data Files)",
    "report.html_tablespace_temp": "Temporary Tablespaces",
    "report.html_redolog":         "Redo Logs",
    "report.html_controlfile":     "Control Files",
    "report.html_perf":            "Performance Metrics",
    "report.html_sessions":        "Session Status",
    "report.html_wait_events":     "Top 10 Wait Events",
    "report.html_buffer_hit":      "Buffer Cache Hit Ratio",
    "report.html_top_sql":         "Top SQL",
    "report.html_buf_gets":        "by Buffer Gets",
    "report.html_disk_reads":      "by Disk Reads",
    "report.html_invalid_obj":     "Invalid Objects",
    "report.html_invalid_detail":  "Details (excluding SYS/SYSTEM)",
    "report.html_users":           "Users and Security",
    "report.html_default_acc":     "Default Accounts (High Risk)",
    "report.html_locked_users":    "Locked/Expired Users",
    "report.html_admin_roles":     "Roles with Admin Privs (non-SYS/SYSTEM)",
    "report.html_backup":          "Backup Information",
    "report.html_rman":            "RMAN Backup Jobs (Last 30 Days)",
    "report.html_flashback":       "Flashback and Recycle Bin",
    "report.html_fb_config":       "Flashback Configuration",
    "report.html_recyclebin":      "Recycle Bin",
    "report.html_dataguard":       "Data Guard",
    "report.html_dg_mode":         "Database Mode",
    "report.html_arch_dest":       "Archive Destinations",
    "report.html_rac":             "RAC + ASM",
    "report.html_rac_inst":        "Instance Status",
    "report.html_crs":             "CRS Resources",
    "report.html_asm":             "ASM Disk Groups",
    "report.html_awr":            "AWR Snapshots",
    "report.html_jobs":            "Job Scheduler",
    "report.html_sched_jobs":      "Scheduler Jobs",
    "report.html_db_jobs":         "Database Jobs",
    "report.html_alert":           "Alert Log Errors (Last 7 Days)",
    "report.html_ai":              "AI Diagnosis Recommendations",
    "report.html_ai_disabled":     "AI diagnosis is not enabled or no advice available. Configure Ollama in ai_config.json and re-run inspection to get AI diagnosis.",
    "report.html_no_data":         "No Data",
    "report.html_no_rman":         "No RMAN backup records in the last 30 days",
    "report.html_no_rac":          "Not a RAC environment or no data",
    "report.html_no_alert":        "No Error-level Alert log entries in the last 7 days",
    "report.html_no_default_acc": "No default account data",
    "report.html_not_dataguard":   "Not a Data Guard environment or no data",
    # Cover page
    "report.cover_version_label": "Version",
    "report.cover_time_label":     "Inspection Time",

    # Oracle interactive CLI prompts
    "oracle_banner_title": "DBCheck - Oracle Inspector",
    "oracle_host_ip": "Host address",
    "oracle_port": "Port",
    "oracle_connect_by": "Connection Mode (S=SID / N=ServiceName)",
    "oracle_servicename": "ServiceName",
    "oracle_sid": "ORACLE_SID",
    "oracle_username": "Username",
    "oracle_password": "Password",
    "oracle_sysdba_prompt": "Connect as SYSDBA? (Y/N)",
    "oracle_ssh_use": "Configure SSH connection?",
    "oracle_ssh_host": "SSH Host address",
    "oracle_ssh_port": "SSH Port",
    "oracle_ssh_username": "SSH Username",
    "oracle_ssh_password": "SSH Password",
    "oracle_ssh_skip_warning": "SSH username and password cannot be empty. SSH collection skipped.",
    "oracle_output_dir": "Report output directory",
    "oracle_inspector_name": "Inspector",

    # Banner
    "oracle_banner_tool": "DBCheck Oracle Comprehensive Inspection Tool",
    "oracle_banner_subtitle": "OS-level + Database-level",

    # Oracle inspection logs
    "oracle_log_start": "Starting Oracle Comprehensive Inspection",
    "oracle_log_connect_db": "Connecting to Oracle database...",
    "oracle_log_connect_ok": "Connection successful",
    "oracle_log_connect_fail": "Connection failed",
    "oracle_log_get_version": "Fetching database version...",
    "oracle_log_collect_os": "Collecting OS-level information...",
    "oracle_log_ssh_ok": "SSH collection successful",
    "oracle_log_ssh_fail": "SSH collection failed",
    "oracle_log_local_ok": "Local collection completed",
    "oracle_log_db_inspect": "Running database inspection",
    "oracle_log_item_ok": "Query successful",
    "oracle_log_item_fail": "Query failed",
    "oracle_log_item_empty": "No data",
    "oracle_log_item_skip": "Skipped",
    "oracle_log_ai_diagnosis": "AI Diagnosis...",
    "oracle_log_ai_calling": "Calling AI diagnosis",
    "oracle_log_ai_ok": "AI diagnosis completed",
    "oracle_log_ai_empty": "AI diagnosis returned empty",
    "oracle_log_ai_disabled": "AI diagnosis disabled",
    "oracle_log_gen_report": "Generating inspection report...",
    "oracle_log_save_report": "Saving report...",
    "oracle_log_word_report": "Word report generation failed",
    "oracle_log_history_ok": "History saved",
    "oracle_log_history_fail": "Failed to save history",
    "oracle_log_complete": "Inspection complete",
    "oracle_log_time": "Time elapsed",
    "oracle_log_version": "Version",
    "oracle_log_need_sid_svc": "Must specify --sid or --servicename",
    "oracle_log_need_ssh_cred": "SSH collection requires both --ssh-user and --ssh-pass",
    "oracle_log_use_local": "Using local collection",
    "oracle_log_ai_timeout": "AI diagnosis timed out: model loading takes long. Please increase timeout in AI config and retry.",
    "oracle_log_ai_conn_fail": "AI diagnosis connection failed: please ensure Ollama service is running.",
    "oracle_log_ai_fail": "AI diagnosis failed",
    # Check item output
    "oracle_log_version_fmt": "Version: {ver}  (Major: {major})",
    "oracle_log_check_ok": "row(s)",  # unit only, number is prepended by f-string
    "oracle_log_check_fail": "Query failed: {error}",
    "oracle_log_check_empty": "No data",
    "oracle_log_check_skip": "Skipped",
    # AI summary
    "oracle_log_ai_wait_fmt": "{w0}: {w1} waits, {w2}s, {w3}%",
    "oracle_log_ai_blocked": "{n} blocked session(s)",
    "oracle_log_ai_no_blocked": "No blocked sessions",
    "oracle_log_ai_top_sql_fmt": "SQL_ID={s0}: Buf={s2}MB, Execs={s4}, Time={s5}s, Text={s1}",
    "oracle_log_time_secs": "{elapsed:.1f} seconds",
    # Check item display names
    "oracle_check_item_instance": "Instance Info",
    "oracle_check_item_database": "Database Info",
    "oracle_check_item_version": "Version & Patches",
    "oracle_check_item_tablespace": "Tablespace",
    "oracle_check_item_redolog": "Redo Logs",
    "oracle_check_item_controlfile": "Control Files",
    "oracle_check_item_sga_pga": "SGA/PGA Memory",
    "oracle_check_item_params": "Key Parameters",
    "oracle_check_item_undo": "Undo Info",
    "oracle_check_item_long_sql": "Long-running SQL",
    "oracle_check_item_perf": "Performance Metrics",
    "oracle_check_item_top_sql": "Top SQL",
    "oracle_check_item_invalid_obj": "Invalid Objects",
    "oracle_check_item_users": "User Security",
    "oracle_check_item_backup": "Backup Info",
    "oracle_check_item_flashback": "Flashback/Recycle Bin",
    "oracle_check_item_dataguard": "Data Guard",
    "oracle_check_item_rac_asm": "RAC+ASM",
    "oracle_check_item_awr": "AWR Snapshots",
    "oracle_check_item_jobs": "Job Scheduler",
    "oracle_check_item_alert": "Alert Log",

    "mysql_cli_ai_calling": "Calling AI diagnosis ({backend} / {model})...",
    "mysql_cli_back_menu": "Return to main menu? (y/n) [y]: ",
    "mysql_cli_banner": "DBCheck - MySQL Database Inspection Tool",
    "mysql_cli_batch_done": "Batch Inspection Complete",
    "mysql_cli_batch_mode": "Batch Inspection Mode",
    "mysql_cli_confirm_batch": "Start batch inspection? (y/n) [y]: ",
    "mysql_cli_conn_fail": "Connection test failed: {e}",
    "mysql_cli_create_excel": "Create Excel Configuration Template",
    "mysql_cli_create_template_now": "Create Excel template now? (y/n) [y]: ",
    "mysql_cli_db_conn_fail": "Database connection failed: {e}",
    "mysql_cli_excel_not_exist": "Excel template file does not exist. Please create it first.",
    "mysql_cli_inspector_prompt": "Inspector name (default Jack): ",
    "mysql_cli_invalid_choice": "Invalid choice. Please enter a number between 1 and 4.",
    "mysql_cli_local_collecting": "Collecting local system info",
    "mysql_cli_menu_item1": "1. Single Instance Inspection",
    "mysql_cli_menu_item2": "2. Batch Inspection (from Excel)",
    "mysql_cli_menu_item3": "3. Create Excel Configuration Template",
    "mysql_cli_menu_item4": "4. Exit",
    "mysql_cli_query_fail": "Database query failed: {e}",
    "mysql_cli_report_dir": "Report output directory: reports/",
    "mysql_cli_report_fail": "Report generation failed: {name}",
    "mysql_cli_report_filename": "MySQL_Inspection_{name}_{ts}",
    "mysql_cli_report_ok": "Report generated: {fname}",
    "mysql_cli_risk_fail": "Risk analysis failed: {e}",
    "mysql_cli_single_mode": "Single Instance Inspection Mode",
    "mysql_cli_sql_template_fail": "Failed to read SQL template: {e}",
    "mysql_cli_ssh_collecting": "Collecting system info via SSH: {host}",
    "mysql_cli_ssh_suffix": "(with system info)",
    "mysql_cli_start_inspect_n": "Starting inspection of {name}...",
    "mysql_cli_starting": "Starting inspection...",
    "mysql_cli_step_fail": "Step {name} failed: {e}",
    "mysql_cli_success_count": "Successful: {s}/{t} database(s)",
    "mysql_cli_sysinfo_fail": "System info collection failed: {e}",
    "mysql_cli_testing_connection": "Testing connection to {ip}:{port}...",
    "mysql_cli_thanks": "Thank you for using DBCheck MySQL Database Inspection Tool!",
    "mysql_cli_total_time": "Total execution time: {t:.2f} seconds",
    "mysql_cli_version": "Database version: MySQL {ver}",
    "mysql_cli_version_fail": "Failed to get version info: {e}",
    "mysql_cli_will_inspect_n": "Will inspect the following {n} database(s):",
    "mysql_cli_word_fail": "Word document generation failed: {e}",
    "mysql_cli_progress_prefix": "Inspection Progress:",
    "mysql_cli_progress_step": "Step {i}/{total}",
    "mysql_cli_sysinfo_suffix": "Collecting System Info",
    "mysql_cli_risk_suffix": "Analyzing Risks & Advice",
    "mysql_cli_complete_suffix": "Complete",
    "mysql_cli_db_info_title": "Enter database connection information:",
    "mysql_cli_host_prompt": "Host address [localhost]: ",
    "mysql_cli_port_prompt": "Port [3306]: ",
    "mysql_cli_port_invalid": "Invalid port, using default 3306",
    "mysql_cli_user_prompt": "Username [root]: ",
    "mysql_cli_password_prompt": "Password: ",
    "mysql_cli_dbname_prompt": "Database name (for report label) [MySQL_Server]: ",
    "mysql_cli_ssh_config": "System Information Collection Configuration:",
    "mysql_cli_ssh_info_note": "To collect system info (CPU, memory, disk, etc.), configure SSH connection",
    "mysql_cli_ssh_enable_prompt": "Configure SSH connection? (y/n) [n]: ",
    "mysql_cli_ssh_host_prompt": "SSH host address [{host}]: ",
    "mysql_cli_ssh_port_prompt": "SSH port [22]: ",
    "mysql_cli_ssh_port_invalid": "Invalid SSH port, using default 22",
    "mysql_cli_ssh_user_prompt": "SSH username [root]: ",
    "mysql_cli_ssh_auth_prompt": "SSH auth method: 1.Password 2.Key file [1]: ",
    "mysql_cli_ssh_key_prompt": "SSH private key file path: ",
    "mysql_cli_ssh_key_not_exist": "Private key file not found: {path}",
    "mysql_cli_ssh_password_prompt": "SSH password: ",
    "mysql_cli_verifying_mysql": "Verifying MySQL connection {host}:{port}...",
    "mysql_cli_mysql_success": "Connected to MySQL {host}:{port}",
    "mysql_cli_mysql_fail": "MySQL connection failed: {e}",
    "mysql_cli_verifying_ssh": "Verifying SSH connection {host}:{port}...",
    "mysql_cli_ssh_success": "Connected to SSH {host}:{port}",
    "mysql_cli_ssh_fail_no_msg": "SSH connection failed",
    "mysql_cli_ssh_fail": "SSH connection failed: {e}",
    "mysql_cli_retry_yes": "Retry input? (y/n) [y]: ",
    "mysql_cli_retry_no": "Retry input? (y/n) [n]: ",
    "mysql_cli_banner_title": "DBCheck - MySQL Database Inspection Tool",
    "mysql_cli_banner_subtitle": "Single Instance / Batch / Word Report / SSH Collection",
    "mysql_cli_datadir_found": "Obtained MySQL datadir via SSH: {path}",
    "mysql_cli_license_fail": "❌ {message}",
    "mysql_cli_license_pos": "✅ {message}",
    "mysql_cli_license_pos_info": "✅ {message}",
    "mysql_cli_license_file_pos": "License file location: {path}",
    "mysql_cli_recreate_license_prompt": "Try to recreate license? (y/n) [y]: ",
    "mysql_cli_license_recreate_fail": "❌ Failed to recreate license: {message}",
    "mysql_cli_license_contact": "Please contact the administrator for a valid license",
    "mysql_cli_license_exception": "❌ License check exception: {e}",
    "mysql_cli_license_continue": "Program will continue, but some features may be limited",
    "mysql_cli_word_template_ok": "✅ Word template created: {path}",
    "mysql_cli_word_template_fail": "❌ Failed to create Word template: {e}",
    "mysql_cli_remote_ssh_fail": "SSH connection failed {host}:{port}: {e}",
    "mysql_cli_remote_cmd_fail": "Command execution failed: {cmd}, error: {e}",
    "mysql_cli_remote_cpu_fail": "Failed to get CPU info: {e}",
    "mysql_cli_remote_mem_fail": "Failed to get memory info: {e}",
    "mysql_cli_remote_disk_fail": "Failed to get disk info: {e}",
    "mysql_cli_remote_datadir_fail": "Failed to get MySQL datadir: {e}",
    "mysql_cli_local_cpu_fail": "Failed to get CPU info: {e}",
    "mysql_cli_local_mem_fail": "Failed to get memory info: {e}",
    "mysql_cli_local_disk_fail": "Failed to get disk info: {e}",
    "mysql_cli_host_disk_fail": "Failed to get disk usage: {e}",
    "pg_cli_ai_calling": "Calling AI diagnosis ({backend} / {model})...",
    "pg_cli_back_menu": "Return to main menu? (y/n) [y]: ",
    "pg_cli_banner": "DBCheck - PostgreSQL Database Inspection Tool",
    "pg_cli_banner_title": "DBCheck - PostgreSQL Database Inspection Tool",
    "pg_cli_banner_subtitle": "Single Instance / Batch / Word Report / SSH Collection",
    "pg_cli_batch_done": "Batch Inspection Complete",
    "pg_cli_batch_mode": "Batch Inspection Mode",
    "pg_cli_confirm_batch": "Start batch inspection? (y/n) [y]: ",
    "pg_cli_conn_fail": "Connection test failed: {e}",
    "pg_cli_create_excel": "Create Excel Configuration Template",
    "pg_cli_create_template_now": "Create Excel template now? (y/n) [y]: ",
    "pg_cli_db_conn_fail": "Database connection failed: {e}",
    "pg_cli_excel_not_exist": "Excel template file does not exist. Please create it first.",
    "pg_cli_inspector_prompt": "Inspector name (default Jack): ",
    "pg_cli_invalid_choice": "Invalid choice. Please enter a number between 1 and 4.",
    "pg_cli_local_collecting": "Collecting local system info",
    "pg_cli_menu_item1": "1. Single Instance Inspection",
    "pg_cli_menu_item2": "2. Batch Inspection (from Excel)",
    "pg_cli_menu_item3": "3. Create Excel Configuration Template",
    "pg_cli_menu_item4": "4. Exit",
    "pg_cli_query_fail": "Database query failed: {e}",
    "pg_cli_report_dir": "Report output directory: reports/",
    "pg_cli_report_fail": "Report generation failed: {name}",
    "pg_cli_report_filename": "PostgreSQL_Inspection_{name}_{ts}",
    "pg_cli_report_ok": "Report generated: {fname}",
    "pg_cli_risk_fail": "Risk analysis failed: {e}",
    "pg_cli_single_mode": "Single Instance Inspection Mode",
    "pg_cli_sql_template_fail": "Failed to read SQL template: {e}",
    "pg_cli_ssh_collecting": "Collecting system info via SSH: {host}",
    "pg_cli_ssh_suffix": "(with system info)",
    "pg_cli_start_inspect_n": "Starting inspection of {name}...",
    "pg_cli_starting": "Starting inspection...",
    "pg_cli_step_fail": "Step {name} failed: {e}",
    "pg_cli_success_count": "Successful: {s}/{t} database(s)",
    "pg_cli_sysinfo_fail": "System info collection failed: {e}",
    "pg_cli_testing_connection": "Testing connection to {ip}:{port}...",
    "pg_cli_thanks": "Thank you for using DBCheck PostgreSQL Database Inspection Tool!",
    "pg_cli_total_time": "Total execution time: {t:.2f} seconds",
    "pg_cli_version": "Database version: PostgreSQL {ver}",
    "pg_cli_version_fail": "Failed to get version info: {e}",
    "pg_cli_will_inspect_n": "Will inspect the following {n} database(s):",
    "pg_cli_word_fail": "Word document generation failed: {e}",
    "mysql_cli_choose_prompt": "Select inspection mode (1-4): ",
    "pg_cli_choose_prompt": "Select inspection mode (1-4): ",
    "pg_cli_ssh_config": "System Information Collection Configuration:",
    "pg_cli_ssh_info_note": "To collect system info (CPU, memory, disk, etc.), configure SSH connection",
    "pg_cli_ssh_enable_prompt": "Configure SSH connection? (y/n) [n]: ",
    "pg_cli_retry_yes": "Retry input? (y/n) [y]: ",
    "pg_cli_retry_no": "Retry input? (y/n) [n]: ",
    "pg_cli_verifying_pg": "Verifying PostgreSQL connection {host}:{port}...",
    "pg_cli_verifying_ssh": "Verifying SSH connection {host}:{port}...",
    "pg_cli_ssh_collecting": "Collecting system info via SSH: {host}",
    "pg_cli_ai_calling": "Calling AI diagnosis ({backend} / {model})...",
    "pg_cli_word_ok": "Word template created: {path}",
    "pg_cli_word_fail": "Word template creation failed: {e}",
    "pg_cli_thanks": "Thank you for using DBCheck PostgreSQL Database Inspection Tool!",
    "pg_cli_db_info_title": "Enter database connection information:",
    "pg_cli_host_prompt": "Host address [localhost]: ",
    "pg_cli_port_prompt": "Port [5432]: ",
    "pg_cli_port_invalid": "⚠️ Invalid port, using default 5432",
    "pg_cli_user_prompt": "Username [postgres]: ",
    "pg_cli_password_prompt": "Password: ",
    "pg_cli_dbname_prompt": "Database name (for report label) [postgres]: ",
    "pg_cli_ssh_host_prompt": "SSH host address [{host}]: ",
    "pg_cli_ssh_port_prompt": "SSH port [22]: ",
    "pg_cli_ssh_port_invalid": "⚠️ Invalid SSH port, using default 22",
    "pg_cli_ssh_user_prompt": "SSH username [root]: ",
    "pg_cli_ssh_auth_prompt": "SSH auth method: 1.Password 2.Key file [1]: ",
    "pg_cli_ssh_key_prompt": "SSH private key file path: ",
    "pg_cli_ssh_key_not_exist": "❌ Private key file not found: {path}",
    "pg_cli_ssh_password_prompt": "SSH password: ",
    "pg_cli_pg_success": "✅ Connected to PostgreSQL {host}:{port}",
    "pg_cli_pg_fail": "❌ PostgreSQL connection failed: {e}",
    "pg_cli_ssh_success": "✅ Connected to SSH {host}:{port}",
    "pg_cli_ssh_fail_no_msg": "❌ SSH connection failed",
    "pg_cli_ssh_fail": "❌ SSH connection failed: {e}",
    "pg_cli_db_conn_fail": "❌ Database connection failed: {e}",
    "pg_cli_sql_template_fail": "❌ Failed to read SQL template: {e}",
    "pg_cli_version_fail": "❌ Failed to get version info: {e}",
    "pg_cli_step_fail": "⚠️ Step {name} failed: {e}",
    "pg_cli_query_fail": "❌ Database query failed: {e}",
    "pg_cli_local_sysinfo": "Collecting local system info",
    "pg_cli_sysinfo_fail": "❌ Failed to collect system info: {e}",
    "pg_cli_risk_fail": "❌ Risk analysis failed: {e}",
    "pg_cli_word_fail_gen": "❌ Failed to generate Word document: {e}",
    "pg_cli_report_fail": "❌ Report generation failed: {name}",
    "pg_cli_excel_created": "✅ Excel template created: {path}",
    "pg_cli_excel_fill_note": "📝 Please fill in database connection info in the template, then use batch inspection",
    "pg_cli_excel_ssh_note": "🔐 Fill in SSH connection info to collect system information",
    "pg_cli_excel_create_fail": "❌ Excel template creation failed: {e}",
    "pg_cli_excel_not_exist_batch": "❌ Excel template file not found: {path}",
    "pg_cli_excel_no_valid_config": "❌ No valid database configuration in Excel template",
    "pg_cli_excel_read_count": "✅ Read {n} database configurations from Excel template",
    "pg_cli_excel_ssh_count": "🔐 {n} configurations include SSH connection info for system info collection",
    "pg_cli_excel_read_fail": "❌ Failed to read Excel template: {e}",
    "pg_cli_progress_prefix": "Inspection Progress:",
    "pg_cli_progress_step": "Step {i}/{total}",
    "pg_cli_sysinfo_suffix": "Collecting System Info",
    "pg_cli_risk_suffix": "Analyzing Risks & Advice",
    "pg_cli_complete_suffix": "Complete",

    # DM8 CLI i18n
    "dm8_driver_missing": "Dameng driver library is missing. Please install with:",
    "dm8_driver_path_note": "Ensure the dpi dynamic library (included with Dameng DB) is in system PATH",
    "dm8_banner_title": "DBCheck - DM8 Inspector",
    "dm8_host_prompt": "Host address: ",
    "dm8_port_prompt": "Port [5236]: ",
    "dm8_user_prompt": "Username [SYSDBA]: ",
    "dm8_password_prompt": "Password: ",
    "dm8_dbname_prompt": "Database name [DAMENG]: ",
    "dm8_inspector_prompt": "Inspector [Jack]: ",
    "dm8_ssh_enable_prompt": "Configure SSH for system info collection? [y/N]: ",
    "dm8_ssh_host_prompt": "  SSH host [same as DB host]: ",
    "dm8_ssh_port_prompt": "  SSH port [22]: ",
    "dm8_ssh_user_prompt": "  SSH user [root]: ",
    "dm8_ssh_password_prompt": "  SSH password (leave empty to skip): ",
    "dm8_report_dir": "Report output directory:",
    "dm8_db_conn_fail": "[FAIL] Database connection failed, please check parameters and retry",
    "dm8_press_enter_return": "Press Enter to return...",
    "dm8_report_ok": "[OK] Report generated: {ofile}",
    "dm8_report_fail": "[FAIL] Report generation failed",
    "dm8_inspection_fail": "[FAIL] Inspection execution failed",
    "dm8_back_menu_prompt": "Return to main menu? [y/N]: ",
    "dm8_template_ok": "[OK] DM8 report template created: {tpl}",
    "dm8_conn_ok": "[OK] DM8 connection successful: {user}@{H}:{P}",
    "dm8_conn_retry": "  [RETRY] Connection retry #{n} ({H}:{P})...",
    "dm8_conn_retry_ok": "[OK] DM8 connection successful (retry #{n}): {user}@{H}:{P}",
    "dm8_conn_retry_fail": "  Retry failed CODE:{code}: {err}",
    "dm8_conn_fail_code": "[FAIL] DM8 connection failed [CODE:{code}]: {hint}",
    "dm8_ssh_conn_fail": "SSH connection failed {host}:{port}",
    "dm8_sql_template_fail": "[FAIL] Failed to read SQL template: {e}",
    "dm8_version_fail": "[FAIL] Failed to get version: {e}",
    "dm8_query_loop_fail": "\n[FAIL] Database query loop exception: {e}",
    "dm8_ssh_collecting": "[INFO] Collecting system info via SSH: {host}",
    "dm8_ssh_conn_fail_skip": "[WARN] SSH connection failed, skipping remote system info collection",
    "dm8_sysinfo_fail": "\n[FAIL] Failed to collect system info: {e}",
    "dm8_warn_hint": "[WARN]  [{item}] {hint0}\n    💡 Suggestion: {hint1}",
    "dm8_warn_db_err": "[WARN]  [{item}] Database error ({code}): {e}",
    "dm8_warn_exc": "[WARN]  [{item}] {type}: {e}",
    "dm8_ai_calling": "\n🤖 Calling AI diagnosis ({backend} / {model})...",
    "dm8_starting": "Starting DM8 inspection...",
    "dm8_alt_render_fail": "Fallback rendering also failed: {e}",
    # DM8 progress bar i18n
    "dm8_progress_prefix": "DM8 Inspection:",
    "dm8_progress_sysinfo": "Collecting System Info",
    "dm8_progress_health": "Smart Health Evaluation",
    "dm8_progress_ai": "AI Diagnosis",
    "dm8_progress_done": "Complete [OK]",

    # Web UI
    "webui.log_generating_report": "Generating Word report...",
    "webui.err_template_create": "Failed to create report template",
    "webui.err_report_generate": "Failed to generate report file",
    "webui.log_report_ok": "Report generated: {fname}",
    "webui.mysql_report_filename": "MySQLInspection_{name}_{ts}",
    "webui.pg_report_filename": "PostgreSQLInspection_{name}_{ts}",
    "webui.oracle_report_filename": "OracleInspection_{name}_{ts}",
    "webui.dm_report_filename": "DMInspection_{name}_{ts}",
    "webui.sqlserver_report_filename": "SQLServerInspection_{name}_{ts}",

    # SQL Server CLI i18n
    "sqlserver.report_title": "SQL Server Database Health Inspection Report",
    "sqlserver.chapter_overview": "Database Overview",
    "sqlserver.chapter_version": "Version & Instance Information",
    "sqlserver.chapter_databases": "Database Status",
    "sqlserver.chapter_connections": "Connection Statistics",
    "sqlserver.chapter_sessions": "Active Sessions",
    "sqlserver.chapter_wait_stats": "Wait Statistics",
    "sqlserver.chapter_locks": "Locks & Blocking",
    "sqlserver.chapter_backups": "Backup Status",
    "sqlserver.chapter_summary": "Health Summary",
    "sqlserver.label": "Database Label",
    "sqlserver.inspector": "Inspector",
    "sqlserver.server": "Server",
    "sqlserver.report_time": "Report Time",
    "sqlserver.config_name": "Configuration Item",
    "sqlserver.config_value": "Configuration Value",
    "sqlserver.db_name": "Database Name",
    "sqlserver.state": "State",
    "sqlserver.recovery_model": "Recovery Model",
    "sqlserver.data_size_mb": "Data Size (MB)",
    "sqlserver.log_size_mb": "Log Size (MB)",
    "sqlserver.spid": "SPID",
    "sqlserver.login": "Login Name",
    "sqlserver.host": "Host",
    "sqlserver.program": "Program",
    "sqlserver.status": "Status",
    "sqlserver.cpu_ms": "CPU Time (ms)",
    "sqlserver.wait_type": "Wait Type",
    "sqlserver.waiting_tasks": "Waiting Tasks",
    "sqlserver.wait_time_ms": "Wait Time (ms)",
    "sqlserver.wait_pct": "Wait Percentage (%)",
    "sqlserver.lock_type": "Lock Type",
    "sqlserver.lock_mode": "Lock Mode",
    "sqlserver.lock_count": "Lock Count",
    "sqlserver.backup_date": "Backup Time",
    "sqlserver.backup_type": "Backup Type",
    "sqlserver.size_mb": "Size (MB)",
    "sqlserver.duration_min": "Duration (min)",
    "sqlserver.metric": "Metric",
    "sqlserver.value": "Value",
    "sqlserver.no_data": "No Data",
    "sqlserver.summary_title": "Health Summary",
    "sqlserver.health_status": "Health Status",
    "sqlserver.issue_summary": "Issue Summary",
    "sqlserver.recommendations": "Recommendations",
    "sqlserver.high": "High Risk",
    "sqlserver.medium": "Medium Risk",
    "sqlserver.low": "Low Risk",
    "sqlserver.status_healthy": "Healthy",
    "sqlserver.status_warning": "Warning",
    "sqlserver.status_critical": "Critical",
    "sqlserver.no_issues": "No issues found",
    "sqlserver.conn_success": "[OK] SQL Server connection successful",
    "sqlserver.conn_failed": "[FAIL] SQL Server connection failed: %s",
    "sqlserver.start_collection": "Starting data collection...",
    "sqlserver.collect_version": "[INFO] Collecting version info",
    "sqlserver.collect_config": "[INFO] Collecting configuration",
    "sqlserver.collect_databases": "[INFO] Collecting database status",
    "sqlserver.collect_connections": "[INFO] Collecting connection statistics",
    "sqlserver.collect_sessions": "[INFO] Collecting active sessions",
    "sqlserver.collect_blocking": "[INFO] Collecting blocking info",
    "sqlserver.collect_wait_stats": "[INFO] Collecting wait statistics",
    "sqlserver.collect_locks": "[INFO] Collecting lock info",
    "sqlserver.collect_backups": "[INFO] Collecting backup info",
    "sqlserver.collect_backup_missing": "[INFO] Checking missing backups",
    "sqlserver.collect_memory": "[INFO] Collecting memory info",
    "sqlserver.collect_buffer": "[INFO] Collecting buffer pool info",
    "sqlserver.collect_top_queries": "[INFO] Collecting TOP queries",
    "sqlserver.collect_host": "[INFO] Collecting host resources",
    "sqlserver.collection_complete": "[OK] Data collection complete",
    "sqlserver.collection_failed": "[FAIL] Data collection failed: %s",
    "sqlserver.starting_inspection": "Starting inspection",
    "sqlserver.running_analysis": "[INFO] Running intelligent analysis...",
    "sqlserver.generating_report": "[INFO] Generating inspection report...",
    "sqlserver.inspection_complete": "[OK] Inspection complete",
    "sqlserver.report_saved": "Report saved",
    "sqlserver.suggest_cxpacket": "Consider adjusting MAX DOP parameter or check parallel queries",
    "sqlserver.suggest_pageiolatch": "Check disk IO performance or increase memory",
    "sqlserver.suggest_lock": "Check long-running transactions",
    "sqlserver.suggest_blocking": "Identify and resolve blocking source",
    "sqlserver.suggest_backup": "Execute database backup immediately",
    "sqlserver.suggest_connections": "Check for connection leaks or increase max connections",
    "sqlserver.suggest_memory": "Increase memory or optimize queries",
}


path: i18n/__init__.py
content: # -*- coding: utf-8 -*-
"""
DBCheck i18n 模块
=================
提供多语言支持，所有面向用户的字符串均通过 t(key) 获取。
默认语言从 dbc_config.json 读取，也可通过启动参数 --lang 覆盖。

用法：
    from i18n import t, set_lang, get_lang
    print(t("cli.main_menu_title"))
"""

import os
import json

from .zh import ZI
from .en import EN

# ── 配置路径 ────────────────────────────────────────────────────────────────
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_CONFIG_FILE = os.path.join(os.path.dirname(_SCRIPT_DIR), 'dbc_config.json')

# 全局语言覆盖（CLI --lang 参数临时设置，不写文件）
_override_lang = None


# ── 语言配置读写 ────────────────────────────────────────────────────────────

def _load_config():
    if os.path.exists(_CONFIG_FILE):
        try:
            with open(_CONFIG_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception:
            pass
    return {}


def _save_config(cfg):
    with open(_CONFIG_FILE, 'w', encoding='utf-8') as f:
        json.dump(cfg, f, ensure_ascii=False, indent=4)


def get_lang():
    """
    获取当前语言。
    优先级：CLI --lang 参数 > dbc_config.json 的 language 字段 > 'zh'
    """
    if _override_lang:
        return _override_lang
    return _load_config().get('language', 'zh')


def set_lang(lang, persist=True):
    """
    设置当前语言。

    :param lang:     'zh' 或 'en'
    :param persist:  是否写入 dbc_config.json（Web UI 保存时为 True，
                     CLI --lang 参数覆盖时为 False，不影响配置文件）
    """
    lang = 'en' if str(lang).lower().startswith('en') else 'zh'
    if persist:
        cfg = _load_config()
        cfg['language'] = lang
        _save_config(cfg)
    else:
        # CLI 模式：全局变量覆盖，不写文件
        global _override_lang
        _override_lang = lang


# ── 翻译查询 ────────────────────────────────────────────────────────────────

def t(key, lang=None):
    """
    根据 key 返回翻译后的字符串。

    :param key:  翻译 key，如 "cli.main_menu_title"，"report.health_excellent"
    :param lang: 指定语言（可选，默认从 get_lang() 获取）
    :return:     翻译字符串，未找到时返回原 key
    """
    if lang is None:
        lang = get_lang()

    data = EN if lang.startswith('en') else ZI
    val = data.get(key)

    if val is not None:
        return str(val)

    # 回退到中文
    val = ZI.get(key)
    if val is not None:
        return str(val)

    return key


# ── 便捷函数（供 Web UI 使用）───────────────────────────────────────────────

def get_all_translations(lang=None):
    """返回指定语言的全部翻译字典"""
    if lang is None:
        lang = get_lang()
    return EN if lang.startswith('en') else ZI


def get_language_display(lang=None):
    """返回语言对应的显示名称"""
    if lang is None:
        lang = get_lang()
    return "English" if lang.startswith('en') else "中文"


path: requirements.txt
content: # DBCheck - Database Inspection Tool
# Install: pip install -r requirements.txt

# ── Core ──────────────────────────────────────────────────────────────────────
python-docx>=0.8.10
docxtpl>=0.16.0
psutil>=5.9.0

# ── Web UI ───────────────────────────────────────────────────────────────────
flask>=2.0.0
flask-socketio>=5.0.0

# ── Database Drivers ──────────────────────────────────────────────────────────
pymysql>=1.0.0          # MySQL / TiDB
psycopg2-binary>=2.9.0   # PostgreSQL
oracledb>=1.4.0         # Oracle (recommended, pure Python, no Instant Client)
# cx_Oracle>=8.0.0      # Oracle (legacy, requires Oracle Instant Client)
dmpython>=1.0.0         # Dameng DM8
pyodbc>=4.0.0           # SQL Server (also requires ODBC Driver 17)

# ── SSH & Remote Collection ───────────────────────────────────────────────────
paramiko>=2.10.0

# ── Batch Inspection & Data Processing ───────────────────────────────────────
openpyxl>=3.0.0
pandas>=1.3.0

# ── PDF Export ───────────────────────────────────────────────────────────────
reportlab>=4.0.0          # PDF report generation (for config baseline & index health PDF export)
# docx2pdf>=0.1.0        # Windows PDF conversion (optional, alternative to LibreOffice)


path: scripts/desensitize.py
content: """
报告脱敏工具 - DBCheck 内置脱敏处理器

将巡检上下文中的敏感信息替换为掩码格式：
  IP地址  → 10.x.x.x
  端口    → ***
  用户名  → ***
  服务名  → ***
  主机名  → DB-HOST-***

使用方式：
  from desensitize import apply_desensitization
  ctx_desens = apply_desensitization(context)
  savedoc = mod.saveDoc(ctx_desens, ofile, ifile, inspector_name)
"""

import re

__all__ = ['Desensitizer', 'apply_desensitization']


class Desensitizer:
    """
    脱敏处理器。

    对 context 字典做深拷贝和原地脱敏替换。
    支持 MySQL / PostgreSQL / DM8 / Oracle Full / SQL Server 五种格式。
    """

    def __init__(self):
        pass

    def _desens_ip(self, val):
        """IP 地址掩码，保留 A.B.x.x 格式"""
        if isinstance(val, str):
            return '10.x.x.x'
        return val

    def _desens_port(self, val):
        """端口号掩码"""
        return '***'

    def _desens_user(self, val):
        """用户名掩码"""
        return '***'

    def _desens_hostname(self, val):
        """主机名掩码"""
        if isinstance(val, str) and val:
            return 'DB-HOST-***'
        return val

    def _desens_service_name(self, val):
        """Oracle 服务名 / SID 掩码"""
        return '***'

    def _desens_str_field(self, val):
        """通用字符串字段脱敏（用户名/IP/主机名混合出现时）"""
        if not isinstance(val, str):
            return val
        # 如果是 IP 格式（含有 .），做 IP 掩码
        if re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', val):
            return '10.x.x.x'
        # 否则用户名掩码
        return '***'

    def apply(self, context: dict) -> dict:
        """
        对 context 做脱敏处理，返回新的 context（深拷贝）。

        支持的字段模式（兼容所有数据库类型）：
        - ip / host / ssh_host          → 10.x.x.x
        - port                          → ***
        - co_name / service_name / sid → ***
        - ssh_user / user / db_user    → ***
        - hostname / sys_hostname      → DB-HOST-***
        - auto_analyze[].col5 (负责人)  → ***
        """
        import copy
        ctx = copy.deepcopy(context)

        # ── 顶层字段脱敏 ──────────────────────────────────────────────────

        # IP 相关字段（MySQL/PG/DM 格式：list of dict）
        for key in ('ip', 'host', 'ssh_host'):
            if key in ctx:
                val = ctx[key]
                if isinstance(val, list) and len(val) > 0:
                    for item in val:
                        if isinstance(item, dict) and 'IP' in item:
                            item['IP'] = self._desens_ip(item['IP'])
                        elif isinstance(item, dict) and 'Host' in item:
                            item['Host'] = self._desens_ip(item['Host'])
                elif isinstance(val, str):
                    ctx[key] = self._desens_ip(val)
                elif isinstance(val, dict):
                    for k2 in val:
                        ctx[key][k2] = self._desens_ip(str(val[k2]))

        # 端口
        for key in ('port', 'ssh_port'):
            if key in ctx:
                val = ctx[key]
                if isinstance(val, list) and len(val) > 0:
                    for item in val:
                        if isinstance(item, dict) and 'PORT' in item:
                            item['PORT'] = self._desens_port(item['PORT'])
                elif isinstance(val, (int, str)):
                    ctx[key] = [{'PORT': '***'}]

        # 实例名称 / 服务名 / SID
        for key in ('co_name', 'service_name', 'sid'):
            if key in ctx:
                val = ctx[key]
                if isinstance(val, list) and len(val) > 0:
                    for item in val:
                        if isinstance(item, dict):
                            for k2 in list(item.keys()):
                                if k2 in item:
                                    item[k2] = self._desens_service_name(item[k2])
                elif isinstance(val, str):
                    ctx[key] = self._desens_service_name(val)

        # 用户名（SSH）
        if 'ssh_user' in ctx and ctx['ssh_user']:
            ctx['ssh_user'] = self._desens_str_field(str(ctx['ssh_user']))

        # 主机名（system_info）
        sys_info = ctx.get('system_info', {})
        if isinstance(sys_info, dict):
            if 'hostname' in sys_info:
                sys_info['hostname'] = self._desens_hostname(str(sys_info['hostname']))
            if 'host' in sys_info:
                sys_info['host'] = self._desens_hostname(str(sys_info['host']))
            # 磁盘列表中的设备名（避免暴露真实服务器）
            for disk in sys_info.get('disk_list', []):
                if 'device' in disk:
                    disk['device'] = disk.get('device', '/dev/sda1')  # 统一显示标准设备名
            ctx['system_info'] = sys_info

        # SSH 主机信息
        ssh_info = ctx.get('ssh_info', {})
        if isinstance(ssh_info, dict):
            if 'host' in ssh_info:
                ssh_info['host'] = self._desens_ip(str(ssh_info['host']))
            if 'user' in ssh_info:
                ssh_info['user'] = self._desens_str_field(str(ssh_info['user']))
            ctx['ssh_info'] = ssh_info

        # auto_analyze 列表中可能出现的敏感字段（负责人等）
        for item in ctx.get('auto_analyze', []):
            if isinstance(item, dict):
                if item.get('col5') and 'DBA' not in str(item.get('col5', '')):
                    # 非 DBA 角色的人名脱敏（保留 DBA/System Admin 标记）
                    item['col5'] = '***'
                # col3 中的 IP/主机名片段
                col3 = item.get('col3', '')
                if isinstance(col3, str):
                    col3 = re.sub(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', '10.x.x.x', col3)
                    item['col3'] = col3

        # Oracle Full 格式的 db_info（dict 直接格式）
        db_info = ctx.get('db_info', {})
        if isinstance(db_info, dict):
            if 'host' in db_info:
                db_info['host'] = self._desens_ip(str(db_info['host']))
            if 'port' in db_info:
                db_info['port'] = '***'
            if 'user' in db_info:
                db_info['user'] = self._desens_str_field(str(db_info['user']))
            if 'service_name' in db_info:
                db_info['service_name'] = self._desens_service_name(str(db_info['service_name']))
            if 'sid' in db_info:
                db_info['sid'] = self._desens_service_name(str(db_info['sid']))

        return ctx


def apply_desensitization(context: dict) -> dict:
    """快捷函数：应用脱敏处理"""
    return Desensitizer().apply(context)

path: scripts/i18n/__init__.py
content: # -*- coding: utf-8 -*-
"""
DBCheck i18n 模块
=================
提供多语言支持，所有面向用户的字符串均通过 t(key) 获取。
默认语言从 dbc_config.json 读取，也可通过启动参数 --lang 覆盖。

用法：
    from i18n import t, set_lang, get_lang
    print(t("cli.main_menu_title"))
"""

import os
import json

from .zh import ZI
from .en import EN

# ── 配置路径 ────────────────────────────────────────────────────────────────
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_CONFIG_FILE = os.path.join(os.path.dirname(_SCRIPT_DIR), 'dbc_config.json')

# 全局语言覆盖（CLI --lang 参数临时设置，不写文件）
_override_lang = None


# ── 语言配置读写 ────────────────────────────────────────────────────────────

def _load_config():
    if os.path.exists(_CONFIG_FILE):
        try:
            with open(_CONFIG_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception:
            pass
    return {}


def _save_config(cfg):
    with open(_CONFIG_FILE, 'w', encoding='utf-8') as f:
        json.dump(cfg, f, ensure_ascii=False, indent=4)


def get_lang():
    """
    获取当前语言。
    优先级：CLI --lang 参数 > dbc_config.json 的 language 字段 > 'zh'
    """
    if _override_lang:
        return _override_lang
    return _load_config().get('language', 'zh')


def set_lang(lang, persist=True):
    """
    设置当前语言。

    :param lang:     'zh' 或 'en'
    :param persist:  是否写入 dbc_config.json（Web UI 保存时为 True，
                     CLI --lang 参数覆盖时为 False，不影响配置文件）
    """
    lang = 'en' if str(lang).lower().startswith('en') else 'zh'
    if persist:
        cfg = _load_config()
        cfg['language'] = lang
        _save_config(cfg)
    else:
        # CLI 模式：全局变量覆盖，不写文件
        global _override_lang
        _override_lang = lang


# ── 翻译查询 ────────────────────────────────────────────────────────────────

def t(key, lang=None):
    """
    根据 key 返回翻译后的字符串。

    :param key:  翻译 key，如 "cli.main_menu_title"，"report.health_excellent"
    :param lang: 指定语言（可选，默认从 get_lang() 获取）
    :return:     翻译字符串，未找到时返回原 key
    """
    if lang is None:
        lang = get_lang()

    data = EN if lang.startswith('en') else ZI
    val = data.get(key)

    if val is not None:
        return str(val)

    # 回退到中文
    val = ZI.get(key)
    if val is not None:
        return str(val)

    return key


# ── 便捷函数（供 Web UI 使用）───────────────────────────────────────────────

def get_all_translations(lang=None):
    """返回指定语言的全部翻译字典"""
    if lang is None:
        lang = get_lang()
    return EN if lang.startswith('en') else ZI


def get_language_display(lang=None):
    """返回语言对应的显示名称"""
    if lang is None:
        lang = get_lang()
    return "English" if lang.startswith('en') else "中文"


path: scripts/main.py
content: # -*- coding: utf-8 -*-
#
# Copyright (c) 2024 DBCheck Contributors
# [REDACTED_SECRET]
#
# This file is part of DBCheck, an open-source database health inspection tool.
# DBCheck is released under the MIT License.
# See LICENSE or visit https://opensource.org/licenses/MIT for full license text.
#
"""
数据库巡检工具统一入口
===========================
作者: Jack Ge
功能: 提供 MySQL、PostgreSQL、Oracle 和达梦 DM8 数据库巡检的统一入口
"""

import sys
import os
import warnings
import argparse

# 屏蔽打包后 jinja2/markupsafe 引发的 pkg_resources 废弃警告
warnings.filterwarnings("ignore", category=UserWarning, message="pkg_resources is deprecated")

# ── i18n 初始化（必须在其他模块导入之前）──────────────────────────
_i18n_loaded = False


def _init_i18n(lang_override=None):
    """初始化 i18n，设置全局语言偏好"""
    global _i18n_loaded
    if _i18n_loaded:
        return
    # lang_override: 来自 --lang 参数，CLI 临时覆盖，不写配置文件
    if lang_override:
        from i18n import set_lang
        set_lang(lang_override, persist=False)
    _i18n_loaded = True

# frozen 模式下 sys._MEIPASS 包含打包后的临时目录，
# 将其加入搜索路径以确保子模块能找到 version.py 等资源
if getattr(sys, 'frozen', False):
    sys.path.insert(0, sys._MEIPASS)

from version import __version__ as VER


def _enable_ansi():
    """Windows 旧终端开启 ANSI 颜色支持"""
    try:
        import ctypes
        if os.name == "nt":
            ctypes.windll.kernel32.SetConsoleMode(
                ctypes.windll.kernel32.GetStdHandle(-11), 7)
    except Exception:
        pass


_enable_ansi()
CYAN    = "\033[96m"
GREEN   = "\033[92m"
YELLOW  = "\033[93m"
MAGENTA = "\033[95m"
BOLD    = "\033[1m"
DIM     = "\033[2m"
RESET   = "\033[0m"
RED     = "\033[91m"
WHITE   = "\033[97m"
ORANGE  = "\033[38;2;255;140;0m"  # 真橙色 RGB


def _parse_args():
    parser = argparse.ArgumentParser(description='DBCheck - Database Inspection Tool')
    parser.add_argument('--lang', dest='lang', default=None,
                        help='Language: zh (Chinese, default) or en (English)')
    return parser.parse_args()


def print_banner():
    from i18n import t
    title = t("cli.main_banner_title")
    art = f"""
{CYAN}{BOLD}  ██████╗ ██████╗  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗
  ██╔══██╗██╔══██╗██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝
  ██║  ██║██████╔╝██║     ███████║██║     ██║     █████╔╝
  ██║  ██║██╔══██╗██║     ██╔══██║██╔══╝  ██║     ██╔═██╗
  ██████╔╝██████╔╝╚██████╗██║  ██║███████╗╚██████╗██║  ██╗
  ╚═════╝ ╚═════╝  ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝{RESET}
{BOLD}          🗄️  {title}  {VER}  {t("cli.main_menu_title")}{RESET}
{DIM}  ──────────────────────────────────────────────────────────{RESET}
{CYAN}{BOLD}    {t("cli.main_menu_line1")}{RESET}
{WHITE}{BOLD}    {t("cli.main_menu_line2")}{RESET}
{RED}{BOLD}    {t("cli.main_menu_line3")}{RESET}
{ORANGE}{BOLD}    {t("cli.main_menu_line4")}{RESET}
{YELLOW}{BOLD}    {t("cli.main_menu_line5")}{RESET}
{CYAN}{BOLD}    {t("cli.main_menu_line6")}{RESET}
{DIM}  ──────────────────────────────────────────────────────────{RESET}
{GREEN}{BOLD}    {t("cli.main_menu_line7")}{RESET}
{CYAN}{BOLD}    {t("cli.main_menu_line8")}{RESET}
{MAGENTA}{BOLD}    {t("cli.main_menu_line9")}{RESET}
{DIM}{BOLD}    {t("cli.main_menu_line10")}{RESET}
{DIM}  ──────────────────────────────────────────────────────────{RESET}
"""
    print(art)


# ── 数据库巡检函数 ────────────────────────────────────────────────

def _run_mysql():
    import main_mysql
    main_mysql.main()


def _run_pg():
    import main_pg
    main_pg.main()


def _run_dm():
    import main_dm
    main_dm.main()


def _run_sqlserver():
    import main_sqlserver
    main_sqlserver.main()

def _run_tidb():
    import main_tidb
    main_tidb.main()


def _run_oracle_full():
    """Oracle 全面巡检（增强版，基于 OS 层 + 数据库层）"""
    import main_oracle_full
    import sys
    sys.argv = ['main_oracle_full']      # 重置，避免父进程 argv 干扰子模块的 argparse
    main_oracle_full.main()


# ── 批量模板生成 ─────────────────────────────────────────────────

def _run_template_menu():
    from i18n import t
    while True:
        print(f"\n{BOLD}{'='*50}{RESET}")
        print(f"{YELLOW}{BOLD}   {t('cli.batch_menu_title')}{RESET}")
        print(f"{DIM}{'='*50}{RESET}")
        print(f"  {GREEN}1{RESET}. {t('cli.template_mysql')}")
        print(f"  {CYAN}2{RESET}. {t('cli.template_pg')}")
        print(f"  {RED}3{RESET}. {t('cli.template_dm')}")
        print(f"  {DIM}{t('cli.batch_menu_opt0')}{RESET}")
        print(f"{DIM}{'='*50}{RESET}")
        sub = input(f"{t('cli.batch_menu_prompt')}").strip()

        if sub == '1':
            import main_mysql
            if hasattr(main_mysql, 'create_excel_template'):
                main_mysql.create_excel_template()
            else:
                print(t("cli.batch_menu_not_support").format("MySQL"))
        elif sub == '2':
            import main_pg
            if hasattr(main_pg, 'create_excel_template'):
                main_pg.create_excel_template()
            else:
                print(t("cli.batch_menu_not_support").format("PostgreSQL"))
        elif sub == '3':
            import main_dm
            if hasattr(main_dm, 'create_excel_template'):
                main_dm.create_excel_template()
            else:
                print(t("cli.batch_menu_not_support").format("DM8"))
        elif sub in ('0', ''):
            break
        else:
            print(f"\n{t('cli.batch_menu_invalid')}")


# ── Web UI ────────────────────────────────────────────────────────

def _run_web_ui():
    """启动 Web UI"""
    from i18n import t
    import web_ui
    print(f"\n{t('cli.webui_starting')}")
    print(f"   {t('cli.webui_stop_hint')}\n")
    try:
        web_ui.socketio.run(web_ui.app, host='0.0.0.0', port=5003)
    except KeyboardInterrupt:
        print(f"\n{t('cli.webui_stopped')}")


# ── 主循环 ───────────────────────────────────────────────────────

def main():
    from i18n import t
    while True:
        print_banner()
        choice = input(t("cli.main_menu_prompt")).strip()

        if choice == '1':
            print(f"\n{t('cli.main_menu_mysql_starting')}\n")
            _run_mysql()
        elif choice == '2':
            print(f"\n{t('cli.main_menu_pg_starting')}\n")
            _run_pg()
        elif choice == '3':
            print(f"\n{t('cli.main_menu_oracle_starting')}\n")
            _run_oracle_full()
        elif choice == '4':
            print(f"\n{t('cli.main_menu_sqlserver_starting')}\n")
            _run_sqlserver()
        elif choice == '5':
            print(f"\n{t('cli.main_menu_dm_starting')}\n")
            _run_dm()
        elif choice == '6':
            print(f"\n{t('cli.main_menu_tidb_starting')}\n")
            _run_tidb()
        elif choice == '7':
            _run_web_ui()
        elif choice == '8':
            _run_template_menu()
        elif choice == '0':
            print(f"\n{t('cli.main_menu_exiting')}")
            break
        else:
            print(f"\n{t('cli.main_menu_invalid')}")


if __name__ == '__main__':
    args = _parse_args()
    _init_i18n(args.lang)
    main()


path: _meta.json
content: ownerId: fiyo
slug: dbcheck
version: 2.3.4

path: _skillhub_meta.json
content: slug: dbcheck
name: DBCheck
version: 2.3.4
source: local

Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)