tui rework

This commit is contained in:
2026-03-09 14:18:34 +03:00
parent 309dfdba86
commit 4f74bb8afb
8 changed files with 5497 additions and 1520 deletions

View File

@@ -2,12 +2,12 @@
> High-level module structure for AI Context. Generated automatically.
**Generated:** 2026-03-06T15:13:36.187520
**Generated:** 2026-03-09T13:33:22.105511
## Summary
- **Total Modules:** 90
- **Total Entities:** 2508
- **Total Modules:** 93
- **Total Entities:** 2649
## Module Hierarchy
@@ -54,9 +54,9 @@
### 📁 `routes/`
- 🏗️ **Layers:** API, UI (API)
- 📊 **Tiers:** CRITICAL: 12, STANDARD: 240, TRIVIAL: 8
- 📊 **Tiers:** CRITICAL: 12, STANDARD: 254, TRIVIAL: 8
- 📄 **Files:** 19
- 📦 **Entities:** 260
- 📦 **Entities:** 274
**Key Entities:**
@@ -92,9 +92,9 @@
### 📁 `__tests__/`
- 🏗️ **Layers:** API, Domain, Domain (Tests), UI (API Tests), Unknown
- 📊 **Tiers:** STANDARD: 81, TRIVIAL: 134
- 📄 **Files:** 13
- 📦 **Entities:** 215
- 📊 **Tiers:** STANDARD: 88, TRIVIAL: 187
- 📄 **Files:** 14
- 📦 **Entities:** 275
**Key Entities:**
@@ -126,9 +126,9 @@
### 📁 `core/`
- 🏗️ **Layers:** Core
- 📊 **Tiers:** CRITICAL: 45, STANDARD: 94, TRIVIAL: 8
- 📊 **Tiers:** CRITICAL: 47, STANDARD: 94, TRIVIAL: 8
- 📄 **Files:** 11
- 📦 **Entities:** 147
- 📦 **Entities:** 149
**Key Entities:**
@@ -509,9 +509,9 @@
### 📁 `schemas/`
- 🏗️ **Layers:** API
- 📊 **Tiers:** CRITICAL: 10, STANDARD: 7, TRIVIAL: 3
- 📊 **Tiers:** CRITICAL: 10, STANDARD: 9, TRIVIAL: 3
- 📄 **Files:** 2
- 📦 **Entities:** 20
- 📦 **Entities:** 22
**Key Entities:**
@@ -521,20 +521,20 @@
- Represents an AD Group to Role mapping in API responses.
- **PermissionSchema** (Class) `[TRIVIAL]`
- Represents a permission in API responses.
- **ProfilePermissionState** (Class)
- Represents one permission badge state for profile read-only ...
- **ProfilePreference** (Class)
- Represents persisted profile preference for a single authent...
- **ProfilePreferenceResponse** (Class)
- Response envelope for profile preference read/update endpoin...
- **ProfilePreferenceUpdateRequest** (Class)
- Request payload for updating current user's dashboard filter...
- Request payload for updating current user's profile settings...
- **ProfileSecuritySummary** (Class)
- Read-only security and access snapshot for current user.
- **RoleCreate** (Class) `[CRITICAL]`
- Schema for creating a new role.
- **RoleSchema** (Class) `[CRITICAL]`
- Represents a role in API responses.
- **RoleUpdate** (Class) `[CRITICAL]`
- Schema for updating an existing role.
- **SupersetAccountCandidate** (Class)
- Canonical account candidate projected from Superset users pa...
**Dependencies:**
@@ -543,9 +543,9 @@
### 📁 `scripts/`
- 🏗️ **Layers:** Scripts, UI, Unknown
- 📊 **Tiers:** CRITICAL: 2, STANDARD: 27, TRIVIAL: 14
- 📊 **Tiers:** CRITICAL: 2, STANDARD: 27, TRIVIAL: 17
- 📄 **Files:** 7
- 📦 **Entities:** 43
- 📦 **Entities:** 46
**Key Entities:**
@@ -574,9 +574,9 @@
### 📁 `services/`
- 🏗️ **Layers:** Core, Domain, Service
- 📊 **Tiers:** CRITICAL: 9, STANDARD: 104, TRIVIAL: 7
- 📊 **Tiers:** CRITICAL: 9, STANDARD: 118, TRIVIAL: 15
- 📄 **Files:** 9
- 📦 **Entities:** 120
- 📦 **Entities:** 142
**Key Entities:**
@@ -773,9 +773,9 @@
### 📁 `core/`
- 🏗️ **Layers:** Domain, Unknown
- 📊 **Tiers:** STANDARD: 6, TRIVIAL: 45
- 📊 **Tiers:** STANDARD: 6, TRIVIAL: 46
- 📄 **Files:** 4
- 📦 **Entities:** 51
- 📦 **Entities:** 52
**Key Entities:**
@@ -870,10 +870,10 @@
### 📁 `git/`
- 🏗️ **Layers:** Component
- 📊 **Tiers:** STANDARD: 46
- 🏗️ **Layers:** Component, Unknown
- 📊 **Tiers:** STANDARD: 47, TRIVIAL: 12
- 📄 **Files:** 6
- 📦 **Entities:** 46
- 📦 **Entities:** 59
**Key Entities:**
@@ -889,6 +889,20 @@
- Modal for deploying a dashboard to a target environment.
- 🧩 **GitManager** (Component)
- Центральный UI управления Git с фокусом на рабочий поток ана...
- 📦 **GitManager** (Module) `[TRIVIAL]`
- Auto-generated module for frontend/src/components/git/GitMan...
### 📁 `__tests__/`
- 🏗️ **Layers:** UI Tests
- 📊 **Tiers:** STANDARD: 1
- 📄 **Files:** 1
- 📦 **Entities:** 1
**Key Entities:**
- 📦 **frontend.src.components.git.__tests__.git_manager_unfinished_merge_integration** (Module)
- Protect unresolved-merge dialog contract in GitManager pull ...
### 📁 `llm/`
@@ -1090,9 +1104,9 @@
### 📁 `layout/`
- 🏗️ **Layers:** UI, Unknown
- 📊 **Tiers:** STANDARD: 11, TRIVIAL: 47
- 📊 **Tiers:** STANDARD: 11, TRIVIAL: 48
- 📄 **Files:** 5
- 📦 **Entities:** 58
- 📦 **Entities:** 59
**Key Entities:**
@@ -1221,9 +1235,9 @@
### 📁 `stores/`
- 🏗️ **Layers:** UI, UI-State, Unknown
- 📊 **Tiers:** CRITICAL: 1, STANDARD: 8, TRIVIAL: 21
- 📊 **Tiers:** CRITICAL: 1, STANDARD: 8, TRIVIAL: 25
- 📄 **Files:** 5
- 📦 **Entities:** 30
- 📦 **Entities:** 34
**Key Entities:**
@@ -1339,13 +1353,15 @@
### 📁 `routes/`
- 🏗️ **Layers:** Infra, UI
- 📊 **Tiers:** CRITICAL: 1, STANDARD: 3, TRIVIAL: 1
- 🏗️ **Layers:** Infra, UI, Unknown
- 📊 **Tiers:** CRITICAL: 1, STANDARD: 3, TRIVIAL: 5
- 📄 **Files:** 5
- 📦 **Entities:** 5
- 📦 **Entities:** 9
**Key Entities:**
- 📦 **+page** (Module) `[TRIVIAL]`
- Auto-generated module for frontend/src/routes/+page.svelte
- 📦 **RootLayoutConfig** (Module) `[TRIVIAL]`
- Root layout configuration (SPA mode)
- 📦 **layout** (Module)
@@ -1513,9 +1529,9 @@
### 📁 `profile/`
- 🏗️ **Layers:** Unknown
- 📊 **Tiers:** TRIVIAL: 9
- 📊 **Tiers:** TRIVIAL: 16
- 📄 **Files:** 1
- 📦 **Entities:** 9
- 📦 **Entities:** 16
**Key Entities:**
@@ -1600,15 +1616,26 @@
### 📁 `git/`
- 🏗️ **Layers:** Page
- 📊 **Tiers:** STANDARD: 8
- 📊 **Tiers:** STANDARD: 10
- 📄 **Files:** 1
- 📦 **Entities:** 8
- 📦 **Entities:** 10
**Key Entities:**
- 🧩 **GitSettingsPage** (Component)
- Manage Git server configurations for dashboard versioning.
### 📁 `__tests__/`
- 📊 **Tiers:** STANDARD: 1
- 📄 **Files:** 1
- 📦 **Entities:** 1
**Key Entities:**
- 📦 **frontend.src.routes.settings.git.__tests__.git_settings_page_ux_test** (Module)
- Test UX states and transitions for the Git Settings page
### 📁 `storage/`
- 🏗️ **Layers:** Page
@@ -1678,6 +1705,17 @@
- 🔗 DEPENDS_ON -> frontend.src.lib.api
### 📁 `__tests__/`
- 📊 **Tiers:** STANDARD: 1
- 📄 **Files:** 1
- 📦 **Entities:** 1
**Key Entities:**
- 📦 **frontend.src.services.__tests__.gitService_test** (Module)
- API client tests ensuring correct endpoints are called per c...
### 📁 `types/`
- 🏗️ **Layers:** Domain
@@ -1693,9 +1731,9 @@
### 📁 `root/`
- 🏗️ **Layers:** DevOps/Tooling, Unknown
- 📊 **Tiers:** CRITICAL: 11, STANDARD: 17, TRIVIAL: 9
- 📄 **Files:** 2
- 📦 **Entities:** 37
- 📊 **Tiers:** CRITICAL: 11, STANDARD: 17, TRIVIAL: 12
- 📄 **Files:** 3
- 📦 **Entities:** 40
**Key Entities:**
@@ -1713,6 +1751,8 @@
- Auto-generated module for check_test_data.py
- 📦 **generate_semantic_map** (Module)
- Scans the codebase to generate a Semantic Map, Module Map, a...
- 📦 **test_pat_retrieve** (Module) `[TRIVIAL]`
- Auto-generated module for test_pat_retrieve.py
## Cross-Module Dependencies
@@ -1869,6 +1909,7 @@ graph TD
scripts-->|TESTS|backend
__tests__-->|VERIFIES|components
__tests__-->|VERIFIES|components
__tests__-->|VERIFIES|components
__tests__-->|TESTS|lib
__tests__-->|VERIFIES|lib
__tests__-->|TESTS|lib

View File

@@ -84,6 +84,13 @@
- 📝 Flattens entity tree for easier grouping.
- ƒ **to_dict** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **test_pat_retrieve** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for test_pat_retrieve.py
- 🏗️ Layer: Unknown
- ƒ **run** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **mock_test** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **DashboardTypes** (`Module`) `[TRIVIAL]`
- 📝 TypeScript interfaces for Dashboard entities
- 🏗️ Layer: Domain
@@ -207,8 +214,16 @@
- 📦 **taskDrawer** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/lib/stores/taskDrawer.js
- 🏗️ Layer: Unknown
- ƒ **readAutoOpenTaskDrawerPreference** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **openDrawerForTask** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **setTaskDrawerAutoOpenPreference** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **getTaskDrawerAutoOpenPreference** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **openDrawerForTaskIfPreferred** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **openDrawer** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **closeDrawer** (`Function`) `[TRIVIAL]`
@@ -570,6 +585,8 @@
- 📝 Auto-detected function (orphan)
- ƒ **handleAssistantClick** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **hydrateTaskDrawerPreference** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleSearchFocus** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **clearSearchState** (`Function`) `[TRIVIAL]`
@@ -692,9 +709,18 @@
- 📝 Root layout configuration (SPA mode)
- 🏗️ Layer: Infra
- 📦 **HomePage** (`Page`) `[CRITICAL]`
- 📝 Redirect to Dashboard Hub as per UX requirements
- 📝 Redirect to preferred start page from profile settings with safe dashboards fallback.
- 🏗️ Layer: UI
- 🔒 Invariant: Always redirects to /dashboards
- 🔒 Invariant: Redirect target resolves to one of /dashboards, /datasets, /reports.
- 📦 **+page** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/routes/+page.svelte
- 🏗️ Layer: Unknown
- ƒ **normalizeStartPage** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **resolveStartPagePath** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **redirectToStartPage** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **load** (`Function`)
- 📝 Loads initial plugin data for the dashboard.
- 📦 **layout** (`Module`)
@@ -1176,16 +1202,30 @@
- 📦 **+page** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/routes/profile/+page.svelte
- 🏗️ Layer: Unknown
- ƒ **createSecuritySummaryDefault** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **normalizeStartPage** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **normalizeDensity** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **parseValidationErrorsFromError** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **setSavedSnapshot** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **syncLocalUiPreferenceCaches** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **applyPreferenceResponse** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **loadPreference** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **loadLookupCandidates** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleSelectCandidate** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleGitTokenInput** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleClearGitToken** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleEnvironmentChange** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleSave** (`Function`) `[TRIVIAL]`
@@ -1306,6 +1346,10 @@
- 📝 Tests connection to a git server with current form data.
- ƒ **handleSave** (`Function`)
- 📝 Saves a new git configuration.
- ƒ **handleEdit** (`Function`)
- 📝 Populates the form with an existing config to edit.
- ƒ **resetForm** (`Function`)
- 📝 Resets the configuration form.
- ƒ **handleDelete** (`Function`)
- 📝 Deletes a git configuration by ID.
- ƒ **loadGiteaRepos** (`Function`)
@@ -1314,6 +1358,8 @@
- 📝 Creates new repository on selected Gitea server.
- ƒ **handleDeleteGiteaRepo** (`Function`)
- 📝 Deletes repository from selected Gitea server.
- 📦 **frontend.src.routes.settings.git.__tests__.git_settings_page_ux_test** (`Module`)
- 📝 Test UX states and transitions for the Git Settings page
- 🧩 **GitDashboardPage** (`Component`)
- 📝 Dashboard management page for Git integration.
- 🏗️ Layer: Page
@@ -1429,6 +1475,8 @@
- 📝 Returns the URL for downloading a file.
- ƒ **downloadFile** (`Function`)
- 📝 Downloads a file using authenticated fetch and saves it in browser.
- 📦 **frontend.src.services.__tests__.gitService_test** (`Module`)
- 📝 API client tests ensuring correct endpoints are called per contract
- 🧩 **DashboardGrid** (`Component`)
- 📝 Displays a grid of dashboards with selection and pagination.
- 🏗️ Layer: Component
@@ -1792,9 +1840,9 @@
- 🏗️ Layer: Component
- 🔒 Invariant: Cannot deploy without a selected environment.
- ⚡ Events: deploy
- ➡️ WRITES_TO `bindable`
- ➡️ WRITES_TO `props`
- ➡️ WRITES_TO `state`
- ➡️ WRITES_TO `derived`
- 📦 **loadStatus** (`Watcher`)
- ƒ **normalizeEnvStage** (`Function`)
- 📝 Normalize environment stage with legacy production fallback.
@@ -1809,6 +1857,7 @@
- 🏗️ Layer: Component
- 🔒 Invariant: User must resolve all conflicts before saving.
- ⚡ Events: resolve
- ➡️ WRITES_TO `bindable`
- ➡️ WRITES_TO `props`
- ➡️ WRITES_TO `state`
- ƒ **resolve** (`Function`)
@@ -1832,9 +1881,9 @@
- 📝 UI для выбора и создания веток Git.
- 🏗️ Layer: Component
- ⚡ Events: change
- ➡️ WRITES_TO `bindable`
- ➡️ WRITES_TO `props`
- ➡️ WRITES_TO `state`
- ⬅️ READS_FROM `t`
- ƒ **onMount** (`Function`)
- 📝 Load branches when component is mounted.
- ƒ **loadBranches** (`Function`)
@@ -1887,6 +1936,8 @@
- 📝 Resolve default git config for current session.
- ƒ **resolvePushProviderLabel** (`Function`)
- 📝 Resolve lower-case provider label for auto-push checkbox.
- ƒ **extractHttpHost** (`Function`)
- 📝 Extract comparable host[:port] from URL string.
- ƒ **buildSuggestedRepoName** (`Function`)
- 📝 Build deterministic repository name from dashboard title/id.
- ƒ **handleCreateRemoteRepo** (`Function`)
@@ -1897,6 +1948,34 @@
- 📝 Close git manager modal.
- ƒ **handleBackdropClick** (`Function`)
- 📝 Close modal on backdrop click.
- 📦 **GitManager** (`Module`) `[TRIVIAL]`
- 📝 Auto-generated module for frontend/src/components/git/GitManager.svelte
- 🏗️ Layer: Unknown
- ƒ **tryParseJsonObject** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **extractUnfinishedMergeContext** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **openUnfinishedMergeDialogFromError** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **loadMergeRecoveryState** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **closeUnfinishedMergeDialog** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleOpenConflictResolver** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleResolveConflicts** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleAbortUnfinishedMerge** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleContinueUnfinishedMerge** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **getUnfinishedMergeCommandsText** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **handleCopyUnfinishedMergeCommands** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **frontend.src.components.git.__tests__.git_manager_unfinished_merge_integration** (`Module`)
- 📝 Protect unresolved-merge dialog contract in GitManager pull flow.
- 🏗️ Layer: UI Tests
- 🧩 **DocPreview** (`Component`)
- 📝 UI component for previewing generated dataset documentation before saving.
- 🏗️ Layer: UI
@@ -2039,7 +2118,13 @@
- 📝 Execute compliance orchestrator run and update UI state.
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- ƒ **_build_repository** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_bootstrap_demo_repository** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_bootstrap_real_repository** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_resolve_candidate_id** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **draw_header** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
@@ -2132,14 +2217,18 @@
- **User** (`Class`) `[CRITICAL]`
- 📝 Schema for user data in API responses.
- 📦 **backend.src.schemas.profile** (`Module`)
- 📝 Defines API schemas for profile preference persistence and Superset account lookup flows.
- 📝 Defines API schemas for profile preference persistence, security read-only snapshot, and Superset account lookup.
- 🏗️ Layer: API
- 🔒 Invariant: Schema shapes stay stable for profile UI states and dashboards filter metadata.
- 🔒 Invariant: Schema shapes stay stable for profile UI states and backend preference contracts.
- 🔗 DEPENDS_ON -> `pydantic`
- **ProfilePermissionState** (`Class`)
- 📝 Represents one permission badge state for profile read-only security view.
- **ProfileSecuritySummary** (`Class`)
- 📝 Read-only security and access snapshot for current user.
- **ProfilePreference** (`Class`)
- 📝 Represents persisted profile preference for a single authenticated user.
- **ProfilePreferenceUpdateRequest** (`Class`)
- 📝 Request payload for updating current user's dashboard filter preference.
- 📝 Request payload for updating current user's profile settings.
- **ProfilePreferenceResponse** (`Class`)
- 📝 Response envelope for profile preference read/update endpoints.
- **SupersetAccountLookupRequest** (`Class`)
@@ -2348,6 +2437,10 @@
- 📝 A session factory for the tasks execution database.
- **AuthSessionLocal** (`Class`) `[TRIVIAL]`
- 📝 A session factory for the authentication database.
- ƒ **_ensure_user_dashboard_preferences_columns** (`Function`) `[CRITICAL]`
- 📝 Applies additive schema upgrades for user_dashboard_preferences table.
- ƒ **_ensure_git_server_configs_columns** (`Function`) `[CRITICAL]`
- 📝 Applies additive schema upgrades for git_server_configs table.
- ƒ **init_db** (`Function`) `[CRITICAL]`
- 📝 Initializes the database by creating all tables.
- ƒ **get_db** (`Function`) `[CRITICAL]`
@@ -3075,10 +3168,18 @@
- 📝 Resolve dashboard ID from slug-or-id reference for Git routes.
- ƒ **_resolve_repo_key_from_ref** (`Function`)
- 📝 Resolve repository folder key with slug-first strategy and deterministic fallback.
- ƒ **_sanitize_optional_identity_value** (`Function`)
- 📝 Normalize optional identity value into trimmed string or None.
- ƒ **_resolve_current_user_git_identity** (`Function`)
- 📝 Resolve configured Git username/email from current user's profile preferences.
- ƒ **_apply_git_identity_from_profile** (`Function`)
- 📝 Apply user-scoped Git identity to repository-local config before write/pull operations.
- ƒ **get_git_configs** (`Function`)
- 📝 List all configured Git servers.
- ƒ **create_git_config** (`Function`)
- 📝 Register a new Git server configuration.
- ƒ **update_git_config** (`Function`)
- 📝 Update an existing Git server configuration.
- ƒ **delete_git_config** (`Function`)
- 📝 Remove a Git server configuration.
- ƒ **test_git_config** (`Function`)
@@ -3109,6 +3210,16 @@
- 📝 Push local commits to the remote repository.
- ƒ **pull_changes** (`Function`)
- 📝 Pull changes from the remote repository.
- ƒ **get_merge_status** (`Function`)
- 📝 Return unfinished-merge status for repository (web-only recovery support).
- ƒ **get_merge_conflicts** (`Function`)
- 📝 Return conflicted files with mine/theirs previews for web conflict resolver.
- ƒ **resolve_merge_conflicts** (`Function`)
- 📝 Apply mine/theirs/manual conflict resolutions from WebUI and stage files.
- ƒ **abort_merge** (`Function`)
- 📝 Abort unfinished merge from WebUI flow.
- ƒ **continue_merge** (`Function`)
- 📝 Finalize unfinished merge from WebUI flow.
- ƒ **sync_dashboard** (`Function`)
- 📝 Sync dashboard state from Superset to Git using the GitPlugin.
- ƒ **promote_dashboard** (`Function`)
@@ -3279,6 +3390,8 @@
- 🔗 DEPENDS_ON -> `backend.src.models.git`
- **GitServerConfigBase** (`Class`) `[TRIVIAL]`
- 📝 Base schema for Git server configuration attributes.
- **GitServerConfigUpdate** (`Class`)
- 📝 Schema for updating an existing Git server configuration.
- **GitServerConfigCreate** (`Class`)
- 📝 Schema for creating a new Git server configuration.
- **GitServerConfigSchema** (`Class`)
@@ -3297,6 +3410,14 @@
- 📝 Schema for staging and committing changes.
- **ConflictResolution** (`Class`)
- 📝 Schema for resolving merge conflicts.
- **MergeStatusSchema** (`Class`)
- 📝 Schema representing unfinished merge status for repository.
- **MergeConflictFileSchema** (`Class`)
- 📝 Schema describing one conflicted file with optional side snapshots.
- **MergeResolveRequest** (`Class`)
- 📝 Request schema for resolving one or multiple merge conflicts.
- **MergeContinueRequest** (`Class`)
- 📝 Request schema for finishing merge with optional explicit commit message.
- **DeploymentEnvironmentSchema** (`Class`)
- 📝 Schema for representing a target deployment environment.
- **DeployRequest** (`Class`)
@@ -3636,6 +3757,18 @@
- 📝 Ensure batch endpoint marks failed items as ERROR without failing entire request.
- ƒ **test_get_repository_status_batch_deduplicates_and_truncates_ids** (`Function`)
- 📝 Ensure batch endpoint protects server from oversized payloads.
- ƒ **test_commit_changes_applies_profile_identity_before_commit** (`Function`)
- 📝 Ensure commit route configures repository identity from profile preferences before commit call.
- ƒ **test_pull_changes_applies_profile_identity_before_pull** (`Function`)
- 📝 Ensure pull route configures repository identity from profile preferences before pull call.
- ƒ **test_get_merge_status_returns_service_payload** (`Function`)
- 📝 Ensure merge status route returns service payload as-is.
- ƒ **test_resolve_merge_conflicts_passes_resolution_items_to_service** (`Function`)
- 📝 Ensure merge resolve route forwards parsed resolutions to service.
- ƒ **test_abort_merge_calls_service_and_returns_result** (`Function`)
- 📝 Ensure abort route delegates to service.
- ƒ **test_continue_merge_passes_message_and_returns_commit** (`Function`)
- 📝 Ensure continue route passes commit message to service.
- ƒ **_get_repo_path** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **get_status** (`Function`) `[TRIVIAL]`
@@ -3662,6 +3795,40 @@
- 📝 Auto-detected function (orphan)
- ƒ **get_status** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **configure_identity** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **commit_changes** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **filter** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **first** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **query** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **configure_identity** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **pull_changes** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **filter** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **first** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **query** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **get_merge_status** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **resolve_merge_conflicts** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **dict** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **abort_merge** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **continue_merge** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.tests.test_reports_openapi_conformance** (`Module`)
- 📝 Validate implemented reports payload shape against OpenAPI-required top-level contract fields.
- 🏗️ Layer: Domain (Tests)
@@ -3858,6 +4025,80 @@
- 📝 Auto-detected function (orphan)
- ƒ **rollback** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.src.api.routes.__tests__.test_git_api** (`Module`)
- 📝 API tests for Git configurations and repository operations.
- ƒ **__init__** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **query** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **filter** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **first** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **all** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **add** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **delete** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **commit** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **refresh** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_get_git_configs_masks_pat** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_create_git_config_persists_config** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_update_git_config_modifies_record** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **query** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **filter** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **first** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **commit** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **refresh** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_update_git_config_raises_404_if_not_found** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_delete_git_config_removes_record** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **query** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **filter** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **first** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **delete** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **commit** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_test_git_config_validates_connection_successfully** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_connection** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_test_git_config_fails_validation** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_connection** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_list_gitea_repositories_returns_payload** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **list_gitea_repositories** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_list_gitea_repositories_rejects_non_gitea** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_create_remote_repository_creates_provider_repo** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **create_gitlab_repository** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_init_repository_initializes_and_saves_binding** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **init_repo** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_get_repo_path** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.src.api.routes.__tests__.test_assistant_api** (`Module`)
- 📝 Validate assistant API endpoint logic via direct async handler invocation.
- 🏗️ Layer: UI (API Tests)
@@ -4201,9 +4442,9 @@
- 📝 Maps an Active Directory group to a local System Role.
- 🔗 DEPENDS_ON -> `Role`
- 📦 **backend.src.models.profile** (`Module`)
- 📝 Defines persistent per-user dashboard filter preferences.
- 📝 Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
- 🏗️ Layer: Domain
- 🔒 Invariant: Exactly one preference row exists per user_id.
- 🔒 Invariant: Sensitive Git token is stored encrypted and never returned in plaintext.
- 🔗 DEPENDS_ON -> `backend.src.models.auth`
- **UserDashboardPreference** (`Class`)
- 📝 Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
@@ -4318,6 +4559,24 @@
- 📝 Query Superset users in selected environment and project canonical account candidates.
- ƒ **matches_dashboard_actor** (`Function`)
- 📝 Apply trim+case-insensitive actor match across owners OR modified_by.
- ƒ **_build_security_summary** (`Function`)
- 📝 Build read-only security snapshot with role and permission badges.
- ƒ **_collect_user_permission_pairs** (`Function`)
- 📝 Collect effective permission tuples from current user's roles.
- ƒ **_format_permission_key** (`Function`)
- 📝 Convert normalized permission pair to compact UI key.
- ƒ **_to_preference_payload** (`Function`)
- 📝 Map ORM preference row to API DTO with token metadata.
- ƒ **_mask_secret_value** (`Function`)
- 📝 Build a safe display value for sensitive secrets.
- ƒ **_sanitize_text** (`Function`)
- 📝 Normalize optional text into trimmed form or None.
- ƒ **_sanitize_secret** (`Function`)
- 📝 Normalize secret input into trimmed form or None.
- ƒ **_normalize_start_page** (`Function`)
- 📝 Normalize supported start page aliases to canonical values.
- ƒ **_normalize_density** (`Function`)
- 📝 Normalize supported density aliases to canonical values.
- ƒ **_resolve_environment** (`Function`)
- 📝 Resolve environment model from configured environments by id.
- ƒ **_get_preference_row** (`Function`)
@@ -4504,6 +4763,8 @@
- 📝 Remove local repository and DB binding for a dashboard.
- ƒ **get_repo** (`Function`)
- 📝 Get Repo object for a dashboard.
- ƒ **configure_identity** (`Function`)
- 📝 Configure repository-local Git committer identity for user-scoped operations.
- ƒ **list_branches** (`Function`)
- 📝 List all branches for a dashboard's repository.
- ƒ **create_branch** (`Function`)
@@ -4512,6 +4773,14 @@
- 📝 Switch to a specific branch.
- ƒ **commit_changes** (`Function`)
- 📝 Stage and commit changes.
- ƒ **_extract_http_host** (`Function`)
- 📝 Extract normalized host[:port] from HTTP(S) URL.
- ƒ **_strip_url_credentials** (`Function`)
- 📝 Remove credentials from URL while preserving scheme/host/path.
- ƒ **_replace_host_in_url** (`Function`)
- 📝 Replace source URL host with host from configured server URL.
- ƒ **_align_origin_host_with_config** (`Function`)
- 📝 Auto-align local origin host to configured Git server host when they drift.
- ƒ **push_changes** (`Function`)
- 📝 Push local commits to remote.
- ƒ **pull_changes** (`Function`)
@@ -4558,6 +4827,22 @@
- 📝 Create pull request in GitHub or GitHub Enterprise.
- ƒ **create_gitlab_merge_request** (`Function`)
- 📝 Create merge request in GitLab.
- ƒ **_read_blob_text** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_get_unmerged_file_paths** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **_build_unfinished_merge_payload** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **get_merge_status** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **get_merge_conflicts** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **resolve_merge_conflicts** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **abort_merge** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **continue_merge** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.src.services.mapping_service** (`Module`)
- 📝 Orchestrates database fetching and fuzzy matching suggestions.
- 🏗️ Layer: Service
@@ -5757,6 +6042,8 @@
- 📝 Auto-detected function (orphan)
- ƒ **remote** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- ƒ **test_git_service_configure_identity_updates_repo_local_config** (`Function`) `[TRIVIAL]`
- 📝 Auto-detected function (orphan)
- 📦 **backend.tests.core.test_migration_engine** (`Module`)
- 📝 Unit tests for MigrationEngine's cross-filter patching algorithms.
- 🏗️ Layer: Domain

14
artifacts.json Normal file
View File

@@ -0,0 +1,14 @@
[
{
"path": "src/main.py",
"category": "core"
},
{
"path": "src/api/routes/clean_release.py",
"category": "core"
},
{
"path": "docs/installation.md",
"category": "docs"
}
]

View File

@@ -8,6 +8,7 @@
# @INVARIANT: TUI must provide a headless fallback for non-TTY environments.
import curses
import json
import os
import sys
import time
@@ -32,51 +33,14 @@ from backend.src.models.clean_release import (
ReleaseCandidate,
ResourceSourceEntry,
ResourceSourceRegistry,
RegistryStatus,
ReleaseCandidateStatus,
)
from backend.src.services.clean_release.compliance_orchestrator import CleanComplianceOrchestrator
from backend.src.services.clean_release.preparation_service import prepare_candidate
from backend.src.services.clean_release.repository import CleanReleaseRepository
from backend.src.services.clean_release.manifest_builder import build_distribution_manifest
class FakeRepository(CleanReleaseRepository):
"""
In-memory stub for the TUI to satisfy Orchestrator without a real DB.
"""
def __init__(self):
super().__init__()
# Seed with demo data for F5 demonstration
now = datetime.now(timezone.utc)
self.save_policy(CleanProfilePolicy(
policy_id="POL-ENT-CLEAN",
policy_version="1",
profile=ProfileType.ENTERPRISE_CLEAN,
active=True,
internal_source_registry_ref="REG-1",
prohibited_artifact_categories=["test-data"],
effective_from=now
))
self.save_registry(ResourceSourceRegistry(
registry_id="REG-1",
name="Default Internal Registry",
entries=[ResourceSourceEntry(
source_id="S1",
host="internal-repo.company.com",
protocol="https",
purpose="artifactory"
)],
updated_at=now,
updated_by="system"
))
self.save_candidate(ReleaseCandidate(
candidate_id="2026.03.03-rc1",
version="1.0.0",
profile=ProfileType.ENTERPRISE_CLEAN,
source_snapshot_ref="v1.0.0-rc1",
created_at=now,
created_by="system"
))
# [DEF:CleanReleaseTUI:Class]
# @PURPOSE: Curses-based application for compliance monitoring.
# @UX_STATE: READY -> Waiting for operator to start checks (F5).
@@ -87,12 +51,15 @@ class FakeRepository(CleanReleaseRepository):
class CleanReleaseTUI:
def __init__(self, stdscr: curses.window):
self.stdscr = stdscr
self.repo = FakeRepository()
self.mode = os.getenv("CLEAN_TUI_MODE", "demo").strip().lower()
self.repo = self._build_repository(self.mode)
self.orchestrator = CleanComplianceOrchestrator(self.repo)
self.candidate_id = self._resolve_candidate_id()
self.status: Any = "READY"
self.checks_progress: List[Dict[str, Any]] = []
self.violations_list: List[ComplianceViolation] = []
self.report_id: Optional[str] = None
self.last_error: Optional[str] = None
curses.start_color()
curses.use_default_colors()
@@ -102,6 +69,124 @@ class CleanReleaseTUI:
curses.init_pair(4, curses.COLOR_YELLOW, -1) # RUNNING
curses.init_pair(5, curses.COLOR_CYAN, -1) # Text
def _build_repository(self, mode: str) -> CleanReleaseRepository:
repo = CleanReleaseRepository()
if mode == "demo":
self._bootstrap_demo_repository(repo)
self._bootstrap_real_repository(repo)
return repo
def _bootstrap_demo_repository(self, repository: CleanReleaseRepository) -> None:
now = datetime.now(timezone.utc)
repository.save_policy(
CleanProfilePolicy(
policy_id="POL-ENT-CLEAN",
policy_version="1",
profile=ProfileType.ENTERPRISE_CLEAN,
active=True,
internal_source_registry_ref="REG-1",
prohibited_artifact_categories=["test-data"],
effective_from=now,
)
)
repository.save_registry(
ResourceSourceRegistry(
registry_id="REG-1",
name="Default Internal Registry",
entries=[
ResourceSourceEntry(
source_id="S1",
host="internal-repo.company.com",
protocol="https",
purpose="artifactory",
)
],
updated_at=now,
updated_by="system",
)
)
repository.save_candidate(
ReleaseCandidate(
candidate_id="2026.03.03-rc1",
version="1.0.0",
profile=ProfileType.ENTERPRISE_CLEAN,
source_snapshot_ref="v1.0.0-rc1",
created_at=now,
created_by="system",
)
)
def _bootstrap_real_repository(self, repository: CleanReleaseRepository) -> None:
bootstrap_path = os.getenv("CLEAN_TUI_BOOTSTRAP_JSON", "").strip()
if not bootstrap_path:
return
with open(bootstrap_path, "r", encoding="utf-8") as bootstrap_file:
payload = json.load(bootstrap_file)
now = datetime.now(timezone.utc)
candidate = ReleaseCandidate(
candidate_id=payload.get("candidate_id", "candidate-1"),
version=payload.get("version", "1.0.0"),
profile=ProfileType.ENTERPRISE_CLEAN,
source_snapshot_ref=payload.get("source_snapshot_ref", "snapshot-ref"),
created_at=now,
created_by=payload.get("created_by", "operator"),
status=ReleaseCandidateStatus.DRAFT,
)
repository.save_candidate(candidate)
registry_id = payload.get("registry_id", "REG-1")
entries = [
ResourceSourceEntry(
source_id=f"S-{index + 1}",
host=host,
protocol="https",
purpose="bootstrap",
enabled=True,
)
for index, host in enumerate(payload.get("allowed_hosts", []))
if str(host).strip()
]
if entries:
repository.save_registry(
ResourceSourceRegistry(
registry_id=registry_id,
name=payload.get("registry_name", "Bootstrap Internal Registry"),
entries=entries,
updated_at=now,
updated_by=payload.get("created_by", "operator"),
status=RegistryStatus.ACTIVE,
)
)
if entries:
repository.save_policy(
CleanProfilePolicy(
policy_id=payload.get("policy_id", "POL-ENT-CLEAN"),
policy_version=payload.get("policy_version", "1"),
profile=ProfileType.ENTERPRISE_CLEAN,
active=True,
internal_source_registry_ref=registry_id,
prohibited_artifact_categories=payload.get(
"prohibited_artifact_categories",
["test-data", "demo", "load-test"],
),
required_system_categories=payload.get("required_system_categories", ["core"]),
effective_from=now,
)
)
def _resolve_candidate_id(self) -> str:
env_candidate = os.getenv("CLEAN_TUI_CANDIDATE_ID", "").strip()
if env_candidate:
return env_candidate
candidate_ids = list(self.repo.candidates.keys())
if candidate_ids:
return candidate_ids[0]
return ""
def draw_header(self, max_y: int, max_x: int):
header_text = " Enterprise Clean Release Validator (TUI) "
self.stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
@@ -109,8 +194,10 @@ class CleanReleaseTUI:
centered = header_text.center(max_x)
self.stdscr.addstr(0, 0, centered[:max_x])
self.stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
info_line_text = " │ Candidate: [2026.03.03-rc1] Profile: [enterprise-clean]".ljust(max_x)
candidate_text = self.candidate_id or "not-set"
profile_text = "enterprise-clean"
info_line_text = f" │ Candidate: [{candidate_text}] Profile: [{profile_text}] Mode: [{self.mode}]".ljust(max_x)
self.stdscr.addstr(2, 0, info_line_text[:max_x])
def draw_checks(self):
@@ -148,12 +235,17 @@ class CleanReleaseTUI:
def draw_sources(self):
self.stdscr.addstr(12, 3, "Allowed Internal Sources:", curses.A_BOLD)
reg = self.repo.get_registry("REG-1")
reg = None
policy = self.repo.get_active_policy()
if policy:
reg = self.repo.get_registry(policy.internal_source_registry_ref)
row = 13
if reg:
for entry in reg.entries:
self.stdscr.addstr(row, 3, f" - {entry.host}")
row += 1
else:
self.stdscr.addstr(row, 3, " - (none)")
def draw_status(self):
color = curses.color_pair(5)
@@ -173,6 +265,8 @@ class CleanReleaseTUI:
v_cat = str(v.category.value if hasattr(v.category, "value") else v.category)
msg_text = f"[{v_cat}] {v.remediation} (Loc: {v.location})"
self.stdscr.addstr(row + i, 5, msg_text[:70], curses.color_pair(3))
if self.last_error:
self.stdscr.addstr(27, 3, f"Error: {self.last_error}"[:100], curses.color_pair(3) | curses.A_BOLD)
def draw_footer(self, max_y: int, max_x: int):
footer_text = " F5 Run Check F7 Clear History F10 Exit ".center(max_x)
@@ -187,28 +281,60 @@ class CleanReleaseTUI:
self.report_id = None
self.violations_list = []
self.checks_progress = []
candidate = self.repo.get_candidate("2026.03.03-rc1")
self.last_error = None
candidate = self.repo.get_candidate(self.candidate_id) if self.candidate_id else None
policy = self.repo.get_active_policy()
if not candidate or not policy:
self.status = "FAILED"
self.last_error = "Candidate or active policy not found. Set CLEAN_TUI_CANDIDATE_ID and prepare repository data."
self.refresh_screen()
return
# Prepare a manifest with a deliberate violation for demo
artifacts = [
{"path": "src/main.py", "category": "core", "reason": "source code", "classification": "allowed"},
{"path": "test/data.csv", "category": "test-data", "reason": "test payload", "classification": "excluded-prohibited"},
]
manifest = build_distribution_manifest(
manifest_id=f"manifest-{candidate.candidate_id}",
candidate_id=candidate.candidate_id,
policy_id=policy.policy_id,
generated_by="operator",
artifacts=artifacts
)
self.repo.save_manifest(manifest)
if self.mode == "demo":
# Prepare a manifest with a deliberate violation for demonstration mode.
artifacts = [
{"path": "src/main.py", "category": "core", "reason": "source code", "classification": "allowed"},
{"path": "test/data.csv", "category": "test-data", "reason": "test payload", "classification": "excluded-prohibited"},
]
manifest = build_distribution_manifest(
manifest_id=f"manifest-{candidate.candidate_id}",
candidate_id=candidate.candidate_id,
policy_id=policy.policy_id,
generated_by="operator",
artifacts=artifacts
)
self.repo.save_manifest(manifest)
else:
manifest = self.repo.get_manifest(f"manifest-{candidate.candidate_id}")
if manifest is None:
artifacts_path = os.getenv("CLEAN_TUI_ARTIFACTS_JSON", "").strip()
if artifacts_path:
try:
with open(artifacts_path, "r", encoding="utf-8") as artifacts_file:
artifacts = json.load(artifacts_file)
if not isinstance(artifacts, list):
raise ValueError("Artifacts JSON must be a list")
prepare_candidate(
repository=self.repo,
candidate_id=candidate.candidate_id,
artifacts=artifacts,
sources=[],
operator_id="tui-operator",
)
manifest = self.repo.get_manifest(f"manifest-{candidate.candidate_id}")
except Exception as exc:
self.status = "FAILED"
self.last_error = f"Unable to prepare manifest from CLEAN_TUI_ARTIFACTS_JSON: {exc}"
self.refresh_screen()
return
if manifest is None:
self.status = "FAILED"
self.last_error = "Manifest not found. Prepare candidate first or provide CLEAN_TUI_ARTIFACTS_JSON."
self.refresh_screen()
return
# Init orchestrator sequence
check_run = self.orchestrator.start_check_run(candidate.candidate_id, policy.policy_id, "operator", "tui")
@@ -244,6 +370,7 @@ class CleanReleaseTUI:
self.report_id = None
self.violations_list = []
self.checks_progress = []
self.last_error = None
self.refresh_screen()
def refresh_screen(self):

17
bootstrap.json Normal file
View File

@@ -0,0 +1,17 @@
{
"candidate_id": "2026.03.03-rc1",
"version": "1.0.0",
"source_snapshot_ref": "v1.0.0-rc1",
"created_by": "operator",
"allowed_hosts": [
"internal-repo.company.com"
],
"prohibited_artifact_categories": [
"test-data",
"demo",
"load-test"
],
"required_system_categories": [
"core"
]
}

View File

@@ -295,7 +295,7 @@ export RETENTION_PERIOD_DAYS=90
```bash
cd /home/busya/dev/ss-tools
./backend/.venv/bin/python3 -m backend.src.scripts.clean_release_tui
./run_clean_tui.sh <candidate_id>
```
Ожидаемый flow:
@@ -306,6 +306,41 @@ cd /home/busya/dev/ss-tools
- `COMPLIANT` — кандидат готов к следующему этапу выпуска;
- `BLOCKED` — выпуск запрещён до устранения нарушений.
По умолчанию `run_clean_tui.sh` запускает TUI в `real` режиме (`CLEAN_TUI_MODE=real`) без инъекции демонстрационных нарушений.
### Переменные запуска `run_clean_tui.sh`
```bash
# Опционально: явный режим (real|demo), по умолчанию real
export CLEAN_TUI_MODE=real
# Опционально: bootstrap данных кандидата/политики/реестра
export CLEAN_TUI_BOOTSTRAP_JSON=/absolute/path/bootstrap.json
# Опционально: артефакты для подготовки manifest, если он еще не создан
export CLEAN_TUI_ARTIFACTS_JSON=/absolute/path/artifacts.json
# Запуск (candidate_id можно передать первым аргументом)
./run_clean_tui.sh 2026.03.03-rc1
# Явный демонстрационный режим
./run_clean_tui.sh --demo
```
Минимальный пример `bootstrap.json`:
```json
{
"candidate_id": "2026.03.03-rc1",
"version": "1.0.0",
"source_snapshot_ref": "v1.0.0-rc1",
"created_by": "operator",
"allowed_hosts": ["internal-repo.company.com"],
"prohibited_artifact_categories": ["test-data", "demo", "load-test"],
"required_system_categories": ["core"]
}
```
### Политика источников (internal-only)
Разрешены только хосты из внутреннего реестра компании, например:
@@ -494,4 +529,4 @@ curl -X POST http://localhost:8001/api/auth/login \
1. Проверьте раздел [Troubleshooting](#troubleshooting)
2. Посмотрите логи в Docker: `docker compose logs -f`
3. Откройте issue на GitHub с подробным описанием проблемы
4. Обратитесь в техническую поддержку
4. Обратитесь в техническую поддержку

View File

@@ -8,11 +8,22 @@ set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
echo "Starting Enterprise Clean Release Validator..."
echo "Starting Enterprise Clean Release Validator (real mode)..."
# Set up environment
export PYTHONPATH="$SCRIPT_DIR/backend"
export TERM="xterm-256color"
export CLEAN_TUI_MODE="real"
CANDIDATE_ID=""
if [ "${1:-}" = "--demo" ]; then
export CLEAN_TUI_MODE="demo"
shift
fi
if [ -n "${1:-}" ]; then
CANDIDATE_ID="$1"
export CLEAN_TUI_CANDIDATE_ID="$CANDIDATE_ID"
fi
# Run the TUI
./backend/.venv/bin/python3 -m backend.src.scripts.clean_release_tui

File diff suppressed because it is too large Load Diff