From 54e90b589b25a8d524d07af4ab40b3b28d140561 Mon Sep 17 00:00:00 2001 From: busya Date: Sun, 15 Mar 2026 22:14:05 +0300 Subject: [PATCH] chore(semantics): checkpoint orphan-reduction hub normalization batch --- backend/src/api/routes/dashboards.py | 10 +-- backend/src/api/routes/datasets.py | 8 +-- backend/src/core/async_superset_client.py | 12 ++-- backend/src/core/superset_client.py | 83 ++++++++++++----------- backend/src/services/git_service.py | 32 ++++----- backend/src/services/resource_service.py | 21 +++--- 6 files changed, 87 insertions(+), 79 deletions(-) diff --git a/backend/src/api/routes/dashboards.py b/backend/src/api/routes/dashboards.py index 481e5d92..aa85fdde 100644 --- a/backend/src/api/routes/dashboards.py +++ b/backend/src/api/routes/dashboards.py @@ -4,9 +4,9 @@ # @SEMANTICS: api, dashboards, resources, hub # @PURPOSE: API endpoints for the Dashboard Hub - listing dashboards with Git and task status # @LAYER: API -# @RELATION: DEPENDS_ON ->[backend.src.dependencies:Dependencies] -# @RELATION: DEPENDS_ON ->[backend.src.services.resource_service:ResourceService] -# @RELATION: DEPENDS_ON ->[backend.src.core.superset_client:SupersetClient] +# @RELATION: DEPENDS_ON ->[backend.src.dependencies] +# @RELATION: DEPENDS_ON ->[backend.src.services.resource_service.ResourceService] +# @RELATION: DEPENDS_ON ->[backend.src.core.superset_client.SupersetClient] # # @INVARIANT: All dashboard responses include git_status and last_task metadata # @@ -533,7 +533,7 @@ def _matches_dashboard_actor_aliases( # @PARAM: page (Optional[int]) - Page number (default: 1) # @PARAM: page_size (Optional[int]) - Items per page (default: 10, max: 100) # @RETURN: DashboardsResponse - List of dashboards with status metadata -# @RELATION: CALLS ->[ResourceService:get_dashboards_with_status] +# @RELATION: CALLS ->[get_dashboards_with_status] @router.get("", response_model=DashboardsResponse) async def get_dashboards( env_id: str, @@ -883,7 +883,7 @@ async def get_database_mappings( # @PURPOSE: Fetch detailed dashboard info with related charts and datasets # @PRE: env_id must be valid and dashboard ref (slug or id) must exist # @POST: Returns dashboard detail payload for overview page -# @RELATION: CALLS ->[AsyncSupersetClient:get_dashboard_detail_async] +# @RELATION: CALLS ->[backend.src.core.async_superset_client.AsyncSupersetClient.get_dashboard_detail_async] @router.get("/{dashboard_ref}", response_model=DashboardDetailResponse) async def get_dashboard_detail( dashboard_ref: str, diff --git a/backend/src/api/routes/datasets.py b/backend/src/api/routes/datasets.py index 4394a7d6..31c82804 100644 --- a/backend/src/api/routes/datasets.py +++ b/backend/src/api/routes/datasets.py @@ -5,8 +5,8 @@ # @PURPOSE: API endpoints for the Dataset Hub - listing datasets with mapping progress # @LAYER: API # @RELATION: DEPENDS_ON ->[backend.src.dependencies] -# @RELATION: DEPENDS_ON ->[backend.src.services.resource_service] -# @RELATION: DEPENDS_ON ->[backend.src.core.superset_client] +# @RELATION: DEPENDS_ON ->[backend.src.services.resource_service.ResourceService] +# @RELATION: DEPENDS_ON ->[backend.src.core.superset_client.SupersetClient] # # @INVARIANT: All dataset responses include last_task metadata @@ -121,7 +121,7 @@ class TaskResponse(BaseModel): # @PARAM: env_id (str) - The environment ID to fetch datasets from # @PARAM: search (Optional[str]) - Filter by table name # @RETURN: List[int] - List of dataset IDs -# @RELATION: CALLS ->[backend.src.services.resource_service.ResourceService:get_datasets_with_status] +# @RELATION: CALLS ->[get_datasets_with_status] @router.get("/ids") async def get_dataset_ids( env_id: str, @@ -178,7 +178,7 @@ async def get_dataset_ids( # @PARAM: page (Optional[int]) - Page number (default: 1) # @PARAM: page_size (Optional[int]) - Items per page (default: 10, max: 100) # @RETURN: DatasetsResponse - List of datasets with status metadata -# @RELATION: CALLS ->[backend.src.services.resource_service.ResourceService:get_datasets_with_status] +# @RELATION: CALLS ->[backend.src.services.resource_service.ResourceService.get_datasets_with_status] @router.get("", response_model=DatasetsResponse) async def get_datasets( env_id: str, diff --git a/backend/src/core/async_superset_client.py b/backend/src/core/async_superset_client.py index 39346b25..1c00e08b 100644 --- a/backend/src/core/async_superset_client.py +++ b/backend/src/core/async_superset_client.py @@ -25,14 +25,14 @@ from .utils.async_network import AsyncAPIClient # [/SECTION] -# [DEF:AsyncSupersetClient:Class] +# [DEF:backend.src.core.async_superset_client.AsyncSupersetClient:Class] # @TIER: STANDARD # @PURPOSE: Async sibling of SupersetClient for dashboard read paths. # @RELATION: [INHERITS] ->[backend.src.core.superset_client.SupersetClient] # @RELATION: [DEPENDS_ON] ->[backend.src.core.utils.async_network.AsyncAPIClient] # @RELATION: [CALLS] ->[backend.src.core.utils.async_network.AsyncAPIClient.request] class AsyncSupersetClient(SupersetClient): - # [DEF:__init__:Function] + # [DEF:backend.src.core.async_superset_client.AsyncSupersetClient.__init__:Function] # @TIER: STANDARD # @PURPOSE: Initialize async Superset client with AsyncAPIClient transport. # @PRE: env is valid Environment instance. @@ -52,18 +52,18 @@ class AsyncSupersetClient(SupersetClient): timeout=env.timeout, ) self.delete_before_reimport = False - # [/DEF:__init__:Function] + # [/DEF:backend.src.core.async_superset_client.AsyncSupersetClient.__init__:Function] - # [DEF:aclose:Function] + # [DEF:backend.src.core.async_superset_client.AsyncSupersetClient.aclose:Function] # @TIER: STANDARD # @PURPOSE: Close async transport resources. # @POST: Underlying AsyncAPIClient is closed. # @SIDE_EFFECT: Closes network sockets. async def aclose(self) -> None: await self.network.aclose() - # [/DEF:aclose:Function] + # [/DEF:backend.src.core.async_superset_client.AsyncSupersetClient.aclose:Function] - # [DEF:get_dashboards_page_async:Function] + # [DEF:backend.src.core.async_superset_client.AsyncSupersetClient.get_dashboards_page_async:Function] # @TIER: STANDARD # @PURPOSE: Fetch one dashboards page asynchronously. # @POST: Returns total count and page result list. diff --git a/backend/src/core/superset_client.py b/backend/src/core/superset_client.py index fae7ca55..80955893 100644 --- a/backend/src/core/superset_client.py +++ b/backend/src/core/superset_client.py @@ -1,5 +1,6 @@ # [DEF:backend.src.core.superset_client:Module] # +# @TIER: STANDARD # @SEMANTICS: superset, api, client, rest, http, dashboard, dataset, import, export # @PURPOSE: Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию. # @LAYER: Core @@ -23,13 +24,13 @@ from .utils.fileio import get_filename_from_headers from .config_models import Environment # [/SECTION] -# [DEF:SupersetClient:Class] +# [DEF:backend.src.core.superset_client.SupersetClient:Class] # @TIER: STANDARD # @PURPOSE: Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами. # @RELATION: [DEPENDS_ON] ->[backend.src.core.utils.network.APIClient] # @RELATION: [DEPENDS_ON] ->[backend.src.core.config_models.Environment] class SupersetClient: - # [DEF:__init__:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.__init__:Function] # @TIER: STANDARD # @PURPOSE: Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент. # @PRE: `env` должен быть валидным объектом Environment. @@ -58,7 +59,7 @@ class SupersetClient: app_logger.info("[SupersetClient.__init__][Exit] SupersetClient initialized.") # [/DEF:__init__:Function] - # [DEF:authenticate:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.authenticate:Function] # @TIER: STANDARD # @PURPOSE: Authenticates the client using the configured credentials. # @PRE: self.network must be initialized with valid auth configuration. @@ -71,7 +72,7 @@ class SupersetClient: # [/DEF:authenticate:Function] @property - # [DEF:headers:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.headers:Function] # @TIER: TRIVIAL # @PURPOSE: Возвращает базовые HTTP-заголовки, используемые сетевым клиентом. # @PRE: APIClient is initialized and authenticated. @@ -83,7 +84,7 @@ class SupersetClient: # [SECTION: DASHBOARD OPERATIONS] - # [DEF:get_dashboards:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards:Function] # @TIER: STANDARD # @PURPOSE: Получает полный список дашбордов, автоматически обрабатывая пагинацию. # @PRE: Client is authenticated. @@ -117,7 +118,7 @@ class SupersetClient: return total_count, paginated_data # [/DEF:get_dashboards:Function] - # [DEF:get_dashboards_page:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_page:Function] # @TIER: STANDARD # @PURPOSE: Fetches a single dashboards page from Superset without iterating all pages. # @PRE: Client is authenticated. @@ -154,7 +155,7 @@ class SupersetClient: return total_count, result # [/DEF:get_dashboards_page:Function] - # [DEF:get_dashboards_summary:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_summary:Function] # @TIER: STANDARD # @PURPOSE: Fetches dashboard metadata optimized for the grid. # @PRE: Client is authenticated. @@ -239,7 +240,7 @@ class SupersetClient: return result # [/DEF:get_dashboards_summary:Function] - # [DEF:get_dashboards_summary_page:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_summary_page:Function] # @TIER: STANDARD # @PURPOSE: Fetches one page of dashboard metadata optimized for the grid. # @PRE: page >= 1 and page_size > 0. @@ -312,7 +313,7 @@ class SupersetClient: return total_count, result # [/DEF:get_dashboards_summary_page:Function] - # [DEF:_extract_owner_labels:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._extract_owner_labels:Function] # @TIER: TRIVIAL # @PURPOSE: Normalize dashboard owners payload to stable display labels. # @PRE: owners payload can be scalar, object or list. @@ -340,7 +341,7 @@ class SupersetClient: return normalized # [/DEF:_extract_owner_labels:Function] - # [DEF:_extract_user_display:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._extract_user_display:Function] # @TIER: TRIVIAL # @PURPOSE: Normalize user payload to a stable display name. # @PRE: user payload can be string, dict or None. @@ -369,7 +370,7 @@ class SupersetClient: return None # [/DEF:_extract_user_display:Function] - # [DEF:_sanitize_user_text:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._sanitize_user_text:Function] # @TIER: TRIVIAL # @PURPOSE: Convert scalar value to non-empty user-facing text. # @PRE: value can be any scalar type. @@ -383,7 +384,7 @@ class SupersetClient: return normalized # [/DEF:_sanitize_user_text:Function] - # [DEF:get_dashboard:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dashboard:Function] # @TIER: STANDARD # @PURPOSE: Fetches a single dashboard by ID. # @PRE: Client is authenticated and dashboard_id exists. @@ -396,7 +397,7 @@ class SupersetClient: return cast(Dict, response) # [/DEF:get_dashboard:Function] - # [DEF:get_chart:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_chart:Function] # @TIER: STANDARD # @PURPOSE: Fetches a single chart by ID. # @PRE: Client is authenticated and chart_id exists. @@ -409,7 +410,7 @@ class SupersetClient: return cast(Dict, response) # [/DEF:get_chart:Function] - # [DEF:get_dashboard_detail:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dashboard_detail:Function] # @TIER: STANDARD # @PURPOSE: Fetches detailed dashboard information including related charts and datasets. # @PRE: Client is authenticated and dashboard_id exists. @@ -604,7 +605,7 @@ class SupersetClient: } # [/DEF:get_dashboard_detail:Function] - # [DEF:get_charts:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_charts:Function] # @TIER: STANDARD # @PURPOSE: Fetches all charts with pagination support. # @PRE: Client is authenticated. @@ -624,7 +625,8 @@ class SupersetClient: return len(paginated_data), paginated_data # [/DEF:get_charts:Function] - # [DEF:_extract_chart_ids_from_layout:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._extract_chart_ids_from_layout:Function] + # @TIER: TRIVIAL # @PURPOSE: Traverses dashboard layout metadata and extracts chart IDs from common keys. # @PRE: payload can be dict/list/scalar. # @POST: Returns a set of chart IDs found in nested structures. @@ -656,7 +658,7 @@ class SupersetClient: return found # [/DEF:_extract_chart_ids_from_layout:Function] - # [DEF:export_dashboard:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.export_dashboard:Function] # @TIER: STANDARD # @PURPOSE: Экспортирует дашборд в виде ZIP-архива. # @PRE: dashboard_id must exist in Superset. @@ -681,7 +683,7 @@ class SupersetClient: return response.content, filename # [/DEF:export_dashboard:Function] - # [DEF:import_dashboard:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.import_dashboard:Function] # @TIER: STANDARD # @PURPOSE: Импортирует дашборд из ZIP-файла. # @PRE: file_name must be a valid ZIP dashboard export. @@ -713,7 +715,7 @@ class SupersetClient: return self._do_import(file_path) # [/DEF:import_dashboard:Function] - # [DEF:delete_dashboard:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.delete_dashboard:Function] # @TIER: STANDARD # @PURPOSE: Удаляет дашборд по его ID или slug. # @PRE: dashboard_id must exist. @@ -735,7 +737,7 @@ class SupersetClient: # [SECTION: DATASET OPERATIONS] - # [DEF:get_datasets:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_datasets:Function] # @TIER: STANDARD # @PURPOSE: Получает полный список датасетов, автоматически обрабатывая пагинацию. # @PRE: Client is authenticated. @@ -756,7 +758,8 @@ class SupersetClient: return total_count, paginated_data # [/DEF:get_datasets:Function] - # [DEF:get_datasets_summary:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_datasets_summary:Function] + # @TIER: STANDARD # @PURPOSE: Fetches dataset metadata optimized for the Dataset Hub grid. # @PRE: Client is authenticated. # @POST: Returns a list of dataset metadata summaries. @@ -780,7 +783,8 @@ class SupersetClient: return result # [/DEF:get_datasets_summary:Function] - # [DEF:get_dataset_detail:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dataset_detail:Function] + # @TIER: STANDARD # @PURPOSE: Fetches detailed dataset information including columns and linked dashboards # @PRE: Client is authenticated and dataset_id exists. # @POST: Returns detailed dataset info with columns and linked dashboards. @@ -892,7 +896,7 @@ class SupersetClient: return result # [/DEF:get_dataset_detail:Function] - # [DEF:get_dataset:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_dataset:Function] # @TIER: STANDARD # @PURPOSE: Получает информацию о конкретном датасете по его ID. # @PRE: dataset_id must exist. @@ -908,7 +912,7 @@ class SupersetClient: return response # [/DEF:get_dataset:Function] - # [DEF:update_dataset:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.update_dataset:Function] # @TIER: STANDARD # @PURPOSE: Обновляет данные датасета по его ID. # @PRE: dataset_id must exist. @@ -934,7 +938,7 @@ class SupersetClient: # [SECTION: DATABASE OPERATIONS] - # [DEF:get_databases:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_databases:Function] # @TIER: STANDARD # @PURPOSE: Получает полный список баз данных. # @PRE: Client is authenticated. @@ -957,7 +961,7 @@ class SupersetClient: return total_count, paginated_data # [/DEF:get_databases:Function] - # [DEF:get_database:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_database:Function] # @TIER: STANDARD # @PURPOSE: Получает информацию о конкретной базе данных по её ID. # @PRE: database_id must exist. @@ -973,7 +977,7 @@ class SupersetClient: return response # [/DEF:get_database:Function] - # [DEF:get_databases_summary:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_databases_summary:Function] # @TIER: STANDARD # @PURPOSE: Fetch a summary of databases including uuid, name, and engine. # @PRE: Client is authenticated. @@ -994,7 +998,7 @@ class SupersetClient: return databases # [/DEF:get_databases_summary:Function] - # [DEF:get_database_by_uuid:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_database_by_uuid:Function] # @TIER: STANDARD # @PURPOSE: Find a database by its UUID. # @PRE: db_uuid must be a valid UUID string. @@ -1014,7 +1018,7 @@ class SupersetClient: # [SECTION: HELPERS] - # [DEF:_resolve_target_id_for_delete:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._resolve_target_id_for_delete:Function] # @TIER: TRIVIAL # @PURPOSE: Resolves a dashboard ID from either an ID or a slug. # @PRE: Either dash_id or dash_slug should be provided. @@ -1037,7 +1041,7 @@ class SupersetClient: return None # [/DEF:_resolve_target_id_for_delete:Function] - # [DEF:_do_import:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._do_import:Function] # @TIER: TRIVIAL # @PURPOSE: Performs the actual multipart upload for import. # @PRE: file_name must be a path to an existing ZIP file. @@ -1059,7 +1063,7 @@ class SupersetClient: ) # [/DEF:_do_import:Function] - # [DEF:_validate_export_response:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._validate_export_response:Function] # @TIER: TRIVIAL # @PURPOSE: Validates that the export response is a non-empty ZIP archive. # @PRE: response must be a valid requests.Response object. @@ -1073,7 +1077,7 @@ class SupersetClient: raise SupersetAPIError("Получены пустые данные при экспорте") # [/DEF:_validate_export_response:Function] - # [DEF:_resolve_export_filename:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._resolve_export_filename:Function] # @TIER: TRIVIAL # @PURPOSE: Determines the filename for an exported dashboard. # @PRE: response must contain Content-Disposition header or dashboard_id must be provided. @@ -1089,7 +1093,7 @@ class SupersetClient: return filename # [/DEF:_resolve_export_filename:Function] - # [DEF:_validate_query_params:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._validate_query_params:Function] # @TIER: TRIVIAL # @PURPOSE: Ensures query parameters have default page and page_size. # @PRE: query can be None or a dictionary. @@ -1102,7 +1106,7 @@ class SupersetClient: return {**base_query, **(query or {})} # [/DEF:_validate_query_params:Function] - # [DEF:_fetch_total_object_count:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._fetch_total_object_count:Function] # @TIER: TRIVIAL # @PURPOSE: Fetches the total number of items for a given endpoint. # @PRE: endpoint must be a valid Superset API path. @@ -1117,7 +1121,8 @@ class SupersetClient: ) # [/DEF:_fetch_total_object_count:Function] - # [DEF:_fetch_all_pages:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._fetch_all_pages:Function] + # @TIER: TRIVIAL # @PURPOSE: Iterates through all pages to collect all data items. # @PRE: pagination_options must contain base_query, total_count, and results_field. # @POST: Returns a combined list of all items. @@ -1126,7 +1131,8 @@ class SupersetClient: return self.network.fetch_paginated_data(endpoint=endpoint, pagination_options=pagination_options) # [/DEF:_fetch_all_pages:Function] - # [DEF:_validate_import_file:Function] + # [DEF:backend.src.core.superset_client.SupersetClient._validate_import_file:Function] + # @TIER: TRIVIAL # @PURPOSE: Validates that the file to be imported is a valid ZIP with metadata.yaml. # @PRE: zip_path must be a path to a file. # @POST: Raises error if file is missing, not a ZIP, or missing metadata. @@ -1142,7 +1148,8 @@ class SupersetClient: raise SupersetAPIError(f"Архив {zip_path} не содержит 'metadata.yaml'") # [/DEF:_validate_import_file:Function] - # [DEF:get_all_resources:Function] + # [DEF:backend.src.core.superset_client.SupersetClient.get_all_resources:Function] + # @TIER: STANDARD # @PURPOSE: Fetches all resources of a given type with id, uuid, and name columns. # @PARAM: resource_type (str) - One of "chart", "dataset", "dashboard". # @PRE: Client is authenticated. resource_type is valid. @@ -1191,6 +1198,6 @@ class SupersetClient: # [/SECTION] -# [/DEF:SupersetClient:Class] +# [/DEF:backend.src.core.superset_client.SupersetClient:Class] # [/DEF:backend.src.core.superset_client:Module] diff --git a/backend/src/services/git_service.py b/backend/src/services/git_service.py index bce34ace..6ffe3e46 100644 --- a/backend/src/services/git_service.py +++ b/backend/src/services/git_service.py @@ -4,12 +4,11 @@ # @SEMANTICS: git, service, gitpython, repository, version_control # @PURPOSE: Core Git logic using GitPython to manage dashboard repositories. # @LAYER: Service -# @RELATION: INHERITS_FROM -> None -# @RELATION: USED_BY -> src.api.routes.git -# @RELATION: USED_BY -> src.plugins.git_plugin -# @RELATION: DEPENDS_ON -> src.core.database.SessionLocal -# @RELATION: DEPENDS_ON -> src.models.config.AppConfigRecord -# @RELATION: DEPENDS_ON -> src.models.git.GitRepository +# @RELATION: USED_BY -> backend.src.api.routes.git +# @RELATION: USED_BY -> backend.src.plugins.git_plugin +# @RELATION: DEPENDS_ON -> backend.src.core.database.SessionLocal +# @RELATION: DEPENDS_ON -> backend.src.models.config.AppConfigRecord +# @RELATION: DEPENDS_ON -> backend.src.models.git.GitRepository # # @INVARIANT: All Git operations must be performed on a valid local directory. @@ -32,14 +31,15 @@ from src.models.git import GitRepository, GitServerConfig from src.models.config import AppConfigRecord from src.core.database import SessionLocal -# [DEF:GitService:Class] +# [DEF:backend.src.services.git_service.GitService:Class] +# @TIER: STANDARD # @PURPOSE: Wrapper for GitPython operations with semantic logging and error handling. class GitService: """ Wrapper for GitPython operations. """ - # [DEF:__init__:Function] + # [DEF:backend.src.services.git_service.GitService.__init__:Function] # @PURPOSE: Initializes the GitService with a base path for repositories. # @PARAM: base_path (str) - Root directory for all Git clones. # @PRE: base_path is a valid string path. @@ -64,7 +64,7 @@ class GitService: base.mkdir(parents=True, exist_ok=True) # [/DEF:_ensure_base_path_exists:Function] - # [DEF:_resolve_base_path:Function] + # [DEF:backend.src.services.git_service.GitService._resolve_base_path:Function] # @PURPOSE: Resolve base repository directory from explicit argument or global storage settings. # @PRE: base_path is a string path. # @POST: Returns absolute path for Git repositories root. @@ -254,7 +254,7 @@ class GitService: ) # [/DEF:_ensure_gitflow_branches:Function] - # [DEF:_get_repo_path:Function] + # [DEF:backend.src.services.git_service.GitService._get_repo_path:Function] # @PURPOSE: Resolves the local filesystem path for a dashboard's repository. # @PARAM: dashboard_id (int) # @PARAM: repo_key (Optional[str]) - Slug-like key used when DB local_path is absent. @@ -394,7 +394,7 @@ class GitService: session.close() # [/DEF:delete_repo:Function] - # [DEF:get_repo:Function] + # [DEF:backend.src.services.git_service.GitService.get_repo:Function] # @PURPOSE: Get Repo object for a dashboard. # @PRE: Repository must exist on disk for the given dashboard_id. # @POST: Returns a GitPython Repo instance for the dashboard. @@ -1112,7 +1112,7 @@ class GitService: raise HTTPException(status_code=500, detail=f"Git pull failed: {str(e)}") # [/DEF:pull_changes:Function] - # [DEF:get_status:Function] + # [DEF:backend.src.services.git_service.GitService.get_status:Function] # @PURPOSE: Get current repository status (dirty files, untracked, etc.) # @PRE: Repository for dashboard_id exists. # @POST: Returns a dictionary representing the Git status. @@ -1657,7 +1657,7 @@ class GitService: } # [/DEF:_parse_remote_repo_identity:Function] - # [DEF:_derive_server_url_from_remote:Function] + # [DEF:backend.src.services.git_service.GitService._derive_server_url_from_remote:Function] # @PURPOSE: Build API base URL from remote repository URL without credentials. # @PRE: remote_url may be any git URL. # @POST: Returns normalized http(s) base URL or None when derivation is impossible. @@ -1744,7 +1744,7 @@ class GitService: } # [/DEF:promote_direct_merge:Function] - # [DEF:create_gitea_pull_request:Function] + # [DEF:backend.src.services.git_service.GitService.create_gitea_pull_request:Function] # @PURPOSE: Create pull request in Gitea. # @PRE: Config and remote URL are valid. # @POST: Returns normalized PR metadata. @@ -1832,7 +1832,7 @@ class GitService: } # [/DEF:create_gitea_pull_request:Function] - # [DEF:create_github_pull_request:Function] + # [DEF:backend.src.services.git_service.GitService.create_github_pull_request:Function] # @PURPOSE: Create pull request in GitHub or GitHub Enterprise. # @PRE: Config and remote URL are valid. # @POST: Returns normalized PR metadata. @@ -1886,7 +1886,7 @@ class GitService: } # [/DEF:create_github_pull_request:Function] - # [DEF:create_gitlab_merge_request:Function] + # [DEF:backend.src.services.git_service.GitService.create_gitlab_merge_request:Function] # @PURPOSE: Create merge request in GitLab. # @PRE: Config and remote URL are valid. # @POST: Returns normalized MR metadata. diff --git a/backend/src/services/resource_service.py b/backend/src/services/resource_service.py index ad313187..b23b877a 100644 --- a/backend/src/services/resource_service.py +++ b/backend/src/services/resource_service.py @@ -3,9 +3,10 @@ # @SEMANTICS: service, resources, dashboards, datasets, tasks, git # @PURPOSE: Shared service for fetching resource data with Git status and task status # @LAYER: Service -# @RELATION: DEPENDS_ON -> backend.src.core.superset_client -# @RELATION: DEPENDS_ON -> backend.src.core.task_manager -# @RELATION: DEPENDS_ON -> backend.src.services.git_service +# @RELATION: DEPENDS_ON ->[backend.src.core.superset_client.SupersetClient] +# @RELATION: DEPENDS_ON ->[TaskManagerPackage] +# @RELATION: DEPENDS_ON ->[TaskManagerModels] +# @RELATION: DEPENDS_ON ->[backend.src.services.git_service.GitService] # @INVARIANT: All resources include metadata about their current state # [SECTION: IMPORTS] @@ -17,12 +18,12 @@ from ..services.git_service import GitService from ..core.logger import logger, belief_scope # [/SECTION] -# [DEF:ResourceService:Class] +# [DEF:backend.src.services.resource_service.ResourceService:Class] # @TIER: STANDARD # @PURPOSE: Provides centralized access to resource data with enhanced metadata class ResourceService: - # [DEF:__init__:Function] + # [DEF:backend.src.services.resource_service.ResourceService.__init__:Function] # @TIER: TRIVIAL # @PURPOSE: Initialize the resource service with dependencies # @PRE: None @@ -31,9 +32,9 @@ class ResourceService: with belief_scope("ResourceService.__init__"): self.git_service = GitService() logger.info("[ResourceService][Action] Initialized ResourceService") - # [/DEF:__init__:Function] + # [/DEF:backend.src.services.resource_service.ResourceService.__init__:Function] - # [DEF:get_dashboards_with_status:Function] + # [DEF:backend.src.services.resource_service.ResourceService.get_dashboards_with_status:Function] # @TIER: STANDARD # @PURPOSE: Fetch dashboards from environment with Git status and last task status # @PRE: env is a valid Environment object @@ -41,9 +42,9 @@ class ResourceService: # @PARAM: env (Environment) - The environment to fetch from # @PARAM: tasks (List[Task]) - List of tasks to check for status # @RETURN: List[Dict] - Dashboards with git_status and last_task fields - # @RELATION: CALLS ->[SupersetClient:get_dashboards_summary] - # @RELATION: CALLS ->[self:_get_git_status_for_dashboard] - # @RELATION: CALLS ->[self:_get_last_llm_task_for_dashboard] + # @RELATION: CALLS ->[backend.src.core.superset_client.SupersetClient.get_dashboards_summary] + # @RELATION: CALLS ->[backend.src.services.resource_service.ResourceService._get_git_status_for_dashboard] + # @RELATION: CALLS ->[backend.src.services.resource_service.ResourceService._get_last_llm_task_for_dashboard] async def get_dashboards_with_status( self, env: Any,