# Python Inventory (function-level)

| File | Symbol | Type | Doc (first line) | Reuse |
|---|---|---|---|---|
| etl_billiards/api/client.py | (module) | module | API客户端：统一封装 POST/重试/分页与列表提取逻辑。 | High |
| etl_billiards/api/client.py | APIClient | class | HTTP API 客户端（默认使用 POST + JSON 请求体） | High |
| etl_billiards/api/client.py | APIClient.__init__ | method |  | High |
| etl_billiards/api/client.py | APIClient._get_session | method | 获取或创建带重试的 Session。 | High |
| etl_billiards/api/client.py | APIClient.get | method | 兼容旧名的请求入口（实际以 POST JSON 方式请求）。 | High |
| etl_billiards/api/client.py | APIClient._post_json | method |  | High |
| etl_billiards/api/client.py | APIClient._build_headers | method |  | High |
| etl_billiards/api/client.py | APIClient._normalize_token | method |  | High |
| etl_billiards/api/client.py | APIClient._ensure_success | method | API 返回 code 非 0 时主动抛错，便于上层重试/记录。 | High |
| etl_billiards/api/client.py | APIClient._iter_paginated_single | method | 单一 endpoint 的分页迭代器（不包含 recent/former 路由逻辑）。 | High |
| etl_billiards/api/client.py | APIClient.iter_paginated | method | 分页迭代器：逐页拉取数据并产出 (page_no, records, request_params, raw_response)。 | High |
| etl_billiards/api/client.py | APIClient.get_paginated | method | 分页获取数据并将所有记录汇总在一个列表中。 | High |
| etl_billiards/api/client.py | APIClient._extract_list | method | 根据 data_path/list_key 提取列表结构，兼容常见字段名。 | High |
| etl_billiards/api/endpoint_routing.py | (module) | module | “近期记录 / 历史记录(Former)”接口路由规则。 | High |
| etl_billiards/api/endpoint_routing.py | WindowSpec | class |  | High |
| etl_billiards/api/endpoint_routing.py | RoutedCall | class |  | High |
| etl_billiards/api/endpoint_routing.py | is_former_endpoint | function |  | High |
| etl_billiards/api/endpoint_routing.py | _parse_dt | function |  | High |
| etl_billiards/api/endpoint_routing.py | _fmt_dt | function |  | High |
| etl_billiards/api/endpoint_routing.py | extract_window_spec | function |  | High |
| etl_billiards/api/endpoint_routing.py | derive_former_endpoint | function |  | High |
| etl_billiards/api/endpoint_routing.py | recent_boundary | function | 3个月（自然月）边界：取 (now - months) 所在月份的 1 号 00:00:00。 | High |
| etl_billiards/api/endpoint_routing.py | plan_calls | function | 根据 endpoint + params 的时间窗口，返回要调用的 endpoint/params 列表（可能拆分为两段）。 | High |
| etl_billiards/api/local_json_client.py | (module) | module | 本地 JSON 客户端，模拟 APIClient 的分页接口，从落盘的 JSON 回放数据。 | High |
| etl_billiards/api/local_json_client.py | LocalJsonClient | class | 读取 RecordingAPIClient 生成的 JSON，提供 iter_paginated/get_paginated 接口。 | High |
| etl_billiards/api/local_json_client.py | LocalJsonClient.__init__ | method |  | High |
| etl_billiards/api/local_json_client.py | LocalJsonClient.get_source_hint | method | Return the JSON file path for this endpoint (for source_file lineage). | High |
| etl_billiards/api/local_json_client.py | LocalJsonClient.iter_paginated | method |  | High |
| etl_billiards/api/local_json_client.py | LocalJsonClient.get_paginated | method |  | High |
| etl_billiards/api/recording_client.py | (module) | module | 包装 APIClient，将分页响应落盘便于后续本地清洗。 | High |
| etl_billiards/api/recording_client.py | RecordingAPIClient | class | 代理 APIClient，在调用 iter_paginated/get_paginated 时同时把响应写入 JSON 文件。 | High |
| etl_billiards/api/recording_client.py | RecordingAPIClient.__init__ | method |  | High |
| etl_billiards/api/recording_client.py | RecordingAPIClient.get_source_hint | method | Return the JSON dump path for this endpoint (for source_file lineage). | High |
| etl_billiards/api/recording_client.py | RecordingAPIClient.iter_paginated | method |  | High |
| etl_billiards/api/recording_client.py | RecordingAPIClient.get_paginated | method |  | High |
| etl_billiards/api/recording_client.py | RecordingAPIClient._dump | method |  | High |
| etl_billiards/api/recording_client.py | _cfg_get | function |  | High |
| etl_billiards/api/recording_client.py | build_recording_client | function | Build RecordingAPIClient from AppConfig or dict config. | High |
| etl_billiards/build_exe.py | (module) | module | ETL GUI 打包脚本 | Medium |
| etl_billiards/build_exe.py | get_project_root | function | 获取项目根目录 | Medium |
| etl_billiards/build_exe.py | clean_build | function | 清理旧的构建文件 | Medium |
| etl_billiards/build_exe.py | build_exe | function | 构建 EXE | Medium |
| etl_billiards/build_exe.py | slim_dist | function | 精简打包后的文件，删除不需要的内容 | Medium |
| etl_billiards/build_exe.py | main | function | 主函数 | Medium |
| etl_billiards/cli/main.py | (module) | module | CLI主入口 | Medium |
| etl_billiards/cli/main.py | setup_logging | function | 设置日志 | Medium |
| etl_billiards/cli/main.py | parse_args | function | 解析命令行参数 | Medium |
| etl_billiards/cli/main.py | build_cli_overrides | function | 从命令行参数构建配置覆盖 | Medium |
| etl_billiards/cli/main.py | main | function | 主函数 | Medium |
| etl_billiards/config/defaults.py | (module) | module | 配置默认值定义 | High |
| etl_billiards/config/env_parser.py | (module) | module | 环境变量解析 | High |
| etl_billiards/config/env_parser.py | _deep_set | function |  | High |
| etl_billiards/config/env_parser.py | _coerce_env | function |  | High |
| etl_billiards/config/env_parser.py | _strip_inline_comment | function | 去掉未被引号包裹的内联注释 | High |
| etl_billiards/config/env_parser.py | _unquote_value | function | 处理引号/原始字符串以及尾随逗号 | High |
| etl_billiards/config/env_parser.py | _parse_dotenv_line | function | 解析 .env 文件中的单行 | High |
| etl_billiards/config/env_parser.py | _load_dotenv_values | function | 从项目根目录读取 .env 文件键值 | High |
| etl_billiards/config/env_parser.py | _apply_env_values | function |  | High |
| etl_billiards/config/env_parser.py | load_env_overrides | function |  | High |
| etl_billiards/config/settings.py | (module) | module | 配置管理主类 | High |
| etl_billiards/config/settings.py | AppConfig | class | 应用配置管理器 | High |
| etl_billiards/config/settings.py | AppConfig.__init__ | method |  | High |
| etl_billiards/config/settings.py | AppConfig.load | method | 加载配置: DEFAULTS < ENV < CLI | High |
| etl_billiards/config/settings.py | AppConfig._deep_merge | method | 深度合并字典 | High |
| etl_billiards/config/settings.py | AppConfig._normalize | method | 规范化配置 | High |
| etl_billiards/config/settings.py | AppConfig._validate | method | 验证必填配置 | High |
| etl_billiards/config/settings.py | AppConfig.get | method | 获取配置值（支持点号路径） | High |
| etl_billiards/config/settings.py | AppConfig.__getitem__ | method |  | High |
| etl_billiards/database/base.py | (module) | module | 数据库操作（批量、RETURNING支持） | High |
| etl_billiards/database/base.py | DatabaseOperations | class | 扩展数据库操作（包含批量upsert和returning支持） | High |
| etl_billiards/database/base.py | DatabaseOperations.batch_execute | method | 批量执行SQL（不带RETURNING） | High |
| etl_billiards/database/base.py | DatabaseOperations.batch_upsert_with_returning | method | 批量 UPSERT 并统计插入/更新数 | High |
| etl_billiards/database/base.py | DatabaseOperations._execute_with_returning_vectorized | method | 向量化执行（使用execute_values） | High |
| etl_billiards/database/base.py | DatabaseOperations._execute_with_returning_row_by_row | method | 逐行执行（回退方案） | High |
| etl_billiards/database/base.py | DatabaseOperations._extract_inserted_flag | method | 从返回记录中提取inserted标志 | High |
| etl_billiards/database/connection.py | (module) | module | Database connection manager with capped connect_timeout. | High |
| etl_billiards/database/connection.py | DatabaseConnection | class | Wrap psycopg2 connection with session parameters and timeout guard. | High |
| etl_billiards/database/connection.py | DatabaseConnection.__init__ | method |  | High |
| etl_billiards/database/connection.py | DatabaseConnection.query | method | Execute a query and fetch all rows. | High |
| etl_billiards/database/connection.py | DatabaseConnection.execute | method | Execute a SQL statement without returning rows. | High |
| etl_billiards/database/connection.py | DatabaseConnection.commit | method | Commit current transaction. | High |
| etl_billiards/database/connection.py | DatabaseConnection.rollback | method | Rollback current transaction. | High |
| etl_billiards/database/connection.py | DatabaseConnection.close | method | Safely close the connection. | High |
| etl_billiards/database/operations.py | (module) | module | 数据库批量操作 | High |
| etl_billiards/database/operations.py | DatabaseOperations | class | 数据库批量操作封装 | High |
| etl_billiards/database/operations.py | DatabaseOperations.__init__ | method |  | High |
| etl_billiards/database/operations.py | DatabaseOperations.batch_execute | method | 批量执行SQL | High |
| etl_billiards/database/operations.py | DatabaseOperations.batch_upsert_with_returning | method | 批量UPSERT并返回插入/更新计数 | High |
| etl_billiards/database/operations.py | DatabaseOperations._is_inserted | method | 判断是否为插入操作 | High |
| etl_billiards/database/operations.py | DatabaseOperations.commit | method | 提交事务（委托给底层连接） | High |
| etl_billiards/database/operations.py | DatabaseOperations.rollback | method | 回滚事务（委托给底层连接） | High |
| etl_billiards/database/operations.py | DatabaseOperations.query | method | 执行查询并返回结果 | High |
| etl_billiards/database/operations.py | DatabaseOperations.execute | method | 执行任意 SQL | High |
| etl_billiards/database/operations.py | DatabaseOperations.cursor | method | 暴露原生 cursor，供特殊操作使用 | High |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | (module) | module | 对比“近期记录”与“历史记录(Former)”接口： | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | EndpointCheckResult | class |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _reconfigure_stdout_utf8 | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | derive_former_endpoint | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _parse_day_start | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _window_from_dates | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _build_window_params | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _extract_records | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _walk_paths | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _schema_from_records | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _schema_from_data | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _cell | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _format_diff | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _post_first_page | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | _load_specs_for_range_only | function |  | Low |
| etl_billiards/fetch-test/compare_recent_former_endpoints.py | main | function |  | Low |
| etl_billiards/gui/__init__.py | (module) | module | ETL GUI 客户端模块 | Medium |
| etl_billiards/gui/main.py | (module) | module | ETL GUI 应用入口 | Medium |
| etl_billiards/gui/main.py | main | function | 主函数 | Medium |
| etl_billiards/gui/main_window.py | (module) | module | 主窗口 | Medium |
| etl_billiards/gui/main_window.py | MainWindow | class | ETL GUI 主窗口 | Medium |
| etl_billiards/gui/main_window.py | MainWindow.__init__ | method |  | Medium |
| etl_billiards/gui/main_window.py | MainWindow.showEvent | method | 窗口显示事件 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._create_nav_widget | method | 创建导航侧边栏 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._create_panels | method | 创建各个功能面板 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._init_menu | method | 初始化菜单栏 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._init_status_bar | method | 初始化状态栏 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._connect_signals | method | 连接信号 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._on_nav_changed | method | 导航项切换 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._switch_panel | method | 切换到指定面板 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._refresh_config | method | 刷新配置 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._on_task_started | method | 任务开始时 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._on_task_finished | method | 任务完成时 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._on_db_connection_changed | method | 数据库连接状态变化 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._show_status_message | method | 显示状态栏消息 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._on_add_to_queue | method | 添加任务到队列 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._on_create_schedule | method | 创建调度任务 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._show_settings | method | 显示设置对话框 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._check_config_on_startup | method | 启动时检查配置 | Medium |
| etl_billiards/gui/main_window.py | MainWindow._show_about | method | 显示关于对话框 | Medium |
| etl_billiards/gui/main_window.py | MainWindow.closeEvent | method | 关闭事件 | Medium |
| etl_billiards/gui/models/__init__.py | (module) | module | 数据模型模块 | Medium |
| etl_billiards/gui/models/schedule_model.py | (module) | module | 调度任务数据模型 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleType | class | 调度类型 | Medium |
| etl_billiards/gui/models/schedule_model.py | IntervalUnit | class | 间隔单位 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleConfig | class | 调度配置 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleConfig.to_dict | method | 转换为字典 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleConfig.from_dict | method | 从字典创建 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleConfig.get_description | method | 获取调度描述 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleConfig.get_next_run_time | method | 计算下次运行时间 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleConfig._parse_simple_cron | method | 简化版 Cron 解析 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleExecutionRecord | class | 调度执行记录 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleExecutionRecord.to_dict | method |  | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleExecutionRecord.from_dict | method |  | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduledTask | class | 调度任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduledTask.add_execution_record | method | 添加执行记录 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduledTask.update_execution_record | method | 更新执行记录状态 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduledTask.to_dict | method | 转换为字典 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduledTask.from_dict | method | 从字典创建 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduledTask.update_next_run | method | 更新下次运行时间 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore | class | 调度任务存储 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.__init__ | method |  | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.load | method | 加载任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.save | method | 保存任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.add_task | method | 添加任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.remove_task | method | 移除任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.update_task | method | 更新任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.get_task | method | 获取任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.get_all_tasks | method | 获取所有任务 | Medium |
| etl_billiards/gui/models/schedule_model.py | ScheduleStore.get_due_tasks | method | 获取到期需要执行的任务 | Medium |
| etl_billiards/gui/models/task_model.py | (module) | module | 任务数据模型 | Medium |
| etl_billiards/gui/models/task_model.py | TaskStatus | class | 任务状态枚举 | Medium |
| etl_billiards/gui/models/task_model.py | TaskCategory | class | 任务分类 | Medium |
| etl_billiards/gui/models/task_model.py | get_task_category | function | 获取任务分类 | Medium |
| etl_billiards/gui/models/task_model.py | TaskItem | class | 任务项 | Medium |
| etl_billiards/gui/models/task_model.py | TaskItem.__post_init__ | method |  | Medium |
| etl_billiards/gui/models/task_model.py | TaskConfig | class | 任务执行配置 | Medium |
| etl_billiards/gui/models/task_model.py | TaskHistory | class | 任务执行历史 | Medium |
| etl_billiards/gui/models/task_model.py | TaskHistory.duration_seconds | method | 执行时长（秒） | Medium |
| etl_billiards/gui/models/task_model.py | TaskHistory.duration_str | method | 格式化的执行时长 | Medium |
| etl_billiards/gui/models/task_model.py | QueuedTask | class | 队列中的任务 | Medium |
| etl_billiards/gui/models/task_registry.py | (module) | module | 任务注册表：定义所有可用任务及其业务域分组。 | Medium |
| etl_billiards/gui/models/task_registry.py | BusinessDomain | class | 业务域枚举 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskDefinition | class | 任务定义 | Medium |
| etl_billiards/gui/models/task_registry.py | _build_ods_task_definition | function | 根据 ODS 任务编码构建任务定义 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry | class | 任务注册表：管理所有可用任务 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.__new__ | method |  | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.__init__ | method |  | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry._load_tasks | method | 加载所有任务定义 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_task | method | 获取任务定义 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_all_tasks | method | 获取所有任务 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_ods_tasks | method | 获取所有 ODS 任务 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_fact_ods_tasks | method | 获取事实类 ODS 任务（需要时间窗口） | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_dimension_ods_tasks | method | 获取维度类 ODS 任务 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_tasks_by_domain | method | 按业务域获取任务 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_ods_tasks_grouped | method | 获取按业务域分组的 ODS 任务 | Medium |
| etl_billiards/gui/models/task_registry.py | TaskRegistry.get_non_ods_tasks | method | 获取非 ODS 任务 | Medium |
| etl_billiards/gui/models/task_registry.py | get_ods_task_codes | function | 获取所有 ODS 任务编码 | Medium |
| etl_billiards/gui/models/task_registry.py | get_fact_ods_task_codes | function | 获取事实类 ODS 任务编码 | Medium |
| etl_billiards/gui/models/task_registry.py | get_dimension_ods_task_codes | function | 获取维度类 ODS 任务编码 | Medium |
| etl_billiards/gui/models/task_registry.py | get_all_task_tuples | function | 获取所有任务的 (code, name, description) 元组列表 | Medium |
| etl_billiards/gui/models/task_registry.py | get_ods_tasks_for_ui | function | 获取 ODS 任务列表供 UI 使用：(code, display_name, domain) | Medium |
| etl_billiards/gui/resources/__init__.py | (module) | module | GUI 资源模块 | Medium |
| etl_billiards/gui/resources/__init__.py | load_stylesheet | function | 加载样式表 | Medium |
| etl_billiards/gui/utils/__init__.py | (module) | module | 工具模块 | Medium |
| etl_billiards/gui/utils/app_settings.py | (module) | module | 应用程序设置管理 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings | class | 应用程序设置单例 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.__new__ | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.__init__ | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings._get_settings_path | method | 获取设置文件路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings._auto_detect_paths | method | 自动检测 ETL 项目路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings._load | method | 加载设置 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings._save | method | 保存设置 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.etl_project_path | method | 获取 ETL 项目路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.etl_project_path | method | 设置 ETL 项目路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.env_file_path | method | 获取 .env 文件路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.env_file_path | method | 设置 .env 文件路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.is_configured | method | 检查是否已配置 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.validate | method | 验证配置 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_hours | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_hours | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_overlap_seconds | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_overlap_seconds | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_include_dwd | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_include_dwd | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_auto_verify | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_auto_verify | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_selected_tasks | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.auto_update_selected_tasks | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_mode | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_mode | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_history_start | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_history_start | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_history_end | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_history_end | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_lookback_hours | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_lookback_hours | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_include_dimensions | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_include_dimensions | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_auto_backfill | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_auto_backfill | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_ods_tasks | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.integrity_ods_tasks | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_pipeline_flow | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_pipeline_flow | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_dry_run | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_dry_run | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_start | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_start | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_end | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_end | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_ingest_source | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_ingest_source | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_split | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_split | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_compensation | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.advanced_window_compensation | method |  | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.get_all_settings | method | 获取所有设置（用于调试） | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.save_all | method | 强制保存所有设置 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings._get_history_path | method | 获取任务历史文件路径 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.save_task_history | method | 保存任务历史到文件 | Medium |
| etl_billiards/gui/utils/app_settings.py | AppSettings.load_task_history | method | 从文件加载任务历史 | Medium |
| etl_billiards/gui/utils/cli_builder.py | (module) | module | CLI 命令构建器 | Medium |
| etl_billiards/gui/utils/cli_builder.py | CLIBuilder | class | 构建 CLI 命令行参数 | Medium |
| etl_billiards/gui/utils/cli_builder.py | CLIBuilder.__init__ | method |  | Medium |
| etl_billiards/gui/utils/cli_builder.py | CLIBuilder.build_command | method | 根据任务配置构建命令行参数列表 | Medium |
| etl_billiards/gui/utils/cli_builder.py | CLIBuilder.build_command_string | method | 构建命令行字符串（用于显示） | Medium |
| etl_billiards/gui/utils/cli_builder.py | CLIBuilder.build_from_dict | method | 从字典构建命令行参数 | Medium |
| etl_billiards/gui/utils/config_helper.py | (module) | module | 配置辅助工具 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper | class | 配置文件辅助类 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.__init__ | method | 初始化配置辅助器 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.load_env | method | 加载 .env 文件内容 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.save_env | method | 保存环境变量到 .env 文件 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.get_grouped_env | method | 获取分组的环境变量 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.validate_env | method | 验证环境变量 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.mask_sensitive | method | 脱敏敏感值 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper._parse_line | method | 解析 .env 文件的一行 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper._unquote_value | method | 处理引号和注释 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper._strip_inline_comment | method | 去除内联注释 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper._format_line | method | 格式化为 .env 行 | Medium |
| etl_billiards/gui/utils/config_helper.py | ConfigHelper.get_group_title | method | 获取分组标题 | Medium |
| etl_billiards/gui/widgets/__init__.py | (module) | module | GUI 组件模块 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | (module) | module | 数据库查看器 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer | class | 数据库查看器 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._create_table_browser | method | 创建表浏览器 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._create_query_area | method | 创建查询区域 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._connect_signals | method | 连接信号 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._load_dsn_from_env | method | 从环境变量加载 DSN | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._toggle_dsn_visibility | method | 切换 DSN 可见性 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._connect_db | method | 连接数据库 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._disconnect_db | method | 断开数据库连接 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._refresh_tables | method | 刷新表列表 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._on_connection_status | method | 处理连接状态变化 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._on_tables_loaded | method | 处理表列表加载完成 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._on_template_selected | method | 模板选择变化 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._on_table_double_clicked | method | 表双击事件 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._execute_query | method | 执行查询 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._on_query_finished | method | 查询完成 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer._on_query_error | method | 查询错误 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer.close_connection | method | 关闭连接 | Medium |
| etl_billiards/gui/widgets/db_viewer.py | DBViewer.keyPressEvent | method | 键盘事件 | Medium |
| etl_billiards/gui/widgets/env_editor.py | (module) | module | 环境变量编辑器 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor | class | 环境变量编辑器 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._create_config_groups | method | 创建配置分组 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor.load_config | method | 加载配置 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._save_config | method | 保存配置 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._import_config | method | 导入配置 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._export_config | method | 导出配置 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._toggle_sensitive | method | 切换敏感信息显示 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._on_value_changed | method | 值变化时验证 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._validate | method | 验证配置 | Medium |
| etl_billiards/gui/widgets/env_editor.py | EnvEditor._get_placeholder | method | 获取占位符提示 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | (module) | module | 日志查看器 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer | class | 日志查看器 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._connect_signals | method | 连接信号 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer.append_log | method | 追加日志 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._append_formatted_line | method | 追加格式化的行 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._matches_filter | method | 检查是否匹配过滤器 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._apply_filter | method | 应用过滤器 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._toggle_auto_scroll | method | 切换自动滚动 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._copy_all | method | 复制全部日志 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._export_log | method | 导出日志 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._clear_log | method | 清空日志 | Medium |
| etl_billiards/gui/widgets/log_viewer.py | LogViewer._update_line_count | method | 更新行数显示 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | (module) | module | 应用程序设置对话框 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog | class | 设置对话框 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog._init_ui | method |  | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog._load_settings | method | 加载设置 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog._browse_project_path | method | 浏览项目路径 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog._browse_env_path | method | 浏览 .env 文件 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog._validate_config | method | 验证配置 | Medium |
| etl_billiards/gui/widgets/settings_dialog.py | SettingsDialog._save_and_accept | method | 保存并关闭 | Medium |
| etl_billiards/gui/widgets/status_panel.py | (module) | module | ETL 状态面板 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusCard | class | 状态卡片 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusCard.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusCard.set_value | method | 设置值 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel | class | ETL 状态面板 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._connect_signals | method | 连接信号 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._toggle_auto_refresh | method | 切换自动刷新 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._auto_refresh | method | 自动刷新 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._refresh_all | method | 刷新所有数据 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._on_connection_status | method | 处理连接状态 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._load_status_data | method | 加载状态数据 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._on_query_finished | method | 处理查询结果 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._process_table_count | method | 处理表数量数据 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._process_cutoff_data | method | 处理 Cutoff 数据 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._process_history_data | method | 处理运行历史数据 | Medium |
| etl_billiards/gui/widgets/status_panel.py | StatusPanel._on_query_error | method | 处理查询错误 | Medium |
| etl_billiards/gui/widgets/task_manager.py | (module) | module | 任务管理器面板 | Medium |
| etl_billiards/gui/widgets/task_manager.py | _get_schedulable_tasks | function | 从任务注册表动态获取可调度任务列表 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskLogDialog | class | 任务日志查看对话框 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskLogDialog.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskLogDialog._init_ui | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskLogDialog._copy_log | method | 复制日志到剪贴板 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskLogDialog._get_status_text | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskLogDialog._get_status_color | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog | class | 调度任务编辑对话框 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._init_ui | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._on_type_changed | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._load_task | method | 加载任务数据 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog.get_task | method | 获取配置的任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._connect_preview_signals | method | 连接信号以实时更新 CLI 预览 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._update_cli_preview | method | 更新 CLI 命令行预览 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._on_cli_editable_changed | method | 切换 CLI 编辑模式 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleEditDialog._copy_cli_to_clipboard | method | 复制 CLI 命令到剪贴板 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog | class | 调度任务日志查看对话框 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._init_ui | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._load_history | method | 加载执行历史 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._on_selection_changed | method | 选择变化时显示对应的日志 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._show_running_task_log | method | 显示执行中任务的实时日志 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._refresh_running_log | method | 定时刷新执行中任务的日志 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._copy_log | method | 复制日志到剪贴板 | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._get_status_text | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | ScheduleLogDialog._get_status_color | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager | class | 任务管理器 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._connect_signals | method | 连接信号 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager.add_task | method | 添加任务到队列 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._toggle_auto_run | method | 切换自动执行 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._clear_queue | method | 清空队列 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._run_next | method | 执行下一个任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._run_all | method | 执行全部任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._stop_current | method | 停止当前任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._clear_history | method | 清空历史 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._execute_task | method | 执行任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._on_output | method | 收到输出 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._on_finished | method | 任务完成 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._on_error | method | 发生错误 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._is_running | method | 是否有任务在运行 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._has_scheduled_tasks_pending | method | 检查队列中是否有待执行的定时任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._refresh_display | method | 刷新显示 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._refresh_queue_table | method | 刷新队列表格 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._refresh_history_table | method | 刷新历史表格 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._show_queue_menu | method | 显示队列右键菜单 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._remove_task | method | 移除任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._show_history_menu | method | 显示历史右键菜单 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._view_task_log | method | 双击查看任务日志 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._show_task_log_dialog | method | 显示任务日志对话框 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._rerun_task | method | 重新执行任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._remove_from_history | method | 从历史中删除任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._load_task_history | method | 从文件加载任务历史 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._save_task_history | method | 保存任务历史到文件 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._extract_result_summary | method | 从任务输出中提取结果摘要 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._get_status_text | method | 获取状态文本 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._get_status_color | method | 获取状态颜色 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._toggle_scheduler | method | 切换调度器状态 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._check_scheduled_tasks | method | 检查并执行到期的调度任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._execute_scheduled_task | method | 执行调度任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._add_schedule | method | 添加调度任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._edit_schedule | method | 编辑调度任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._delete_schedule | method | 删除调度任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._toggle_schedule_enabled | method | 切换调度任务启用状态 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._run_schedule_now | method | 立即执行调度任务 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._show_schedule_menu | method | 显示调度任务右键菜单 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._refresh_schedule_table | method | 刷新调度任务表格 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._update_schedule_execution_record | method | 更新调度执行记录（如果此任务来自调度） | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._view_schedule_log | method | 查看调度任务日志 | Medium |
| etl_billiards/gui/widgets/task_manager.py | TaskManager._on_schedule_double_click | method | 双击调度任务查看日志 | Medium |
| etl_billiards/gui/widgets/task_panel.py | (module) | module | 任务配置面板 | Medium |
| etl_billiards/gui/widgets/task_panel.py | _get_all_tasks | function | 从注册表动态获取所有任务 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel | class | 任务配置面板 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_task_selection | method | 创建任务选择区域 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_config_area | method | 创建参数配置区域 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_quick_actions_tab | method | 创建快捷操作选项卡 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_reload_include_dimensions_changed | method | 全量重刷的"包含维度表"选项变化 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_advanced_config_tab | method | 创建高级配置选项卡 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_bottom_area | method | 创建底部区域 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._connect_signals | method | 连接信号 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_backfill_option_changed | method | 自动补齐选项变化时，联动其他选项 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel.refresh_tasks | method | 刷新任务列表 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._filter_tasks | method | 过滤任务列表 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_selection_changed | method | 选择变化时 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._select_all | method | 全选 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._deselect_all | method | 全不选 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._browse_source_dir | method | 浏览数据源目录 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._get_config | method | 获取当前配置 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._update_preview | method | 更新命令行预览 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._run_task | method | 执行任务 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._stop_task | method | 停止任务 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_output | method | 收到输出 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_finished | method | 任务完成 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_error | method | 发生错误 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel.is_running | method | 是否正在执行任务 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._add_task_to_queue | method | 将任务列表中选中的任务添加到队列 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._on_integrity_mode_changed | method | 校验模式变化 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._update_sync_time_preview | method | 更新日常同步的时间范围预览（精确到秒） | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._run_daily_sync | method | 执行日常增量同步 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_sync_schedule | method | 创建日常同步调度任务 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._run_full_reload | method | 执行全量重刷 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._get_integrity_config | method | 获取数据校验配置 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._run_integrity_check | method | 执行数据完整性校验 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._create_integrity_schedule | method | 创建数据校验调度任务 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._load_settings | method | 从持久化存储加载设置 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._save_sync_settings | method | 保存日常同步设置 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._save_reload_settings | method | 保存全量重刷设置 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._save_integrity_settings | method | 保存数据校验设置 | Medium |
| etl_billiards/gui/widgets/task_panel.py | TaskPanel._save_advanced_settings | method | 保存高级设置 | Medium |
| etl_billiards/gui/widgets/task_selector.py | (module) | module | 可复用的 ODS 任务选择组件：按业务域分组显示，支持全选/反选。 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget | class | ODS 任务选择组件：按业务域分组显示 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget.__init__ | method | 初始化任务选择器 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._create_domain_group | method | 创建业务域分组框 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._apply_default_selection | method | 应用默认选择 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._on_selection_changed | method | 选择变化时 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._update_count_label | method | 更新选中计数标签 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._select_all | method | 全选 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._deselect_all | method | 全不选 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget._select_facts_only | method | 只选事实表任务 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget.get_selected_codes | method | 获取选中的任务编码列表 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget.set_selected_codes | method | 设置选中的任务编码 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget.get_all_codes | method | 获取所有任务编码 | Medium |
| etl_billiards/gui/widgets/task_selector.py | TaskSelectorWidget.is_any_selected | method | 是否有任何任务被选中 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector | class | 紧凑型任务选择器：单行显示业务域，点击展开选择 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector.__init__ | method |  | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector._init_ui | method | 初始化界面 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector._apply_default_selection | method | 应用默认选择 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector._on_selection_changed | method | 选择变化时 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector._update_count_label | method | 更新计数标签 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector._select_all | method | 全选所有业务域 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector._deselect_all | method | 取消全选 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector.get_selected_codes | method | 获取选中的任务编码 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector.set_selected_domains | method | 设置选中的业务域 | Medium |
| etl_billiards/gui/widgets/task_selector.py | CompactTaskSelector.is_any_selected | method | 是否有任何任务被选中 | Medium |
| etl_billiards/gui/workers/__init__.py | (module) | module | 后台工作线程模块 | Medium |
| etl_billiards/gui/workers/db_worker.py | (module) | module | 数据库查询工作线程 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker | class | 数据库查询工作线程 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.__init__ | method |  | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.connect_db | method | 连接数据库 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.disconnect_db | method | 断开数据库连接 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.execute_query | method | 执行查询 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.load_tables | method | 加载表列表 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.run | method | 执行任务 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker._do_connect | method | 执行连接 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker._do_disconnect | method | 执行断开连接 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker._do_query | method | 执行查询 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker._do_load_tables | method | 加载表列表 | Medium |
| etl_billiards/gui/workers/db_worker.py | DBWorker.is_connected | method | 检查是否已连接 | Medium |
| etl_billiards/gui/workers/task_worker.py | (module) | module | 任务执行工作线程 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker | class | 任务执行工作线程 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker.__init__ | method |  | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker.run | method | 执行任务 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker.stop | method | 停止任务 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker._parse_progress | method | 解析进度信息 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker._generate_summary | method | 生成执行摘要 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker._parse_detailed_summary | method | 解析详细的执行摘要 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker.exit_code | method | 获取退出码 | Medium |
| etl_billiards/gui/workers/task_worker.py | TaskWorker.output | method | 获取完整输出 | Medium |
| etl_billiards/loaders/base_loader.py | (module) | module | 数据加载器基类 | Medium |
| etl_billiards/loaders/base_loader.py | BaseLoader | class | 数据加载器基类 | Medium |
| etl_billiards/loaders/base_loader.py | BaseLoader.__init__ | method |  | Medium |
| etl_billiards/loaders/base_loader.py | BaseLoader.upsert | method | 执行 UPSERT 操作 | Medium |
| etl_billiards/loaders/base_loader.py | BaseLoader._batch_size | method | 批次大小 | Medium |
| etl_billiards/loaders/dimensions/assistant.py | (module) | module | 助教维度加载器 | Medium |
| etl_billiards/loaders/dimensions/assistant.py | AssistantLoader | class | 写入 dim_assistant | Medium |
| etl_billiards/loaders/dimensions/assistant.py | AssistantLoader.upsert_assistants | method |  | Medium |
| etl_billiards/loaders/dimensions/member.py | (module) | module | 会员维度表加载器 | Medium |
| etl_billiards/loaders/dimensions/member.py | MemberLoader | class | 会员维度加载器 | Medium |
| etl_billiards/loaders/dimensions/member.py | MemberLoader.upsert_members | method | 加载会员数据 | Medium |
| etl_billiards/loaders/dimensions/package.py | (module) | module | 团购/套餐定义加载器 | Medium |
| etl_billiards/loaders/dimensions/package.py | PackageDefinitionLoader | class | 写入 dim_package_coupon | Medium |
| etl_billiards/loaders/dimensions/package.py | PackageDefinitionLoader.upsert_packages | method |  | Medium |
| etl_billiards/loaders/dimensions/product.py | (module) | module | 商品维度 + 价格SCD2 加载器 | Medium |
| etl_billiards/loaders/dimensions/product.py | ProductLoader | class | 商品维度加载器（dim_product + dim_product_price_scd） | Medium |
| etl_billiards/loaders/dimensions/product.py | ProductLoader.__init__ | method |  | Medium |
| etl_billiards/loaders/dimensions/product.py | ProductLoader.upsert_products | method | 加载商品维度及价格SCD | Medium |
| etl_billiards/loaders/dimensions/table.py | (module) | module | 台桌维度加载器 | Medium |
| etl_billiards/loaders/dimensions/table.py | TableLoader | class | 将台桌档案写入 dim_table | Medium |
| etl_billiards/loaders/dimensions/table.py | TableLoader.upsert_tables | method | 批量写入台桌档案 | Medium |
| etl_billiards/loaders/facts/assistant_abolish.py | (module) | module | 助教作废事实表 | Medium |
| etl_billiards/loaders/facts/assistant_abolish.py | AssistantAbolishLoader | class | 写入 fact_assistant_abolish | Medium |
| etl_billiards/loaders/facts/assistant_abolish.py | AssistantAbolishLoader.upsert_records | method |  | Medium |
| etl_billiards/loaders/facts/assistant_ledger.py | (module) | module | 助教流水事实表 | Medium |
| etl_billiards/loaders/facts/assistant_ledger.py | AssistantLedgerLoader | class | 写入 fact_assistant_ledger | Medium |
| etl_billiards/loaders/facts/assistant_ledger.py | AssistantLedgerLoader.upsert_ledgers | method |  | Medium |
| etl_billiards/loaders/facts/coupon_usage.py | (module) | module | 券核销事实表 | Medium |
| etl_billiards/loaders/facts/coupon_usage.py | CouponUsageLoader | class | 写入 fact_coupon_usage | Medium |
| etl_billiards/loaders/facts/coupon_usage.py | CouponUsageLoader.upsert_coupon_usage | method |  | Medium |
| etl_billiards/loaders/facts/inventory_change.py | (module) | module | 库存变动事实表 | Medium |
| etl_billiards/loaders/facts/inventory_change.py | InventoryChangeLoader | class | 写入 fact_inventory_change | Medium |
| etl_billiards/loaders/facts/inventory_change.py | InventoryChangeLoader.upsert_changes | method |  | Medium |
| etl_billiards/loaders/facts/order.py | (module) | module | 订单事实表加载器 | Medium |
| etl_billiards/loaders/facts/order.py | OrderLoader | class | 订单数据加载器 | Medium |
| etl_billiards/loaders/facts/order.py | OrderLoader.upsert_orders | method | 加载订单数据 | Medium |
| etl_billiards/loaders/facts/payment.py | (module) | module | 支付事实表加载器 | Medium |
| etl_billiards/loaders/facts/payment.py | PaymentLoader | class | 支付数据加载器 | Medium |
| etl_billiards/loaders/facts/payment.py | PaymentLoader.upsert_payments | method | 加载支付数据 | Medium |
| etl_billiards/loaders/facts/refund.py | (module) | module | 退款事实表加载器 | Medium |
| etl_billiards/loaders/facts/refund.py | RefundLoader | class | 写入 fact_refund | Medium |
| etl_billiards/loaders/facts/refund.py | RefundLoader.upsert_refunds | method |  | Medium |
| etl_billiards/loaders/facts/table_discount.py | (module) | module | 台费打折事实表 | Medium |
| etl_billiards/loaders/facts/table_discount.py | TableDiscountLoader | class | 写入 fact_table_discount | Medium |
| etl_billiards/loaders/facts/table_discount.py | TableDiscountLoader.upsert_discounts | method |  | Medium |
| etl_billiards/loaders/facts/ticket.py | (module) | module | 小票详情加载器 | Medium |
| etl_billiards/loaders/facts/ticket.py | TicketLoader | class | Loader for parsing Ticket Detail JSON and populating DWD fact tables. | Medium |
| etl_billiards/loaders/facts/ticket.py | TicketLoader.process_tickets | method | Process a batch of ticket JSONs. | Medium |
| etl_billiards/loaders/facts/ticket.py | TicketLoader._upsert_orders | method |  | Medium |
| etl_billiards/loaders/facts/ticket.py | TicketLoader._upsert_goods | method |  | Medium |
| etl_billiards/loaders/facts/ticket.py | TicketLoader._upsert_table_usages | method |  | Medium |
| etl_billiards/loaders/facts/ticket.py | TicketLoader._upsert_assistant_services | method |  | Medium |
| etl_billiards/loaders/facts/topup.py | (module) | module | 充值记录事实表 | Medium |
| etl_billiards/loaders/facts/topup.py | TopupLoader | class | 写入 fact_topup | Medium |
| etl_billiards/loaders/facts/topup.py | TopupLoader.upsert_topups | method |  | Medium |
| etl_billiards/loaders/ods/__init__.py | (module) | module | ODS loader helpers. | Medium |
| etl_billiards/loaders/ods/generic.py | (module) | module | Generic ODS loader that keeps raw payload + primary keys. | Medium |
| etl_billiards/loaders/ods/generic.py | GenericODSLoader | class | Insert/update helper for ODS tables that share the same pattern. | Medium |
| etl_billiards/loaders/ods/generic.py | GenericODSLoader.__init__ | method |  | Medium |
| etl_billiards/loaders/ods/generic.py | GenericODSLoader.upsert_rows | method | Insert/update the provided iterable of dictionaries. | Medium |
| etl_billiards/loaders/ods/generic.py | GenericODSLoader._build_sql | method |  | Medium |
| etl_billiards/loaders/ods/generic.py | GenericODSLoader._normalize_row | method |  | Medium |
| etl_billiards/models/parsers.py | (module) | module | 数据类型解析器 | Medium |
| etl_billiards/models/parsers.py | TypeParser | class | 类型解析工具 | Medium |
| etl_billiards/models/parsers.py | TypeParser.parse_timestamp | method | 解析时间戳 | Medium |
| etl_billiards/models/parsers.py | TypeParser.parse_decimal | method | 解析金额 | Medium |
| etl_billiards/models/parsers.py | TypeParser.parse_int | method | 解析整数 | Medium |
| etl_billiards/models/parsers.py | TypeParser.format_timestamp | method | 格式化时间戳 | Medium |
| etl_billiards/models/validators.py | (module) | module | 数据验证器 | Medium |
| etl_billiards/models/validators.py | DataValidator | class | 数据验证工具 | Medium |
| etl_billiards/models/validators.py | DataValidator.validate_positive_amount | method | 验证金额为正数 | Medium |
| etl_billiards/models/validators.py | DataValidator.validate_required | method | 验证必填字段 | Medium |
| etl_billiards/models/validators.py | DataValidator.validate_range | method | 验证值范围 | Medium |
| etl_billiards/orchestration/cursor_manager.py | (module) | module | 游标管理器 | High |
| etl_billiards/orchestration/cursor_manager.py | CursorManager | class | ETL游标管理 | High |
| etl_billiards/orchestration/cursor_manager.py | CursorManager.__init__ | method |  | High |
| etl_billiards/orchestration/cursor_manager.py | CursorManager.get_or_create | method | 获取或创建游标 | High |
| etl_billiards/orchestration/cursor_manager.py | CursorManager.advance | method | 推进游标 | High |
| etl_billiards/orchestration/run_tracker.py | (module) | module | 运行记录追踪器 | High |
| etl_billiards/orchestration/run_tracker.py | RunTracker | class | ETL运行记录管理 | High |
| etl_billiards/orchestration/run_tracker.py | RunTracker.__init__ | method |  | High |
| etl_billiards/orchestration/run_tracker.py | RunTracker.create_run | method | 创建运行记录 | High |
| etl_billiards/orchestration/run_tracker.py | RunTracker.update_run | method | 更新运行记录 | High |
| etl_billiards/orchestration/scheduler.py | (module) | module | ETL 调度：支持在线抓取、离线清洗入库、全流程三种模式。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler | class | 调度多个任务，按 pipeline.flow 执行抓取/清洗入库。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler.__init__ | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._attach_run_file_logger | method | 为本次 run_uuid 动态挂载文件日志处理器。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler.run_tasks | method | 按配置或传入列表执行任务。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._run_single_task | method | 单个任务的抓取/清洗编排。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._execute_fetch | method | 在线抓取阶段：用 RecordingAPIClient 拉取并落盘，不做 Transform/Load。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._is_ods_task | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._execute_ods_record_and_load | method | Execute an ODS task with RecordingAPIClient so it fetches online and writes JSON dumps. | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._execute_ingest | method | 本地清洗入库：使用 LocalJsonClient 回放 JSON，走原有任务 ETL。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._build_fetch_dir | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._resolve_ingest_source | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._counts_from_fetch | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._flow_includes_fetch | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._flow_includes_ingest | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._run_utility_task | method | 执行工具类任务（不记录 cursor/run，直接执行）。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._load_task_config | method | 从数据库加载任务配置。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._maybe_run_integrity_check | method |  | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler.close | method | 关闭连接。 | High |
| etl_billiards/orchestration/scheduler.py | ETLScheduler._map_run_status | method | 将任务返回的状态转换为 etl_admin.run_status_enum | High |
| etl_billiards/orchestration/task_registry.py | (module) | module | 任务注册表 | High |
| etl_billiards/orchestration/task_registry.py | TaskRegistry | class | 任务注册和工厂 | High |
| etl_billiards/orchestration/task_registry.py | TaskRegistry.__init__ | method |  | High |
| etl_billiards/orchestration/task_registry.py | TaskRegistry.register | method | 注册任务类 | High |
| etl_billiards/orchestration/task_registry.py | TaskRegistry.create_task | method | 创建任务实例 | High |
| etl_billiards/orchestration/task_registry.py | TaskRegistry.get_all_task_codes | method | 获取所有已注册的任务代码 | High |
| etl_billiards/quality/balance_checker.py | (module) | module | 余额一致性检查器 | Medium |
| etl_billiards/quality/balance_checker.py | BalanceChecker | class | 检查订单、支付、退款的金额一致性 | Medium |
| etl_billiards/quality/balance_checker.py | BalanceChecker.check | method | 检查指定时间范围内的余额一致性 | Medium |
| etl_billiards/quality/base_checker.py | (module) | module | 数据质量检查器基类 | Medium |
| etl_billiards/quality/base_checker.py | BaseDataQualityChecker | class | 数据质量检查器基类 | Medium |
| etl_billiards/quality/base_checker.py | BaseDataQualityChecker.__init__ | method |  | Medium |
| etl_billiards/quality/base_checker.py | BaseDataQualityChecker.check | method | 执行质量检查 | Medium |
| etl_billiards/quality/integrity_checker.py | (module) | module | Integrity checks across API -> ODS -> DWD. | Medium |
| etl_billiards/quality/integrity_checker.py | IntegrityWindow | class |  | Medium |
| etl_billiards/quality/integrity_checker.py | _ensure_tz | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _month_start | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _next_month | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _date_to_start | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _date_to_end_exclusive | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | build_history_windows | function | Build weekly windows for current month, monthly windows for earlier months. | Medium |
| etl_billiards/quality/integrity_checker.py | _split_table | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _pick_time_column | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _fetch_columns | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _amount_columns | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _build_hash_expr | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _build_snapshot_subquery | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _build_snapshot_expr_subquery | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _cast_expr | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _fetch_pk_columns | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _pick_snapshot_order_column | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _count_table | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _sum_column | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | run_dwd_vs_ods_check | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | _default_report_path | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | run_integrity_window | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | run_integrity_history | function |  | Medium |
| etl_billiards/quality/integrity_checker.py | compute_last_etl_end | function |  | Medium |
| etl_billiards/quality/integrity_service.py | (module) | module | Shared integrity flow helpers (window/history + optional backfill). | Medium |
| etl_billiards/quality/integrity_service.py | _normalize_windows | function |  | Medium |
| etl_billiards/quality/integrity_service.py | build_window_report | function |  | Medium |
| etl_billiards/quality/integrity_service.py | run_window_flow | function |  | Medium |
| etl_billiards/quality/integrity_service.py | run_history_flow | function |  | Medium |
| etl_billiards/quality/integrity_service.py | write_report | function |  | Medium |
| etl_billiards/reports/__init__.py | (module) | module | Reports package. | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | (module) | module | 统计“忠实台球类竞技客户”Top N（按平均单次日打球小时数排序）。 | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | SessionRow | class |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | MemberAgg | class |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _as_tz | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _parse_date | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _date_floor | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _split_by_day | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _union_seconds | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _avg_gap_days | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _load_sessions | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _load_member_profiles | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _load_latest_settlement_contact | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _build_member_aggs | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | _write_report | function |  | Medium |
| etl_billiards/reports/loyal_billiards_customers_report.py | main | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | (module) | module | 按自定义名单统计累计打球总时长（同“忠实台球类竞技客户”口径） | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | InputRow | class |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _digits | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _normalize_name | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _read_input | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _load_member_candidates_by_phone | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _load_member_candidates_by_mobile | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _resolve_member_ids | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _load_sessions_for_members | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | _write_report | function |  | Medium |
| etl_billiards/reports/loyal_customers_total_hours_for_list.py | main | function |  | Medium |
| etl_billiards/run_update.py | (module) | module | 一键增量更新脚本（ODS -> DWD -> DWS）。 | Medium |
| etl_billiards/run_update.py | _coerce_date | function |  | Medium |
| etl_billiards/run_update.py | _compute_dws_window | function |  | Medium |
| etl_billiards/run_update.py | _run_check_cutoff | function |  | Medium |
| etl_billiards/run_update.py | _iter_daily_windows | function |  | Medium |
| etl_billiards/run_update.py | _run_step_worker | function |  | Medium |
| etl_billiards/run_update.py | _run_step_with_timeout | function |  | Medium |
| etl_billiards/run_update.py | main | function |  | Medium |
| etl_billiards/scd/scd2_handler.py | (module) | module | SCD2 (Slowly Changing Dimension Type 2) 处理逻辑 | Medium |
| etl_billiards/scd/scd2_handler.py | _row_to_dict | function |  | Medium |
| etl_billiards/scd/scd2_handler.py | SCD2Handler | class | SCD2历史记录处理 | Medium |
| etl_billiards/scd/scd2_handler.py | SCD2Handler.__init__ | method |  | Medium |
| etl_billiards/scd/scd2_handler.py | SCD2Handler.upsert | method | 处理SCD2更新 | Medium |
| etl_billiards/scripts/backfill_missing_data.py | (module) | module | 补全丢失的 ODS 数据 | Low |
| etl_billiards/scripts/backfill_missing_data.py | _reconfigure_stdout_utf8 | function |  | Low |
| etl_billiards/scripts/backfill_missing_data.py | _parse_dt | function |  | Low |
| etl_billiards/scripts/backfill_missing_data.py | _get_spec | function | 根据任务代码获取 ODS 任务规格 | Low |
| etl_billiards/scripts/backfill_missing_data.py | _merge_record_layers | function | Flatten nested data layers into a single dict. | Low |
| etl_billiards/scripts/backfill_missing_data.py | _get_value_case_insensitive | function | Fetch value without case sensitivity. | Low |
| etl_billiards/scripts/backfill_missing_data.py | _normalize_pk_value | function | Normalize PK value. | Low |
| etl_billiards/scripts/backfill_missing_data.py | _pk_tuple_from_record | function | Extract PK tuple from record. | Low |
| etl_billiards/scripts/backfill_missing_data.py | _get_table_pk_columns | function | 获取表的主键列 | Low |
| etl_billiards/scripts/backfill_missing_data.py | _get_table_columns | function | 获取表的所有列信息 | Low |
| etl_billiards/scripts/backfill_missing_data.py | _fetch_existing_pk_set | function | 获取已存在的 PK 集合 | Low |
| etl_billiards/scripts/backfill_missing_data.py | _cast_value | function | 类型转换 | Low |
| etl_billiards/scripts/backfill_missing_data.py | _normalize_scalar | function | 规范化标量值 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller | class | 丢失数据补全器 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller.__init__ | method |  | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller.close | method | 关闭连接 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller._ensure_db | method | 确保数据库连接可用 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller.backfill_from_gap_check | method | 运行 gap check 并补全丢失数据 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller._backfill_task | method | 补全单个任务的丢失数据 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller._build_params | method | 构建 API 请求参数 | Low |
| etl_billiards/scripts/backfill_missing_data.py | MissingDataBackfiller._insert_records | method | 插入记录到数据库 | Low |
| etl_billiards/scripts/backfill_missing_data.py | run_backfill | function | 运行数据补全 | Low |
| etl_billiards/scripts/backfill_missing_data.py | main | function |  | Low |
| etl_billiards/scripts/bootstrap_schema.py | (module) | module | Apply the PRD-aligned warehouse schema (ODS/DWD/DWS) to PostgreSQL. | Low |
| etl_billiards/scripts/bootstrap_schema.py | parse_args | function |  | Low |
| etl_billiards/scripts/bootstrap_schema.py | apply_schema | function |  | Low |
| etl_billiards/scripts/bootstrap_schema.py | main | function |  | Low |
| etl_billiards/scripts/build_dwd_from_ods.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Low |
| etl_billiards/scripts/build_dws_order_summary.py | (module) | module | Recompute billiards_dws.dws_order_summary from DWD tables (dwd_*). | Low |
| etl_billiards/scripts/build_dws_order_summary.py | parse_args | function |  | Low |
| etl_billiards/scripts/build_dws_order_summary.py | main | function |  | Low |
| etl_billiards/scripts/check_data_integrity.py | (module) | module | Run data integrity checks across API -> ODS -> DWD. | Low |
| etl_billiards/scripts/check_data_integrity.py | _parse_dt | function |  | Low |
| etl_billiards/scripts/check_data_integrity.py | main | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | (module) | module | Check missing ODS records by comparing API primary keys vs ODS table primary keys. | Low |
| etl_billiards/scripts/check_ods_gaps.py | _reconfigure_stdout_utf8 | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _parse_dt | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _iter_windows | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _merge_record_layers | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _chunked | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _get_table_pk_columns | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _table_has_column | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _fetch_existing_pk_set | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _fetch_existing_pk_hash_set | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _init_db_state | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _reconnect_db | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _ensure_db_conn | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _merge_common_params | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _build_params | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _pk_tuple_from_merged | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _pk_tuple_from_record | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _pk_tuple_from_ticket_candidate | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _format_missing_sample | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _format_mismatch_sample | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _check_spec | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _check_settlement_tickets | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _compute_ods_cutoff | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | _resolve_window_from_cutoff | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | run_gap_check | function |  | Low |
| etl_billiards/scripts/check_ods_gaps.py | main | function |  | Low |
| etl_billiards/scripts/check_ods_json_vs_table.py | (module) | module | ODS JSON 字段核对脚本：对照当前数据库中的 ODS 表字段，检查示例 JSON（默认目录 export/test-json-doc） | Low |
| etl_billiards/scripts/check_ods_json_vs_table.py | _flatten_keys | function | 递归展开 JSON 所有键路径，返回形如 data.assistantInfos.id 的集合。列表不保留索引，仅继续向下展开。 | Low |
| etl_billiards/scripts/check_ods_json_vs_table.py | _load_json_keys | function | 读取单个 JSON 文件并返回展开后的键集合以及末段->路径列表映射，若文件不存在或无法解析则返回空集合。 | Low |
| etl_billiards/scripts/check_ods_json_vs_table.py | _load_ods_columns | function | 从数据库读取 billiards_ods.* 的列名集合，按表返回。 | Low |
| etl_billiards/scripts/check_ods_json_vs_table.py | main | function | 主流程：遍历 FILE_MAPPING 中的 ODS 表，检查 JSON 键覆盖情况并打印报告。 | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | (module) | module | 迁移到“快照型 ODS + DWD SCD2”： | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _hash_default | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _sanitize_record_for_hash | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _compute_content_hash | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _fetch_tables | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _fetch_columns | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _fetch_pk_constraint | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _ensure_content_hash_column | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _backfill_content_hash | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _ensure_ods_primary_key | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _migrate_ods | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _backfill_scd2_fields | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _ensure_dwd_primary_key | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | _migrate_dwd | function |  | Low |
| etl_billiards/scripts/migrate_snapshot_ods.py | main | function |  | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | (module) | module | 一键重建 ETL 相关 Schema，并执行 ODS → DWD。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | RunArgs | class | 脚本参数对象（用于减少散落的参数传递）。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _attach_file_logger | function | 给 root logger 附加文件日志处理器（UTF-8）。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _parse_args | function | 解析命令行/环境变量参数。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _build_config | function | 构建本次执行所需的最小配置覆盖。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _drop_schemas | function | 删除并重建 ETL 相关 schema（具备破坏性，请谨慎）。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _terminate_own_idle_in_tx | function | 终止当前用户在本库中处于 idle-in-transaction 的会话，避免阻塞 DROP/DDL。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _run_task | function | 统一运行任务并打印关键结果。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _basic_validate | function | 做最基础的可用性校验：schema 存在、关键表行数可查询。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _connect_db_with_retry | function | 创建数据库连接（带重试），避免短暂网络抖动导致脚本直接失败。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _is_connection_error | function | 判断是否为连接断开/服务端异常导致的可重试错误。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | _run_stage_with_reconnect | function | 运行单个阶段：失败（尤其是连接断开）时自动重连并重试。 | Low |
| etl_billiards/scripts/rebuild_db_and_run_ods_to_dwd.py | main | function | 脚本主入口：按顺序重建并跑通 ODS→DWD。 | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | (module) | module | 从本地 JSON 示例目录重建 billiards_ods.* 表，并导入样例数据。 | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | sanitize_identifier | function | 将任意字符串转为可用的 SQL identifier（小写、非字母数字转下划线）。 | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | _extract_list_via_path | function |  | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | load_records | function | 尝试从 JSON 结构中提取记录列表： | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | collect_columns | function | 汇总所有顶层键，作为表字段；仅处理 dict 记录。 | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | create_table | function | 创建表：字段全部 jsonb，外加 source_file、record_index、payload、ingested_at。 | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | insert_records | function | 批量插入记录。 | Low |
| etl_billiards/scripts/rebuild_ods_from_json.py | rebuild | function |  | Low |
| etl_billiards/scripts/reload_ods_windowed.py | (module) | module | Reload ODS tasks by fixed time windows with optional sleep between windows. | Low |
| etl_billiards/scripts/reload_ods_windowed.py | _parse_dt | function |  | Low |
| etl_billiards/scripts/reload_ods_windowed.py | _iter_windows | function |  | Low |
| etl_billiards/scripts/reload_ods_windowed.py | _run_task_window | function |  | Low |
| etl_billiards/scripts/reload_ods_windowed.py | main | function |  | Low |
| etl_billiards/scripts/run_tests.py | (module) | module | 灵活的测试执行脚本，可像搭积木一样组合不同参数或预置命令（模式/数据库/归档路径等）， | Low |
| etl_billiards/scripts/run_tests.py | _load_presets | function |  | Low |
| etl_billiards/scripts/run_tests.py | parse_args | function |  | Low |
| etl_billiards/scripts/run_tests.py | apply_presets_to_args | function |  | Low |
| etl_billiards/scripts/run_tests.py | apply_env | function |  | Low |
| etl_billiards/scripts/run_tests.py | build_pytest_args | function |  | Low |
| etl_billiards/scripts/run_tests.py | main | function |  | Low |
| etl_billiards/scripts/test_db_connection.py | (module) | module | Quick utility for validating PostgreSQL connectivity (ASCII-only output). | Low |
| etl_billiards/scripts/test_db_connection.py | parse_args | function |  | Low |
| etl_billiards/scripts/test_db_connection.py | main | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | (module) | module | PostgreSQL connection performance test (ASCII-only output). | Low |
| etl_billiards/scripts/test_db_performance.py | _load_env | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | _apply_dsn_overrides | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | _build_dsn_from_env | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | _safe_dsn_summary | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | _percentile | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | _format_stats | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | parse_args | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | _run_round | function |  | Low |
| etl_billiards/scripts/test_db_performance.py | main | function |  | Low |
| etl_billiards/scripts/test_presets.py | (module) | module | 测试命令仓库：集中维护 run_tests.py 的常用组合，支持一键执行。 | Low |
| etl_billiards/scripts/test_presets.py | print_parameter_help | function |  | Low |
| etl_billiards/scripts/test_presets.py | print_presets | function |  | Low |
| etl_billiards/scripts/test_presets.py | resolve_targets | function |  | Low |
| etl_billiards/scripts/test_presets.py | run_presets | function |  | Low |
| etl_billiards/scripts/test_presets.py | main | function |  | Low |
| etl_billiards/setup.py | (module) | module | Setup script for ETL Billiards | Medium |
| etl_billiards/tasks/assistant_abolish_task.py | (module) | module | 助教作废任务 | Task |
| etl_billiards/tasks/assistant_abolish_task.py | AssistantAbolishTask | class | 同步助教作废记录 | Task |
| etl_billiards/tasks/assistant_abolish_task.py | AssistantAbolishTask.get_task_code | method |  | Task |
| etl_billiards/tasks/assistant_abolish_task.py | AssistantAbolishTask.extract | method |  | Task |
| etl_billiards/tasks/assistant_abolish_task.py | AssistantAbolishTask.transform | method |  | Task |
| etl_billiards/tasks/assistant_abolish_task.py | AssistantAbolishTask.load | method |  | Task |
| etl_billiards/tasks/assistant_abolish_task.py | AssistantAbolishTask._parse_record | method |  | Task |
| etl_billiards/tasks/assistants_task.py | (module) | module | 助教账号任务 | Task |
| etl_billiards/tasks/assistants_task.py | AssistantsTask | class | 同步助教账号资料 | Task |
| etl_billiards/tasks/assistants_task.py | AssistantsTask.get_task_code | method |  | Task |
| etl_billiards/tasks/assistants_task.py | AssistantsTask.extract | method |  | Task |
| etl_billiards/tasks/assistants_task.py | AssistantsTask.transform | method |  | Task |
| etl_billiards/tasks/assistants_task.py | AssistantsTask.load | method |  | Task |
| etl_billiards/tasks/assistants_task.py | AssistantsTask._parse_assistant | method |  | Task |
| etl_billiards/tasks/base_dwd_task.py | (module) | module | DWD任务基类 | Task |
| etl_billiards/tasks/base_dwd_task.py | BaseDwdTask | class | DWD 层任务基类 | Task |
| etl_billiards/tasks/base_dwd_task.py | BaseDwdTask._get_ods_cursor | method | 获取上次处理的 ODS 数据的时间点 (fetched_at) | Task |
| etl_billiards/tasks/base_dwd_task.py | BaseDwdTask.iter_ods_rows | method | 分批迭代读取 ODS 表数据 | Task |
| etl_billiards/tasks/base_dwd_task.py | BaseDwdTask.parse_payload | method | 解析 ODS 行中的 payload JSON | Task |
| etl_billiards/tasks/base_task.py | (module) | module | ETL任务基类（引入 Extract/Transform/Load 模板方法） | Task |
| etl_billiards/tasks/base_task.py | TaskContext | class | 统一透传给 Extract/Transform/Load 的运行期信息。 | Task |
| etl_billiards/tasks/base_task.py | BaseTask | class | 提供 E/T/L 模板的任务基类。 | Task |
| etl_billiards/tasks/base_task.py | BaseTask.__init__ | method |  | Task |
| etl_billiards/tasks/base_task.py | BaseTask.get_task_code | method | 获取任务代码 | Task |
| etl_billiards/tasks/base_task.py | BaseTask.extract | method | 提取数据 | Task |
| etl_billiards/tasks/base_task.py | BaseTask.transform | method | 转换数据 | Task |
| etl_billiards/tasks/base_task.py | BaseTask.load | method | 加载数据并返回统计信息 | Task |
| etl_billiards/tasks/base_task.py | BaseTask.execute | method | 统一 orchestrate Extract → Transform → Load | Task |
| etl_billiards/tasks/base_task.py | BaseTask._build_context | method |  | Task |
| etl_billiards/tasks/base_task.py | BaseTask._build_context_for_window | method |  | Task |
| etl_billiards/tasks/base_task.py | BaseTask._accumulate_counts | method |  | Task |
| etl_billiards/tasks/base_task.py | BaseTask._get_time_window | method | 计算时间窗口 | Task |
| etl_billiards/tasks/base_task.py | BaseTask._is_in_idle_window | method | 判断是否在闲时窗口 | Task |
| etl_billiards/tasks/base_task.py | BaseTask._merge_common_params | method | 合并全局/任务级参数池，便于在配置中统一覆�?/追加过滤条件。 | Task |
| etl_billiards/tasks/base_task.py | BaseTask._build_result | method | 构建结果字典 | Task |
| etl_billiards/tasks/check_cutoff_task.py | (module) | module | Task: report last successful cursor cutoff times from etl_admin. | Task |
| etl_billiards/tasks/check_cutoff_task.py | CheckCutoffTask | class | Report per-task cursor cutoff times (etl_admin.etl_cursor.last_end). | Task |
| etl_billiards/tasks/check_cutoff_task.py | CheckCutoffTask.get_task_code | method |  | Task |
| etl_billiards/tasks/check_cutoff_task.py | CheckCutoffTask.execute | method |  | Task |
| etl_billiards/tasks/check_cutoff_task.py | CheckCutoffTask._probe_ods_fetched_at | method |  | Task |
| etl_billiards/tasks/check_cutoff_task.py | CheckCutoffTask._probe_dw_time_columns | method |  | Task |
| etl_billiards/tasks/coupon_usage_task.py | (module) | module | 平台券核销任务 | Task |
| etl_billiards/tasks/coupon_usage_task.py | CouponUsageTask | class | 同步平台券验券/核销记录 | Task |
| etl_billiards/tasks/coupon_usage_task.py | CouponUsageTask.get_task_code | method |  | Task |
| etl_billiards/tasks/coupon_usage_task.py | CouponUsageTask.extract | method |  | Task |
| etl_billiards/tasks/coupon_usage_task.py | CouponUsageTask.transform | method |  | Task |
| etl_billiards/tasks/coupon_usage_task.py | CouponUsageTask.load | method |  | Task |
| etl_billiards/tasks/coupon_usage_task.py | CouponUsageTask._parse_usage | method |  | Task |
| etl_billiards/tasks/data_integrity_task.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Task |
| etl_billiards/tasks/dwd_load_task.py | (module) | module | DWD 装载任务：从 ODS 增量写入 DWD（维度 SCD2，事实按时间增量）。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask | class | 负责 DWD 装载：维度表做 SCD2 合并，事实表按时间增量写入。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._strip_scd2_keys | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._pick_snapshot_order_column | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._latest_snapshot_select_sql | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask.get_task_code | method | 返回任务编码。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask.extract | method | 准备运行所需的上下文信息。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask.load | method | 遍历映射关系，维度执行 SCD2 合并，事实表按时间增量插入。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._get_columns | method | 获取指定表的列名（小写）。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._get_primary_keys | method | 获取表的主键列名列表。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._get_column_types | method | 获取列的数据类型（information_schema.data_type）。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._build_column_mapping | method | 合并显式 FACT_MAPPINGS 与主键兜底映射。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._fetch_source_rows | method | 从源表读取指定列，返回小写键的字典列表。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._expand_goods_category_rows | method | 将分类表中的 categoryboxes 元素展开为子类记录。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._merge_dim | method | 维表合并策略： | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._merge_dim_type1_upsert | method | 维表 Type1 Upsert（主键冲突则更新），兼容带 scd2 字段但主键不支持多版本的表。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._merge_dim_scd2 | method | 对维表执行 SCD2 合并：对比变更关闭旧版并插入新版。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._close_current_dim_bulk | method | 批量关闭当前版本（scd2_is_current=0 + 填充结束时间）。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._insert_dim_rows_bulk | method | 批量插入新的 SCD2 版本行。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._upsert_scd2_row | method | SCD2 合并：若有变更则关闭旧版并插入新版本。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._close_current_dim | method | 关闭当前版本，标记 scd2_is_current=0 并填充结束时间。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._insert_dim_row | method | 插入新的 SCD2 版本行。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._is_row_changed | method | 比较非 SCD2 列，判断是否存在变更。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._values_equal | method | Normalize common type mismatches (numeric/text, naive/aware datetime) before compare. | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._normalize_empty | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._normalize_datetime | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._looks_numeric | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._coerce_numeric | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._looks_bool | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._coerce_bool | method |  | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._merge_fact_increment | method | 事实表按时间增量插入，默认按列名交集写入。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._pick_order_column | method | Pick an incremental order column that exists in both DWD and ODS. | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._get_fact_watermark | method | Fetch incremental watermark; default from DWD, fallback from ODS join. | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._insert_missing_by_pk | method | Backfill missing PK rows for facts that can receive late data. | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._build_fact_select_exprs | method | 构造事实表 SELECT 列表，需要时做类型转换。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._split_table_name | method | 拆分 schema.table，若无 schema 则补默认 schema。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._table_base | method | 获取不含 schema 的表名。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._format_table | method | 返回带引号的 schema.table 名称。 | Task |
| etl_billiards/tasks/dwd_load_task.py | DwdLoadTask._cast_expr | method | 构造带可选 CAST 的列表达式。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | (module) | module | DWD 质量核对任务：按 dwd_quality_check.md 输出行数/金额对照报表。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask | class | 对 ODS 与 DWD 进行行数、金额对照核查，生成 JSON 报表。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask.get_task_code | method | 返回任务编码。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask.extract | method | 准备运行时上下文。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask.load | method | 输出行数/金额差异报表到本地文件。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask._compare_counts | method | 统计两端行数并返回差异。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask._compare_amounts | method | 扫描金额相关列，生成 ODS 与 DWD 的汇总对照。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask._get_numeric_amount_columns | method | 获取列名包含金额关键词的数值型字段。 | Task |
| etl_billiards/tasks/dwd_quality_task.py | DwdQualityTask._split_table_name | method | 拆分 schema 与表名，缺省使用 default_schema。 | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | (module) | module | Build DWS order summary table from DWD fact tables. | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | DwsBuildOrderSummaryTask | class | Recompute/refresh `billiards_dws.dws_order_summary` for a date window. | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | DwsBuildOrderSummaryTask.get_task_code | method |  | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | DwsBuildOrderSummaryTask.execute | method |  | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | DwsBuildOrderSummaryTask.extract | method |  | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | DwsBuildOrderSummaryTask.load | method |  | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | _as_date | function |  | Task |
| etl_billiards/tasks/dws_build_order_summary_task.py | _jsonable_date | function |  | Task |
| etl_billiards/tasks/init_dwd_schema_task.py | (module) | module | 初始化 DWD Schema：执行 schema_dwd_doc.sql，可选先 DROP SCHEMA。 | Task |
| etl_billiards/tasks/init_dwd_schema_task.py | InitDwdSchemaTask | class | 通过调度执行 DWD schema 初始化。 | Task |
| etl_billiards/tasks/init_dwd_schema_task.py | InitDwdSchemaTask.get_task_code | method | 返回任务编码。 | Task |
| etl_billiards/tasks/init_dwd_schema_task.py | InitDwdSchemaTask.extract | method | 读取 DWD SQL 文件与参数。 | Task |
| etl_billiards/tasks/init_dwd_schema_task.py | InitDwdSchemaTask.load | method | 可选 DROP schema，再执行 DWD DDL。 | Task |
| etl_billiards/tasks/init_dws_schema_task.py | (module) | module | Initialize DWS schema (billiards_dws). | Task |
| etl_billiards/tasks/init_dws_schema_task.py | InitDwsSchemaTask | class | Apply DWS schema SQL. | Task |
| etl_billiards/tasks/init_dws_schema_task.py | InitDwsSchemaTask.get_task_code | method |  | Task |
| etl_billiards/tasks/init_dws_schema_task.py | InitDwsSchemaTask.extract | method |  | Task |
| etl_billiards/tasks/init_dws_schema_task.py | InitDwsSchemaTask.load | method |  | Task |
| etl_billiards/tasks/init_schema_task.py | (module) | module | 任务：初始化运行环境，执行 ODS 与 etl_admin 的 DDL，并准备日志/导出目录。 | Task |
| etl_billiards/tasks/init_schema_task.py | InitOdsSchemaTask | class | 通过调度执行初始化：创建必要目录，执行 ODS 与 etl_admin 的 DDL。 | Task |
| etl_billiards/tasks/init_schema_task.py | InitOdsSchemaTask.get_task_code | method | 返回任务编码。 | Task |
| etl_billiards/tasks/init_schema_task.py | InitOdsSchemaTask.extract | method | 读取 SQL 文件路径，收集需创建的目录。 | Task |
| etl_billiards/tasks/init_schema_task.py | InitOdsSchemaTask.load | method | 执行 DDL 并创建必要目录。 | Task |
| etl_billiards/tasks/inventory_change_task.py | (module) | module | 库存变更任务 | Task |
| etl_billiards/tasks/inventory_change_task.py | InventoryChangeTask | class | 同步库存变化记录 | Task |
| etl_billiards/tasks/inventory_change_task.py | InventoryChangeTask.get_task_code | method |  | Task |
| etl_billiards/tasks/inventory_change_task.py | InventoryChangeTask.extract | method |  | Task |
| etl_billiards/tasks/inventory_change_task.py | InventoryChangeTask.transform | method |  | Task |
| etl_billiards/tasks/inventory_change_task.py | InventoryChangeTask.load | method |  | Task |
| etl_billiards/tasks/inventory_change_task.py | InventoryChangeTask._parse_change | method |  | Task |
| etl_billiards/tasks/ledger_task.py | (module) | module | 助教流水任务 | Task |
| etl_billiards/tasks/ledger_task.py | LedgerTask | class | 同步助教服务台账 | Task |
| etl_billiards/tasks/ledger_task.py | LedgerTask.get_task_code | method |  | Task |
| etl_billiards/tasks/ledger_task.py | LedgerTask.extract | method |  | Task |
| etl_billiards/tasks/ledger_task.py | LedgerTask.transform | method |  | Task |
| etl_billiards/tasks/ledger_task.py | LedgerTask.load | method |  | Task |
| etl_billiards/tasks/ledger_task.py | LedgerTask._parse_ledger | method |  | Task |
| etl_billiards/tasks/manual_ingest_task.py | (module) | module | 手工示例数据灌入：按 schema_ODS_doc.sql 的表结构写入 ODS。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask | class | 本地示例 JSON 灌入 ODS，确保表名/主键/插入列与 schema_ODS_doc.sql 对齐。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask.get_task_code | method | 返回任务编码。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask.execute | method | 从目录读取 JSON，按表定义批量入库（按文件提交事务，避免长事务导致连接不稳定）。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._match_by_filename | method | 根据文件名关键字匹配目标表。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._extract_records | method | 兼容多层 data/list 包装，抽取记录列表。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._get_table_columns | method | 查询 information_schema，获取目标表列信息。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._ingest_table | method | 构建 INSERT/ON CONFLICT 语句并批量执行（优先向量化，小批次提交）。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._get_value_case_insensitive | method | 忽略大小写获取值，兼容 information_schema 与 JSON 原始字段。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._normalize_scalar | method | 将空字符串/空 JSON 规范为 None，避免类型转换错误。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._cast_value | method | 根据列类型做简单转换，保证批量插入兼容。 | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._hash_default | method |  | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._sanitize_record_for_hash | method |  | Task |
| etl_billiards/tasks/manual_ingest_task.py | ManualIngestTask._compute_content_hash | method |  | Task |
| etl_billiards/tasks/members_dwd_task.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Task |
| etl_billiards/tasks/members_task.py | (module) | module | 会员ETL任务 | Task |
| etl_billiards/tasks/members_task.py | MembersTask | class | 会员ETL任务 | Task |
| etl_billiards/tasks/members_task.py | MembersTask.get_task_code | method |  | Task |
| etl_billiards/tasks/members_task.py | MembersTask.extract | method |  | Task |
| etl_billiards/tasks/members_task.py | MembersTask.transform | method |  | Task |
| etl_billiards/tasks/members_task.py | MembersTask.load | method |  | Task |
| etl_billiards/tasks/members_task.py | MembersTask._parse_member | method | 解析会员记录 | Task |
| etl_billiards/tasks/ods_json_archive_task.py | (module) | module | 在线抓取 ODS 相关接口并落盘为 JSON（用于后续离线回放/入库）。 | Task |
| etl_billiards/tasks/ods_json_archive_task.py | EndpointSpec | class |  | Task |
| etl_billiards/tasks/ods_json_archive_task.py | OdsJsonArchiveTask | class | 抓取一组 ODS 所需接口并落盘为“简化 JSON”： | Task |
| etl_billiards/tasks/ods_json_archive_task.py | OdsJsonArchiveTask.get_task_code | method |  | Task |
| etl_billiards/tasks/ods_json_archive_task.py | OdsJsonArchiveTask.extract | method |  | Task |
| etl_billiards/tasks/ods_json_archive_task.py | OdsJsonArchiveTask._build_params | method |  | Task |
| etl_billiards/tasks/ods_tasks.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Task |
| etl_billiards/tasks/orders_task.py | (module) | module | 订单ETL任务 | Task |
| etl_billiards/tasks/orders_task.py | OrdersTask | class | 订单数据ETL任务 | Task |
| etl_billiards/tasks/orders_task.py | OrdersTask.get_task_code | method |  | Task |
| etl_billiards/tasks/orders_task.py | OrdersTask.extract | method | 调用 API 拉取订单记录 | Task |
| etl_billiards/tasks/orders_task.py | OrdersTask.transform | method | 解析原始订单 JSON | Task |
| etl_billiards/tasks/orders_task.py | OrdersTask.load | method | 写入 fact_order | Task |
| etl_billiards/tasks/orders_task.py | OrdersTask._parse_order | method | 解析单条订单记录 | Task |
| etl_billiards/tasks/packages_task.py | (module) | module | 团购/套餐定义任务 | Task |
| etl_billiards/tasks/packages_task.py | PackagesDefTask | class | 同步团购套餐定义 | Task |
| etl_billiards/tasks/packages_task.py | PackagesDefTask.get_task_code | method |  | Task |
| etl_billiards/tasks/packages_task.py | PackagesDefTask.extract | method |  | Task |
| etl_billiards/tasks/packages_task.py | PackagesDefTask.transform | method |  | Task |
| etl_billiards/tasks/packages_task.py | PackagesDefTask.load | method |  | Task |
| etl_billiards/tasks/packages_task.py | PackagesDefTask._parse_package | method |  | Task |
| etl_billiards/tasks/payments_dwd_task.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Task |
| etl_billiards/tasks/payments_task.py | (module) | module | 支付记录ETL任务 | Task |
| etl_billiards/tasks/payments_task.py | PaymentsTask | class | 支付记录 E/T/L 任务 | Task |
| etl_billiards/tasks/payments_task.py | PaymentsTask.get_task_code | method |  | Task |
| etl_billiards/tasks/payments_task.py | PaymentsTask.extract | method | 调用 API 抓取支付记录 | Task |
| etl_billiards/tasks/payments_task.py | PaymentsTask.transform | method | 解析支付 JSON | Task |
| etl_billiards/tasks/payments_task.py | PaymentsTask.load | method | 写入 fact_payment | Task |
| etl_billiards/tasks/payments_task.py | PaymentsTask._parse_payment | method | 解析支付记录 | Task |
| etl_billiards/tasks/products_task.py | (module) | module | 商品档案（PRODUCTS）ETL任务 | Task |
| etl_billiards/tasks/products_task.py | ProductsTask | class | 商品维度 ETL 任务 | Task |
| etl_billiards/tasks/products_task.py | ProductsTask.get_task_code | method |  | Task |
| etl_billiards/tasks/products_task.py | ProductsTask.extract | method |  | Task |
| etl_billiards/tasks/products_task.py | ProductsTask.transform | method |  | Task |
| etl_billiards/tasks/products_task.py | ProductsTask.load | method |  | Task |
| etl_billiards/tasks/products_task.py | ProductsTask._parse_product | method |  | Task |
| etl_billiards/tasks/refunds_task.py | (module) | module | 退款记录任务 | Task |
| etl_billiards/tasks/refunds_task.py | RefundsTask | class | 同步支付退款流水 | Task |
| etl_billiards/tasks/refunds_task.py | RefundsTask.get_task_code | method |  | Task |
| etl_billiards/tasks/refunds_task.py | RefundsTask.extract | method |  | Task |
| etl_billiards/tasks/refunds_task.py | RefundsTask.transform | method |  | Task |
| etl_billiards/tasks/refunds_task.py | RefundsTask.load | method |  | Task |
| etl_billiards/tasks/refunds_task.py | RefundsTask._parse_refund | method |  | Task |
| etl_billiards/tasks/table_discount_task.py | (module) | module | 台费折扣任务 | Task |
| etl_billiards/tasks/table_discount_task.py | TableDiscountTask | class | 同步台费折扣/调价记录 | Task |
| etl_billiards/tasks/table_discount_task.py | TableDiscountTask.get_task_code | method |  | Task |
| etl_billiards/tasks/table_discount_task.py | TableDiscountTask.extract | method |  | Task |
| etl_billiards/tasks/table_discount_task.py | TableDiscountTask.transform | method |  | Task |
| etl_billiards/tasks/table_discount_task.py | TableDiscountTask.load | method |  | Task |
| etl_billiards/tasks/table_discount_task.py | TableDiscountTask._parse_discount | method |  | Task |
| etl_billiards/tasks/tables_task.py | (module) | module | 台桌档案任务 | Task |
| etl_billiards/tasks/tables_task.py | TablesTask | class | 同步门店台桌列表 | Task |
| etl_billiards/tasks/tables_task.py | TablesTask.get_task_code | method |  | Task |
| etl_billiards/tasks/tables_task.py | TablesTask.extract | method |  | Task |
| etl_billiards/tasks/tables_task.py | TablesTask.transform | method |  | Task |
| etl_billiards/tasks/tables_task.py | TablesTask.load | method |  | Task |
| etl_billiards/tasks/tables_task.py | TablesTask._parse_table | method |  | Task |
| etl_billiards/tasks/ticket_dwd_task.py | TicketDwdTask | class | DWD Task: Process Ticket Details from ODS to Fact Tables | Task |
| etl_billiards/tasks/ticket_dwd_task.py | TicketDwdTask.get_task_code | method |  | Task |
| etl_billiards/tasks/ticket_dwd_task.py | TicketDwdTask.execute | method |  | Task |
| etl_billiards/tasks/topups_task.py | (module) | module | 充值记录任务 | Task |
| etl_billiards/tasks/topups_task.py | TopupsTask | class | 同步储值充值结算记录 | Task |
| etl_billiards/tasks/topups_task.py | TopupsTask.get_task_code | method |  | Task |
| etl_billiards/tasks/topups_task.py | TopupsTask.extract | method |  | Task |
| etl_billiards/tasks/topups_task.py | TopupsTask.transform | method |  | Task |
| etl_billiards/tasks/topups_task.py | TopupsTask.load | method |  | Task |
| etl_billiards/tasks/topups_task.py | TopupsTask._parse_topup | method |  | Task |
| etl_billiards/tests/integration/test_database.py | (module) | module | 数据库集成测试 | Low |
| etl_billiards/tests/integration/test_database.py | db_connection | function | 数据库连接fixture | Low |
| etl_billiards/tests/integration/test_database.py | test_database_query | function | 测试数据库查询 | Low |
| etl_billiards/tests/integration/test_database.py | test_database_operations | function | 测试数据库操作 | Low |
| etl_billiards/tests/unit/task_test_utils.py | (module) | module | ETL 任务测试的共用辅助模块，涵盖在线/离线模式所需的伪造数据、客户端与配置等工具函数。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | TaskSpec | class | 描述单个任务在测试中如何被驱动的元数据，包含任务代码、API 路径、数据路径与样例记录。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | TaskSpec.archive_filename | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | wrap_records | function | 按照 data_path 逐层包裹记录列表，使其结构与真实 API 返回体一致，方便离线回放。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | create_test_config | function | 构建一份适合测试的 AppConfig，自动填充存储、日志、归档目录等参数并保证目录存在。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | dump_offline_payload | function | 将 TaskSpec 的样例数据写入指定归档目录，供离线测试回放使用，并返回生成文件的完整路径。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor | class | 极简游标桩对象，记录 SQL/参数并支持上下文管理，供 FakeDBOperations 与 SCD2Handler 使用。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.__init__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.execute | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.fetchone | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.fetchall | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.mogrify | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor._record_upserts | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor._fake_columns | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.__enter__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeCursor.__exit__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeConnection | class | 仿 psycopg 连接对象，仅满足 SCD2Handler 对 cursor 的最小需求，并缓存执行过的语句。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeConnection.__init__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeConnection.cursor | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations | class | 拦截并记录批量 upsert/事务操作，避免触碰真实数据库，同时提供 commit/rollback 计数。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.__init__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.batch_upsert_with_returning | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.batch_execute | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.execute | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.query | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.cursor | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.commit | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeDBOperations.rollback | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeAPIClient | class | 在线模式使用的伪 API Client，直接返回预置的内存数据并记录调用，以确保任务参数正确传递。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeAPIClient.__init__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeAPIClient.iter_paginated | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeAPIClient.get_paginated | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | FakeAPIClient.get_source_hint | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | OfflineAPIClient | class | 离线模式专用 API Client，根据 endpoint 读取归档 JSON、套入 data_path 并回放列表数据。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | OfflineAPIClient.__init__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | OfflineAPIClient.iter_paginated | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | OfflineAPIClient.get_paginated | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | OfflineAPIClient.get_source_hint | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter | class | 连接真实 PostgreSQL 的适配器，为任务提供 batch_upsert + 事务能力。 | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter.__init__ | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter.batch_upsert_with_returning | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter.batch_execute | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter.commit | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter.rollback | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | RealDBOperationsAdapter.close | method |  | Low |
| etl_billiards/tests/unit/task_test_utils.py | get_db_operations | function | 测试专用的 DB 操作上下文： | Low |
| etl_billiards/tests/unit/test_config.py | (module) | module | 配置管理测试 | Low |
| etl_billiards/tests/unit/test_config.py | test_config_load | function | 测试配置加载 | Low |
| etl_billiards/tests/unit/test_config.py | test_config_override | function | 测试配置覆盖 | Low |
| etl_billiards/tests/unit/test_config.py | test_config_get_nested | function | 测试嵌套配置获取 | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | (module) | module | Unit tests for recent/former endpoint routing. | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | _now | function |  | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | test_recent_boundary_month_start | function |  | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | test_paylog_routes_to_former_when_old_window | function |  | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | test_coupon_usage_stays_same_path_even_when_old | function |  | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | test_goods_outbound_routes_to_queryformer_when_old | function |  | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | test_settlement_records_split_when_crossing_boundary | function |  | Low |
| etl_billiards/tests/unit/test_endpoint_routing.py | test_explicit_former_endpoint_not_rerouted | function |  | Low |
| etl_billiards/tests/unit/test_etl_tasks_offline.py | (module) | module | 离线模式任务测试，通过回放归档 JSON 来验证 T+L 链路可用。 | Low |
| etl_billiards/tests/unit/test_etl_tasks_offline.py | test_task_offline_mode | function | 确保每个任务都能读取归档 JSON 并完成 Transform + Load 操作。 | Low |
| etl_billiards/tests/unit/test_etl_tasks_online.py | (module) | module | 在线模式下的端到端任务测试，验证所有任务在模拟 API 下能顺利执行。 | Low |
| etl_billiards/tests/unit/test_etl_tasks_online.py | test_task_online_mode | function | 针对每个 TaskSpec 验证：模拟 API 数据下依旧能完整跑完 ETL，并正确统计。 | Low |
| etl_billiards/tests/unit/test_etl_tasks_stages.py | (module) | module | 验证 14 个任务的 E/T/L 分阶段调用（FakeDB/FakeAPI，不访问真实接口或数据库）。 | Low |
| etl_billiards/tests/unit/test_etl_tasks_stages.py | _build_context | function |  | Low |
| etl_billiards/tests/unit/test_etl_tasks_stages.py | test_etl_stage_flow | function | 对每个任务，单独调用 transform/load，验证 counts 结构与 FakeDB 写入。 | Low |
| etl_billiards/tests/unit/test_ods_tasks.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Low |
| etl_billiards/tests/unit/test_parsers.py | (module) | module | 解析器测试 | Low |
| etl_billiards/tests/unit/test_parsers.py | test_parse_decimal | function | 测试金额解析 | Low |
| etl_billiards/tests/unit/test_parsers.py | test_parse_int | function | 测试整数解析 | Low |
| etl_billiards/tests/unit/test_parsers.py | test_parse_timestamp | function | 测试时间戳解析 | Low |
| etl_billiards/tests/unit/test_reporting.py | (module) | module | 汇总与报告工具的单测。 | Low |
| etl_billiards/tests/unit/test_reporting.py | test_summarize_counts_and_format | function |  | Low |
| etl_billiards/utils/helpers.py | (module) | module | 通用工具函数 | High |
| etl_billiards/utils/helpers.py | ensure_dir | function | 确保目录存在 | High |
| etl_billiards/utils/helpers.py | make_surrogate_key | function | 生成代理键 | High |
| etl_billiards/utils/helpers.py | now_local | function | 获取本地当前时间 | High |
| etl_billiards/utils/json_store.py | (module) | module | JSON 归档/读取的通用工具。 | High |
| etl_billiards/utils/json_store.py | endpoint_to_filename | function | 将 API endpoint 转换为规范化的文件名，优先使用 非球接口API.md 中约定的名称。 | High |
| etl_billiards/utils/json_store.py | dump_json | function | 将 JSON 对象写入文件，默认紧凑，可选美化。 | High |
| etl_billiards/utils/json_store.py | _normalize_endpoint | function | 标准化 endpoint，提取路径部分并统一小写、去除 base 前缀。 | High |
| etl_billiards/utils/logging_utils.py | TeeStream | class |  | High |
| etl_billiards/utils/logging_utils.py | TeeStream.__init__ | method |  | High |
| etl_billiards/utils/logging_utils.py | TeeStream.write | method |  | High |
| etl_billiards/utils/logging_utils.py | TeeStream.flush | method |  | High |
| etl_billiards/utils/logging_utils.py | TeeStream.isatty | method |  | High |
| etl_billiards/utils/logging_utils.py | TeeStream.fileno | method |  | High |
| etl_billiards/utils/logging_utils.py | build_log_path | function |  | High |
| etl_billiards/utils/logging_utils.py | configure_logging | function |  | High |
| etl_billiards/utils/ods_record_utils.py | (module) | module | Shared helpers for ODS/API record normalization. | High |
| etl_billiards/utils/ods_record_utils.py | merge_record_layers | function | Flatten nested data/settleList layers into a single dict. | High |
| etl_billiards/utils/ods_record_utils.py | get_value_case_insensitive | function | Fetch column value without case sensitivity. | High |
| etl_billiards/utils/ods_record_utils.py | normalize_pk_value | function | Normalize PK value (e.g., digit string -> int). | High |
| etl_billiards/utils/ods_record_utils.py | pk_tuple_from_record | function | Extract PK tuple from a record. | High |
| etl_billiards/utils/reporting.py | (module) | module | 简单的任务结果汇总与格式化工具。 | High |
| etl_billiards/utils/reporting.py | summarize_counts | function | 汇总多个任务的 counts，返回总计与逐任务明细。 | High |
| etl_billiards/utils/reporting.py | format_report | function | 将 summarize_counts 的输出格式化为可读文案。 | High |
| etl_billiards/utils/windowing.py | (module) | module | Time window helpers for ETL and validation tasks. | High |
| etl_billiards/utils/windowing.py | _ensure_tz | function |  | High |
| etl_billiards/utils/windowing.py | _next_month_start | function |  | High |
| etl_billiards/utils/windowing.py | calc_window_minutes | function |  | High |
| etl_billiards/utils/windowing.py | split_window | function |  | High |
| etl_billiards/utils/windowing.py | build_window_segments | function |  | High |
| query_db.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/etl_billiards_misc/0.py | (module) | module | Simple PostgreSQL connectivity smoke-checker. | Medium |
| tmp/etl_billiards_misc/0.py | check_postgres_connection | function | Return True if connection succeeds; print diagnostics otherwise. | Medium |
| tmp/etl_billiards_misc/backups/manual_ingest_task.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/fetch_member_balance_change.py | (module) | module | 获取会员余额变动数据: /MemberProfile/GetMemberCardBalanceChange | Medium |
| tmp/fetch_member_balance_change.py | main | function |  | Medium |
| tmp/hebing.py | merge_md_and_json | function | 在指定目录下，将 .md 和 .json 文件按规则合并输出到一个文件中。 | Medium |
| tmp/query_missing_tables.py | safe_str | function |  | Medium |
| tmp/rewrite_schema_dwd_doc_comments.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/rewrite_schema_ods_doc_comments.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/tmp_debug_sql.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/tmp_drop_dwd.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/tmp_dwd_tasks.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/tmp_problems.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
| tmp/tmp_run_sql.py | (parse_error) | module | invalid non-printable character U+FEFF (<unknown>, line 1) | Medium |
