Похоже работает

This commit is contained in:
2026-02-07 11:26:06 +03:00
parent 7de96c17c4
commit 0f16bab2b8
26 changed files with 62583 additions and 58745 deletions

View File

@@ -27,6 +27,7 @@ Stores the outcome of a dashboard validation task.
| timestamp | DateTime | Yes | When the validation ran |
| status | Enum | Yes | `PASS`, `WARN`, `FAIL` |
| screenshot_path | String | No | Path to the captured screenshot (if stored) |
| screenshot_metadata | JSON | No | `{width: 1920, height: dynamic, tabs_processed: []}` |
| issues | JSON | Yes | List of detected issues `[{severity, message, location}]` |
| raw_response | Text | No | Full LLM response for debugging |

View File

@@ -23,6 +23,25 @@ This feature implements two new plugins for the `ss-tools` platform: `DashboardV
**Constraints**: Must integrate with existing `PluginBase` and `TaskManager`. Secure storage for API keys.
**Scale/Scope**: Support for configurable LLM providers, scheduled tasks, and notification integration.
## Implementation Notes
### Screenshot Capture Implementation
The screenshot service uses Playwright with Chrome DevTools Protocol (CDP) to avoid font loading timeouts in headless mode. Key implementation details:
- **Full Page Capture**: Uses CDP `Page.captureScreenshot` with `captureBeyondViewport: true` and `fromSurface: true`
- **Tab Switching**: Implements recursive tab switching to trigger lazy-loaded chart rendering on multi-tab dashboards
- **Authentication**: Uses direct UI login flow (navigating to `/login/` and filling credentials) instead of API cookie injection for better reliability
- **Resolution**: 1920px width with dynamic full page height calculation
### Authentication Flow
The service authenticates via Playwright UI login rather than API authentication:
1. Navigate to `/login/` page
2. Fill username/password fields (supports multiple Superset versions)
3. Click login button
4. Verify successful redirect to `/superset/welcome/`
5. Navigate to dashboard with valid session
This approach is more reliable than API-to-UI cookie injection which was causing 403 Forbidden errors.
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
@@ -60,7 +79,8 @@ backend/
│ │ ├── llm_analysis/ # New Plugin Directory
│ │ │ ├── __init__.py
│ │ │ ├── plugin.py # Implements DashboardValidationPlugin & DocumentationPlugin
│ │ │ ├── service.py # LLM interaction logic
│ │ │ ├── service.py # LLM interaction logic + ScreenshotService (CDP, tab switching)
│ │ │ ├── scheduler.py # Scheduled validation task handler
│ │ │ └── models.py # Pydantic models for LLM config/results
│ │ └── git/ # Existing Git Plugin
│ │ └── ... # Update for commit message generation

View File

@@ -30,7 +30,7 @@
**Goal**: Implement core services and shared infrastructure.
- [x] T008 Implement `LLMProviderService` in `backend/src/services/llm_provider.py` (CRUD for providers, AES-256 encryption)
- [x] T009 Implement `ScreenshotService` in `backend/src/plugins/llm_analysis/service.py` (Playwright + API strategies, fallback logic, min 1280x720px resolution)
- [x] T009 Implement `ScreenshotService` in `backend/src/plugins/llm_analysis/service.py` (Playwright + API strategies, fallback logic, 1920px width, full page height, CDP screenshot, recursive tab switching)
- [x] T010 Implement `LLMClient` in `backend/src/plugins/llm_analysis/service.py` (OpenAI SDK wrapper, retry logic with tenacity, rate limit handling)
- [x] T011 Create `backend/src/plugins/llm_analysis/plugin.py` with `PluginBase` implementation stubs
- [x] T012 Define database schema updates for `LLMProviderConfig` in `backend/src/models/llm.py` (or appropriate location)
@@ -43,7 +43,7 @@
- [x] T014 [US1] Implement `validate_dashboard` task logic in `backend/src/plugins/llm_analysis/plugin.py`
- [x] T015 [US1] Implement log retrieval logic (fetch recent logs, limit 100 lines/24h) in `backend/src/plugins/llm_analysis/plugin.py`
- [x] T016 [US1] Construct multimodal prompt (image + text) in `backend/src/plugins/llm_analysis/service.py` (implement PII/credential filtering)
- [x] T017 [US1] Implement result parsing and persistence (ValidationResult) in `backend/src/plugins/llm_analysis/plugin.py` (ensure JSON structure: status, issues, summary)
- [x] T017 [US1] Implement result parsing and persistence (ValidationResult) in `backend/src/plugins/llm_analysis/plugin.py` (ensure JSON structure: status, issues, summary, log results to task output with `[ANALYSIS_SUMMARY]` and `[ANALYSIS_ISSUE]` markers)
- [x] T018 [US1] Add `validate` endpoint trigger in `backend/src/api/routes/tasks.py` (or reuse existing dispatch)
- [x] T019 [US1] Implement notification dispatch (Email/Pulse) on failure in `backend/src/plugins/llm_analysis/plugin.py` (Summary + Link format)
- [x] T020 [US1] Create `frontend/src/components/llm/ValidationReport.svelte` for viewing results

View File

@@ -247,6 +247,14 @@
- 📝 Fetches AD mappings and roles from the backend to populate the UI.
- ƒ **handleCreateMapping** (`Function`)
- 📝 Submits a new AD Group to Role mapping to the backend.
- 🧩 **LLMSettingsPage** (`Component`)
- 📝 Admin settings page for LLM provider configuration.
- 🏗️ Layer: UI
- 📦 **+page** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/routes/admin/settings/llm/+page.svelte
- 🏗️ Layer: Unknown
- ƒ **fetchProviders** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 🧩 **MigrationDashboard** (`Component`)
- 📝 Main dashboard for configuring and starting migrations.
- 🏗️ Layer: Page
@@ -492,10 +500,12 @@
- 📝 Displays a grid of dashboards with selection and pagination.
- 🏗️ Layer: Component
- 🔒 Invariant: Selected IDs must be a subset of available dashboards.
- 📥 Props: dashboards: DashboardMetadata[] , selectedIds: number[]
- 📥 Props: dashboards: DashboardMetadata[] , selectedIds: number[] , environmentId: string
- ⚡ Events: selectionChanged
- ➡️ WRITES_TO `t`
- ⬅️ READS_FROM `t`
- ƒ **handleValidate** (`Function`)
- 📝 Triggers dashboard validation task.
- ƒ **handleSort** (`Function`)
- 📝 Toggles sort direction or changes sort column.
- ƒ **handleSelectionChange** (`Function`)
@@ -647,6 +657,13 @@
- 📝 Fetches environments and saved connections.
- ƒ **handleRunMapper** (`Function`)
- 📝 Triggers the MapperPlugin task.
- ƒ **handleGenerateDocs** (`Function`)
- 📝 Triggers the LLM Documentation task.
- 📦 **MapperTool** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/components/tools/MapperTool.svelte
- 🏗️ Layer: Unknown
- ƒ **handleApplyDoc** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 🧩 **DebugTool** (`Component`)
- 📝 UI component for system diagnostics and debugging API responses.
- 🏗️ Layer: UI
@@ -692,6 +709,8 @@
- 🏗️ Layer: Component
- 📥 Props: dashboardId: any, show: any
- ⚡ Events: commit
- ƒ **handleGenerateMessage** (`Function`)
- 📝 Generates a commit message using LLM.
- ƒ **loadStatus** (`Function`)
- 📝 Загружает текущий статус репозитория и diff.
- ƒ **handleCommit** (`Function`)
@@ -728,6 +747,41 @@
- 📝 Pushes local commits to the remote repository.
- ƒ **handlePull** (`Function`)
- 📝 Pulls changes from the remote repository.
- 🧩 **DocPreview** (`Component`)
- 📝 UI component for previewing generated dataset documentation before saving.
- 🏗️ Layer: UI
- 📥 Props: documentation: any, onSave: any, onCancel: any
- ➡️ WRITES_TO `t`
- ⬅️ READS_FROM `t`
- 📦 **DocPreview** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/components/llm/DocPreview.svelte
- 🏗️ Layer: Unknown
- ƒ **handleSave** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 🧩 **ProviderConfig** (`Component`)
- 📝 UI form for managing LLM provider configurations.
- 🏗️ Layer: UI
- 📥 Props: providers: any, onSave: any
- ➡️ WRITES_TO `t`
- ⬅️ READS_FROM `t`
- 📦 **ProviderConfig** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/components/llm/ProviderConfig.svelte
- 🏗️ Layer: Unknown
- ƒ **resetForm** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleEdit** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **testConnection** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleSubmit** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **toggleActive** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **ValidationReport** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/components/llm/ValidationReport.svelte
- 🏗️ Layer: Unknown
- ƒ **getStatusColor** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.delete_running_tasks** (`Module`)
- 📝 Script to delete tasks with RUNNING status from the database.
- 🏗️ Layer: Utility
@@ -752,6 +806,8 @@
- 📝 Serves frontend static files or index.html for SPA routing.
- ƒ **read_root** (`Function`)
- 📝 A simple root endpoint to confirm that the API is running when frontend is missing.
- ƒ **network_error_handler** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **Dependencies** (`Module`)
- 📝 Manages the creation and provision of shared application dependencies, such as the PluginLoader and TaskManager, to avoid circular imports.
- 🏗️ Layer: Core
@@ -941,6 +997,8 @@
- 🏗️ Layer: Core
- 🔒 Invariant: A single engine instance is used for the entire application.
- 🔗 DEPENDS_ON -> `sqlalchemy`
- 📦 **BASE_DIR** (`Variable`)
- 📝 Base directory for the backend (where .db files should reside).
- 📦 **DATABASE_URL** (`Constant`)
- 📝 URL for the main mappings database.
- 📦 **TASKS_DATABASE_URL** (`Constant`)
@@ -1328,6 +1386,20 @@
- 📝 Initiates the ADFS OIDC login flow.
- ƒ **auth_callback_adfs** (`Function`)
- 📝 Handles the callback from ADFS after successful authentication.
- 📦 **router** (`Global`)
- 📝 APIRouter instance for LLM routes.
- ƒ **get_providers** (`Function`)
- 📝 Retrieve all LLM provider configurations.
- ƒ **create_provider** (`Function`)
- 📝 Create a new LLM provider configuration.
- ƒ **update_provider** (`Function`)
- 📝 Update an existing LLM provider configuration.
- ƒ **delete_provider** (`Function`)
- 📝 Delete an LLM provider configuration.
- ƒ **test_connection** (`Function`)
- 📝 Test connection to an LLM provider.
- ƒ **test_provider_config** (`Function`)
- 📝 Test connection with a provided configuration (not yet saved).
- 📦 **backend.src.api.routes.git** (`Module`)
- 📝 Provides FastAPI endpoints for Git integration operations.
- 🏗️ Layer: API
@@ -1366,6 +1438,8 @@
- 📝 Get current Git status for a dashboard repository.
- ƒ **get_repository_diff** (`Function`)
- 📝 Get Git diff for a dashboard repository.
- ƒ **generate_commit_message** (`Function`)
- 📝 Generate a suggested commit message using LLM.
- 📦 **ConnectionsRouter** (`Module`)
- 📝 Defines the FastAPI router for managing external database connections.
- 🏗️ Layer: UI (API)
@@ -1546,6 +1620,15 @@
- 📝 Resume a task that is awaiting input (e.g., passwords).
- ƒ **clear_tasks** (`Function`)
- 📝 Clear tasks matching the status filter.
- 📦 **backend.src.models.llm** (`Module`)
- 📝 SQLAlchemy models for LLM provider configuration and validation results.
- 🏗️ Layer: Domain
- **LLMProvider** (`Class`)
- 📝 SQLAlchemy model for LLM provider configuration.
- **ValidationRecord** (`Class`)
- 📝 SQLAlchemy model for dashboard validation history.
- ƒ **generate_uuid** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **GitModels** (`Module`)
- 📝 Git-specific SQLAlchemy models for configuration and repository tracking.
- 🏗️ Layer: Model
@@ -1608,6 +1691,36 @@
- **ADGroupMapping** (`Class`)
- 📝 Maps an Active Directory group to a local System Role.
- 🔗 DEPENDS_ON -> `Role`
- 📦 **backend.src.services.llm_provider** (`Module`)
- 📝 Service for managing LLM provider configurations with encrypted API keys.
- 🏗️ Layer: Domain
- 🔗 DEPENDS_ON -> `backend.src.core.database`
- 🔗 DEPENDS_ON -> `backend.src.models.llm`
- **EncryptionManager** (`Class`)
- 📝 Handles encryption and decryption of sensitive data like API keys.
- 🔒 Invariant: Uses a secret key from environment or a default one (fallback only for dev).
- **LLMProviderService** (`Class`)
- 📝 Service to manage LLM provider lifecycle.
- ƒ **get_all_providers** (`Function`)
- 📝 Returns all configured LLM providers.
- ƒ **get_provider** (`Function`)
- 📝 Returns a single LLM provider by ID.
- ƒ **create_provider** (`Function`)
- 📝 Creates a new LLM provider with encrypted API key.
- ƒ **update_provider** (`Function`)
- 📝 Updates an existing LLM provider.
- ƒ **delete_provider** (`Function`)
- 📝 Deletes an LLM provider.
- ƒ **get_decrypted_api_key** (`Function`)
- 📝 Returns the decrypted API key for a provider.
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **encrypt** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **decrypt** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.src.services.auth_service** (`Module`)
- 📝 Orchestrates authentication business logic.
- 🏗️ Layer: Service
@@ -1814,6 +1927,72 @@
- 📝 Executes the dashboard migration logic.
- 📦 **MigrationPlugin.execute** (`Action`)
- 📝 Execute the migration logic with proper task logging.
- ƒ **schedule_dashboard_validation** (`Function`)
- 📝 Schedules a recurring dashboard validation task.
- 📦 **scheduler** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for backend/src/plugins/llm_analysis/scheduler.py
- 🏗️ Layer: Unknown
- ƒ **job_func** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_parse_cron** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- **LLMProviderType** (`Class`)
- 📝 Enum for supported LLM providers.
- **LLMProviderConfig** (`Class`)
- 📝 Configuration for an LLM provider.
- **ValidationStatus** (`Class`)
- 📝 Enum for dashboard validation status.
- **DetectedIssue** (`Class`)
- 📝 Model for a single issue detected during validation.
- **ValidationResult** (`Class`)
- 📝 Model for dashboard validation result.
- 📦 **backend.src.plugins.llm_analysis.plugin** (`Module`)
- 📝 Implements DashboardValidationPlugin and DocumentationPlugin.
- 🏗️ Layer: Domain
- **DashboardValidationPlugin** (`Class`)
- 📝 Plugin for automated dashboard health analysis using LLMs.
- **DocumentationPlugin** (`Class`)
- 📝 Plugin for automated dataset documentation using LLMs.
- ƒ **id** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **name** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **description** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **version** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **get_schema** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **execute** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **id** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **name** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **description** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **version** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **get_schema** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **execute** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.src.plugins.llm_analysis.service** (`Module`)
- 📝 Services for LLM interaction and dashboard screenshots.
- 🏗️ Layer: Domain
- 🔗 DEPENDS_ON -> `playwright`
- 🔗 DEPENDS_ON -> `openai`
- 🔗 DEPENDS_ON -> `tenacity`
- **ScreenshotService** (`Class`)
- 📝 Handles capturing screenshots of Superset dashboards.
- ƒ **capture_dashboard** (`Function`)
- 📝 Captures a screenshot of a dashboard using Playwright.
- **LLMClient** (`Class`)
- 📝 Wrapper for LLM provider APIs.
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **StoragePlugin** (`Module`)
- 📝 Provides core filesystem operations for managing backups and repositories.
- 🏗️ Layer: App
@@ -1854,6 +2033,15 @@
- 📝 Deletes a file or directory from the specified category and path.
- ƒ **get_file_path** (`Function`)
- 📝 Returns the absolute path of a file for download.
- **GitLLMExtension** (`Class`)
- 📝 Provides LLM capabilities to the Git plugin.
- ƒ **suggest_commit_message** (`Function`)
- 📝 Generates a suggested commit message based on a diff and history.
- 📦 **llm_extension** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for backend/src/plugins/git/llm_extension.py
- 🏗️ Layer: Unknown
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_environment_model** (`Function`)
- 📝 Tests that Environment model correctly stores values.
- ƒ **test_belief_scope_logs_entry_action_exit** (`Function`)